diff --git a/data/strings/en.ini b/data/strings/en.ini index 6edbfd005..fcbdd6361 100644 --- a/data/strings/en.ini +++ b/data/strings/en.ini @@ -6,6 +6,15 @@ title = Warning - Important description = You are going to enter in "Advanced Mode". +[ani_controls] +shortcut = Shortcut: +right_click = Right-click: Show playback options + +[anidir_combo] +forward = Forward +reverse = Reverse +ping_pong = Ping-pong + [ask_for_color_profile] title = Color Profile sprite_with_profile = The sprite contains a color profile. @@ -14,6 +23,23 @@ sprite_without_profile = The sprite doesn't contain a color profile. [statusbar_tips] all_layers_are_locked = All selected layers are locked layer_locked = Layer '{0}' is locked +disable_snap_grid = Disable Snap to Grid +frame = Frame: +current_frame = Current Frame +zoom_level = Zoom Level +new_frame = New Frame +locked_layers = There are locked layers +no_active_layers = There is no active layer +layer_x_is_hidden = Layer '{}' is hidden +unmodifiable_reference_layer = Layer '{}' is reference, cannot be modified +filter_no_unlocked_layer = No unlocked layers to apply filter +cannot_move_bg_layer = The background layer cannot be moved +nothing_to_move = Nothing to move +recovery_task_using_sprite = Sprite is used by a backup/data recovery task +non_transformable_reference_layer = Layer '{}' is reference, cannot be transformed +sprite_locked_somewhere = The sprite is locked in other editor +not_enough_transform_memory = Not enough memory to transform the selection +not_enough_rotsprite_memory = Not enough memory for RotSprite [alerts] applying_filter = FX< saved. + +[save_palette] +title = Save Palette + +[save_selection] +title = Save Selection (.msk file) + [script_access] title = Security script_label = The following script: @@ -1590,6 +1896,13 @@ double_high = Double-high Pixels (1:2) color_profile = Color Profile: assign_color_profile = Assign convert_color_profile = Convert +rgb = RGB +grayscale = Grayscale +indexed_color = Indexed ({0} colors) +indexed_image_only = (only for indexed images) +assign_color_profile = Assign Color Profile +convert_color_profile = Convert Color Profile +change_sprite_props = Change Sprite Properties [sprite_size] title = Sprite Size @@ -1610,6 +1923,9 @@ lock_ratio = Lock Ratio percentage = Percentage: interpolation = Interpolation: method = Method: +method_nearest_neighbor = Nearest-neighbor +method_bilinear = Bilinear +method_rotsprite = RotSprite [svg_options] title = SVG Options diff --git a/src/app/cmd/flatten_layers.cpp b/src/app/cmd/flatten_layers.cpp index c281b722d..936a5b04f 100644 --- a/src/app/cmd/flatten_layers.cpp +++ b/src/app/cmd/flatten_layers.cpp @@ -20,6 +20,7 @@ #include "app/cmd/set_layer_name.h" #include "app/cmd/unlink_cel.h" #include "app/doc.h" +#include "app/i18n/strings.h" #include "app/restore_visible_layers.h" #include "doc/algorithm/shrink_bounds.h" #include "doc/cel.h" @@ -81,7 +82,7 @@ void FlattenLayers::onExecute() // Create a new transparent layer to flatten everything onto it. flatLayer = new LayerImage(sprite); ASSERT(flatLayer->isVisible()); - flatLayer->setName("Flattened"); + flatLayer->setName(Strings::layer_properties_flattened()); newFlatLayer = true; bgcolor = sprite->transparentColor(); } diff --git a/src/app/commands/cmd_change_pixel_format.cpp b/src/app/commands/cmd_change_pixel_format.cpp index 1a9a221c5..2ca4f2ebf 100644 --- a/src/app/commands/cmd_change_pixel_format.cpp +++ b/src/app/commands/cmd_change_pixel_format.cpp @@ -171,17 +171,13 @@ class ConversionItem : public ListItem { public: ConversionItem(const doc::PixelFormat pixelFormat) : m_pixelFormat(pixelFormat) { + std::string toMode; switch (pixelFormat) { - case IMAGE_RGB: - setText("-> RGB"); - break; - case IMAGE_GRAYSCALE: - setText("-> Grayscale"); - break; - case IMAGE_INDEXED: - setText("-> Indexed"); - break; + case IMAGE_RGB: toMode = Strings::commands_ChangePixelFormat_RGB(); break; + case IMAGE_GRAYSCALE: toMode = Strings::commands_ChangePixelFormat_Grayscale(); break; + case IMAGE_INDEXED: toMode = Strings::commands_ChangePixelFormat_Indexed(); break; } + setText(fmt::format("-> {}", toMode)); } doc::PixelFormat pixelFormat() const { return m_pixelFormat; } private: @@ -204,11 +200,13 @@ public: const doc::PixelFormat from = m_editor->sprite()->pixelFormat(); // Add the color mode in the window title + std::string fromMode; switch (from) { - case IMAGE_RGB: setText(text() + ": RGB"); break; - case IMAGE_GRAYSCALE: setText(text() + ": Grayscale"); break; - case IMAGE_INDEXED: setText(text() + ": Indexed"); break; + case IMAGE_RGB: fromMode = Strings::commands_ChangePixelFormat_RGB(); break; + case IMAGE_GRAYSCALE: fromMode = Strings::commands_ChangePixelFormat_Grayscale(); break; + case IMAGE_INDEXED: fromMode = Strings::commands_ChangePixelFormat_Indexed(); break; } + setText(fmt::format("{}: {}", text(), fromMode)); // Add conversion items if (from != IMAGE_RGB) @@ -646,7 +644,7 @@ void ChangePixelFormatCommand::onExecute(Context* context) { const ContextReader reader(context); - SpriteJob job(reader, "Color Mode Change"); + SpriteJob job(reader, Strings::color_mode_title().c_str()); Sprite* sprite(job.sprite()); // TODO this was moved in the main UI thread because diff --git a/src/app/commands/cmd_clear_cel.cpp b/src/app/commands/cmd_clear_cel.cpp index 48624649d..a7669865a 100644 --- a/src/app/commands/cmd_clear_cel.cpp +++ b/src/app/commands/cmd_clear_cel.cpp @@ -13,6 +13,7 @@ #include "app/commands/command.h" #include "app/context_access.h" #include "app/doc_api.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/tx.h" #include "app/ui/status_bar.h" @@ -80,7 +81,7 @@ void ClearCelCommand::onExecute(Context* context) if (nonEditableLayers) StatusBar::instance()->showTip(1000, - "There are locked layers"); + Strings::statusbar_tips_locked_layers()); update_screen_for_document(document); } diff --git a/src/app/commands/cmd_export_sprite_sheet.cpp b/src/app/commands/cmd_export_sprite_sheet.cpp index a20b73379..84148eb89 100644 --- a/src/app/commands/cmd_export_sprite_sheet.cpp +++ b/src/app/commands/cmd_export_sprite_sheet.cpp @@ -854,7 +854,7 @@ private: void onImageFilename() { base::paths newFilename; if (!app::show_file_selector( - "Save Sprite Sheet", m_filename, + Strings::export_sprite_sheet_save_title(), m_filename, get_writable_extensions(), FileSelectorType::Save, newFilename)) return; @@ -879,8 +879,11 @@ private: base::paths exts = { "json" }; base::paths newFilename; if (!app::show_file_selector( - "Save JSON Data", m_dataFilename, exts, - FileSelectorType::Save, newFilename)) + Strings::export_sprite_sheet_save_json_title(), + m_dataFilename, + exts, + FileSelectorType::Save, + newFilename)) return; ASSERT(!newFilename.empty()); @@ -1335,7 +1338,7 @@ void ExportSpriteSheetCommand::onExecute(Context* context) StatusBar* statusbar = StatusBar::instance(); if (statusbar) - statusbar->showTip(1000, "Sprite Sheet Generated"); + statusbar->showTip(1000, Strings::export_sprite_sheet_generated()); // Save the exported sprite sheet as a recent file if (newDocument->isAssociatedToFile()) diff --git a/src/app/commands/cmd_import_sprite_sheet.cpp b/src/app/commands/cmd_import_sprite_sheet.cpp index 418a775c5..f69e6dfb2 100644 --- a/src/app/commands/cmd_import_sprite_sheet.cpp +++ b/src/app/commands/cmd_import_sprite_sheet.cpp @@ -70,10 +70,10 @@ public: (int)app::SpriteSheetType::Columns == 4, "SpriteSheetType enum changed"); - sheetType()->addItem("Horizontal Strip"); - sheetType()->addItem("Vertical Strip"); - sheetType()->addItem("By Rows"); - sheetType()->addItem("By Columns"); + sheetType()->addItem(Strings::import_sprite_sheet_type_horz()); + sheetType()->addItem(Strings::import_sprite_sheet_type_vert()); + sheetType()->addItem(Strings::import_sprite_sheet_type_rows()); + sheetType()->addItem(Strings::import_sprite_sheet_type_cols()); sheetType()->setSelectedItemIndex((int)app::SpriteSheetType::Rows-1); sheetType()->Change.connect([this]{ onSheetTypeChange(); }); @@ -251,7 +251,7 @@ protected: } std::string onGetContextBarHelp() override { - return "Select bounds to identify sprite frames"; + return Strings::import_sprite_sheet_context_bar_help(); } private: @@ -513,11 +513,13 @@ void ImportSpriteSheetCommand::onExecute(Context* context) // The following steps modify the sprite, so we wrap all // operations in a undo-transaction. ContextWriter writer(context); - Tx tx(writer.context(), "Import Sprite Sheet", ModifyDocument); + Tx tx( + writer.context(), Strings::import_sprite_sheet_title(), ModifyDocument); DocApi api = document->getApi(tx); // Add the layer in the sprite. - LayerImage* resultLayer = api.newLayer(sprite->root(), "Sprite Sheet"); + LayerImage* resultLayer = + api.newLayer(sprite->root(), Strings::import_sprite_sheet_layer_name()); // Add all frames+cels to the new layer for (size_t i=0; isetBgColor(gfx::ColorNone); m_addButton->setBounds(itemBounds); - m_addButton->setText("Add"); + m_addButton->setText(Strings::keyboard_shortcuts_add()); invalidate(); } @@ -481,7 +481,7 @@ private: std::string getAccelText(const Accelerator& accel) const { if (m_key && m_key->type() == KeyType::WheelAction && accel.isEmpty()) { - return "(Default Action)"; + return Strings::keyboard_shortcuts_default_action(); } else { return accel.toString(); @@ -840,7 +840,7 @@ private: base::paths exts = { KEYBOARD_FILENAME_EXTENSION }; base::paths filename; if (!app::show_file_selector( - "Import Keyboard Shortcuts", "", exts, + Strings::keyboard_shortcuts_import_keyboard_sc(), "", exts, FileSelectorType::Open, filename)) return; @@ -856,7 +856,7 @@ private: base::paths filename; if (!app::show_file_selector( - "Export Keyboard Shortcuts", "", exts, + Strings::keyboard_shortcuts_export_keyboard_sc(), "", exts, FileSelectorType::Save, filename)) return; diff --git a/src/app/commands/cmd_layer_properties.cpp b/src/app/commands/cmd_layer_properties.cpp index c8542e4fd..574cb4355 100644 --- a/src/app/commands/cmd_layer_properties.cpp +++ b/src/app/commands/cmd_layer_properties.cpp @@ -21,6 +21,7 @@ #include "app/context_access.h" #include "app/doc.h" #include "app/doc_event.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/tx.h" #include "app/ui/main_window.h" @@ -79,30 +80,49 @@ public: name()->setMinSize(gfx::Size(128, 0)); name()->setExpansive(true); - mode()->addItem(new BlendModeItem("Normal", doc::BlendMode::NORMAL)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_normal(), + doc::BlendMode::NORMAL)); mode()->addItem(new SeparatorInView); - mode()->addItem(new BlendModeItem("Darken", doc::BlendMode::DARKEN)); - mode()->addItem(new BlendModeItem("Multiply", doc::BlendMode::MULTIPLY)); - mode()->addItem(new BlendModeItem("Color Burn", doc::BlendMode::COLOR_BURN)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_darken(), + doc::BlendMode::DARKEN)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_multiply(), + doc::BlendMode::MULTIPLY)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_color_burn(), + doc::BlendMode::COLOR_BURN)); mode()->addItem(new SeparatorInView); - mode()->addItem(new BlendModeItem("Lighten", doc::BlendMode::LIGHTEN)); - mode()->addItem(new BlendModeItem("Screen", doc::BlendMode::SCREEN)); - mode()->addItem(new BlendModeItem("Color Dodge", doc::BlendMode::COLOR_DODGE)); - mode()->addItem(new BlendModeItem("Addition", doc::BlendMode::ADDITION)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_lighten(), + doc::BlendMode::LIGHTEN)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_screen(), + doc::BlendMode::SCREEN)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_color_dodge(), + doc::BlendMode::COLOR_DODGE)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_addition(), + doc::BlendMode::ADDITION)); mode()->addItem(new SeparatorInView); - mode()->addItem(new BlendModeItem("Overlay", doc::BlendMode::OVERLAY)); - mode()->addItem(new BlendModeItem("Soft Light", doc::BlendMode::SOFT_LIGHT)); - mode()->addItem(new BlendModeItem("Hard Light", doc::BlendMode::HARD_LIGHT)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_overlay(), + doc::BlendMode::OVERLAY)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_soft_light(), + doc::BlendMode::SOFT_LIGHT)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_hard_light(), + doc::BlendMode::HARD_LIGHT)); mode()->addItem(new SeparatorInView); - mode()->addItem(new BlendModeItem("Difference", doc::BlendMode::DIFFERENCE)); - mode()->addItem(new BlendModeItem("Exclusion", doc::BlendMode::EXCLUSION)); - mode()->addItem(new BlendModeItem("Subtract", doc::BlendMode::SUBTRACT)); - mode()->addItem(new BlendModeItem("Divide", doc::BlendMode::DIVIDE)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_difference(), + doc::BlendMode::DIFFERENCE)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_exclusion(), + doc::BlendMode::EXCLUSION)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_subtract(), + doc::BlendMode::SUBTRACT)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_divide(), + doc::BlendMode::DIVIDE)); mode()->addItem(new SeparatorInView); - mode()->addItem(new BlendModeItem("Hue", doc::BlendMode::HSL_HUE)); - mode()->addItem(new BlendModeItem("Saturation", doc::BlendMode::HSL_SATURATION)); - mode()->addItem(new BlendModeItem("Color", doc::BlendMode::HSL_COLOR)); - mode()->addItem(new BlendModeItem("Luminosity", doc::BlendMode::HSL_LUMINOSITY)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_hue(), + doc::BlendMode::HSL_HUE)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_saturation(), + doc::BlendMode::HSL_SATURATION)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_color(), + doc::BlendMode::HSL_COLOR)); + mode()->addItem(new BlendModeItem(Strings::layer_properties_luminosity(), + doc::BlendMode::HSL_LUMINOSITY)); name()->Change.connect([this]{ onStartTimer(); }); mode()->Change.connect([this]{ onStartTimer(); }); @@ -407,7 +427,7 @@ private: m_userDataView.entry()->setText(m_layer->userData().text()); } else { - name()->setText("No Layer"); + name()->setText(Strings::layer_properties_no_layer()); name()->setEnabled(false); mode()->setEnabled(false); opacity()->setEnabled(false); diff --git a/src/app/commands/cmd_link_cels.cpp b/src/app/commands/cmd_link_cels.cpp index 48c5700b6..a466add56 100644 --- a/src/app/commands/cmd_link_cels.cpp +++ b/src/app/commands/cmd_link_cels.cpp @@ -12,6 +12,7 @@ #include "app/cmd/copy_cel.h" #include "app/commands/command.h" #include "app/context_access.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/tx.h" #include "app/ui/status_bar.h" @@ -91,7 +92,7 @@ void LinkCelsCommand::onExecute(Context* context) if (nonEditableLayers) StatusBar::instance()->showTip(1000, - "There are locked layers"); + Strings::statusbar_tips_locked_layers()); update_screen_for_document(document); } diff --git a/src/app/commands/cmd_load_mask.cpp b/src/app/commands/cmd_load_mask.cpp index c1e176e05..3197a6a8c 100644 --- a/src/app/commands/cmd_load_mask.cpp +++ b/src/app/commands/cmd_load_mask.cpp @@ -61,7 +61,7 @@ void LoadMaskCommand::onExecute(Context* context) base::paths exts = { "msk" }; base::paths selectedFilename; if (!app::show_file_selector( - "Load .msk File", m_filename, exts, + Strings::load_selection_title(), m_filename, exts, FileSelectorType::Open, selectedFilename)) return; @@ -77,7 +77,9 @@ void LoadMaskCommand::onExecute(Context* context) { ContextWriter writer(reader); Doc* document = writer.document(); - Tx tx(writer.context(), "Mask Load", DoesntModifyDocument); + Tx tx(writer.context(), + Strings::load_selection_title(), + DoesntModifyDocument); tx(new cmd::SetMask(document, mask.get())); tx.commit(); diff --git a/src/app/commands/cmd_load_palette.cpp b/src/app/commands/cmd_load_palette.cpp index 7d136d721..fb46d1a15 100644 --- a/src/app/commands/cmd_load_palette.cpp +++ b/src/app/commands/cmd_load_palette.cpp @@ -66,7 +66,7 @@ void LoadPaletteCommand::onExecute(Context* context) base::paths exts = get_readable_palette_extensions(); base::paths filenames; if (app::show_file_selector( - "Load Palette", "", exts, + Strings::load_palette_title(), "", exts, FileSelectorType::Open, filenames)) { filename = filenames.front(); } diff --git a/src/app/commands/cmd_mask_by_color.cpp b/src/app/commands/cmd_mask_by_color.cpp index e0c0b3dc4..89a355073 100644 --- a/src/app/commands/cmd_mask_by_color.cpp +++ b/src/app/commands/cmd_mask_by_color.cpp @@ -18,6 +18,7 @@ #include "app/context_access.h" #include "app/doc.h" #include "app/ini_file.h" +#include "app/i18n/strings.h" #include "app/modules/editors.h" #include "app/modules/gui.h" #include "app/tx.h" @@ -106,7 +107,8 @@ void MaskByColorCommand::onExecute(Context* context) if (!image) return; - std::unique_ptr win(new Window(Window::WithTitleBar, "Mask by Color")); + std::unique_ptr win( + new Window(Window::WithTitleBar, Strings::mask_by_color_title())); base::ScopedValue setWindow(m_window, win.get(), nullptr); TooltipManager* tooltipManager = new TooltipManager(); m_window->addChild(tooltipManager); @@ -114,20 +116,20 @@ void MaskByColorCommand::onExecute(Context* context) auto box2 = new Box(HORIZONTAL); auto box3 = new Box(HORIZONTAL); auto box4 = new Box(HORIZONTAL | HOMOGENEOUS); - auto label_color = new Label("Color:"); + auto label_color = new Label(Strings::mask_by_color_label_color()); m_buttonColor = new ColorButton( ColorBar::instance()->getFgColor(), sprite->pixelFormat(), ColorButtonOptions()); - auto label_tolerance = new Label("Tolerance:"); + auto label_tolerance = new Label(Strings::mask_by_color_tolerance()); m_sliderTolerance = new Slider(0, 255, get_config_int(ConfigSection, "Tolerance", 0)); m_selMode = new SelModeField; m_selMode->setupTooltips(tooltipManager); - m_checkPreview = new CheckBox("&Preview"); - auto button_ok = new Button("&OK"); - auto button_cancel = new Button("&Cancel"); + m_checkPreview = new CheckBox(Strings::mask_by_color_preview()); + auto button_ok = new Button(Strings::mask_by_color_ok()); + auto button_cancel = new Button(Strings::mask_by_color_cancel()); m_checkPreview->processMnemonicFromText(); button_ok->processMnemonicFromText(); diff --git a/src/app/commands/cmd_new_brush.cpp b/src/app/commands/cmd_new_brush.cpp index cf0f44c07..cfd7975bd 100644 --- a/src/app/commands/cmd_new_brush.cpp +++ b/src/app/commands/cmd_new_brush.cpp @@ -15,6 +15,7 @@ #include "app/commands/commands.h" #include "app/console.h" #include "app/context_access.h" +#include "app/i18n/strings.h" #include "app/modules/editors.h" #include "app/tools/active_tool.h" #include "app/tools/ink.h" @@ -46,7 +47,7 @@ protected: void onQuickboxCancel(Editor* editor) override; std::string onGetContextBarHelp() override { - return "Select brush bounds | Right-click to cut"; + return Strings::new_brush_context_bar_help(); } private: @@ -173,7 +174,7 @@ void NewBrushCommand::createBrush(const Site& site, const Mask* mask) CommandId::ChangeBrush(), params); if (key && !key->accels().empty()) { std::string tooltip; - tooltip += "Shortcut: "; + tooltip += Strings::new_brush_shortcut() + " "; tooltip += key->accels().front().toString(); StatusBar::instance()->showTip(2000, tooltip); } diff --git a/src/app/commands/cmd_open_file.cpp b/src/app/commands/cmd_open_file.cpp index 04473312f..212d96963 100644 --- a/src/app/commands/cmd_open_file.cpp +++ b/src/app/commands/cmd_open_file.cpp @@ -18,6 +18,7 @@ #include "app/doc.h" #include "app/file/file.h" #include "app/file_selector.h" +#include "app/i18n/strings.h" #include "app/job.h" #include "app/modules/editors.h" #include "app/modules/gui.h" @@ -37,7 +38,7 @@ namespace app { class OpenFileJob : public Job, public IFileOpProgress { public: OpenFileJob(FileOp* fop) - : Job("Loading file") + : Job(Strings::open_file_loading().c_str()) , m_fop(fop) { } @@ -122,7 +123,7 @@ void OpenFileCommand::onExecute(Context* context) if (!m_folder.empty() && !base::is_path_separator(m_folder[m_folder.size()-1])) m_folder.push_back(base::path_separator); - if (!app::show_file_selector("Open", m_folder, exts, + if (!app::show_file_selector(Strings::open_file_title(), m_folder, exts, FileSelectorType::OpenMultiple, filenames)) { // The user cancelled the operation through UI diff --git a/src/app/commands/cmd_options.cpp b/src/app/commands/cmd_options.cpp index f7a3f42a2..b54c8ad75 100644 --- a/src/app/commands/cmd_options.cpp +++ b/src/app/commands/cmd_options.cpp @@ -472,14 +472,14 @@ public: discardBrush()->setSelected(true); // Scope - bgScope()->addItem("Background for New Documents"); - gridScope()->addItem("Grid for New Documents"); + bgScope()->addItem(Strings::options_bg_for_new_docs()); + gridScope()->addItem(Strings::options_grid_for_new_docs()); if (context->activeDocument()) { - bgScope()->addItem("Background for the Active Document"); + bgScope()->addItem(Strings::options_bg_for_active_doc()); bgScope()->setSelectedItemIndex(1); bgScope()->Change.connect([this]{ onChangeBgScope(); }); - gridScope()->addItem("Grid for the Active Document"); + gridScope()->addItem(Strings::options_grid_for_active_doc()); gridScope()->setSelectedItemIndex(1); gridScope()->Change.connect([this]{ onChangeGridScope(); }); } @@ -526,13 +526,13 @@ public: static_assert(int(app::gen::RightClickMode::LASSO) == 5, ""); static_assert(int(app::gen::RightClickMode::SELECT_LAYER_AND_MOVE) == 6, ""); - rightClickBehavior()->addItem("Paint with background color"); - rightClickBehavior()->addItem("Pick foreground color"); - rightClickBehavior()->addItem("Erase"); - rightClickBehavior()->addItem("Scroll"); - rightClickBehavior()->addItem("Rectangular Marquee"); - rightClickBehavior()->addItem("Lasso"); - rightClickBehavior()->addItem("Select Layer & Move"); + rightClickBehavior()->addItem(Strings::options_right_click_paint_bgcolor()); + rightClickBehavior()->addItem(Strings::options_right_click_pick_fgcolor()); + rightClickBehavior()->addItem(Strings::options_right_click_erase()); + rightClickBehavior()->addItem(Strings::options_right_click_scroll()); + rightClickBehavior()->addItem(Strings::options_right_click_rectangular_marquee()); + rightClickBehavior()->addItem(Strings::options_right_click_lasso()); + rightClickBehavior()->addItem(Strings::options_right_click_select_layer_and_move()); rightClickBehavior()->setSelectedItemIndex((int)m_pref.editor.rightClickMode()); #ifndef __APPLE__ // Zoom sliding two fingers option only on macOS @@ -548,7 +548,7 @@ public: checkeredBgSize()->addItem("4x4"); checkeredBgSize()->addItem("2x2"); checkeredBgSize()->addItem("1x1"); - checkeredBgSize()->addItem("Custom"); + checkeredBgSize()->addItem(Strings::options_bg_custom_size()); checkeredBgSize()->Change.connect([this]{ onCheckeredBgSizeChange(); }); // Reset buttons @@ -1339,7 +1339,7 @@ private: if (first) { first = false; themeList()->addChild( - new SeparatorInView("Extension Themes", HORIZONTAL)); + new SeparatorInView(Strings::options_extension_themes(), HORIZONTAL)); } for (auto it : ext->themes()) { diff --git a/src/app/commands/cmd_remove_layer.cpp b/src/app/commands/cmd_remove_layer.cpp index 0ee577521..6e4944fc0 100644 --- a/src/app/commands/cmd_remove_layer.cpp +++ b/src/app/commands/cmd_remove_layer.cpp @@ -97,9 +97,11 @@ void RemoveLayerCommand::onExecute(Context* context) StatusBar::instance()->invalidate(); if (!layerName.empty()) - StatusBar::instance()->showTip(1000, fmt::format("Layer '{}' removed", layerName)); + StatusBar::instance()->showTip( + 1000, fmt::format(Strings::remove_layer_x_removed(), layerName)); else - StatusBar::instance()->showTip(1000, "Layers removed"); + StatusBar::instance()->showTip(1000, + Strings::remove_layer_layers_removed()); } #endif } diff --git a/src/app/commands/cmd_remove_slice.cpp b/src/app/commands/cmd_remove_slice.cpp index 986444a3a..433e5dcb4 100644 --- a/src/app/commands/cmd_remove_slice.cpp +++ b/src/app/commands/cmd_remove_slice.cpp @@ -14,6 +14,7 @@ #include "app/cmd/set_slice_key.h" #include "app/commands/command.h" #include "app/context_access.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/tx.h" #include "app/ui/status_bar.h" @@ -122,10 +123,12 @@ void RemoveSliceCommand::onExecute(Context* context) StatusBar::instance()->invalidate(); if (!sliceName.empty()) StatusBar::instance()->showTip( - 1000, fmt::format("Slice '{}' removed", sliceName)); + 1000, fmt::format(Strings::remove_slice_x_removed(), sliceName)); else StatusBar::instance()->showTip( - 1000, fmt::format("{} slice(s) removed", slicesToDelete.size())); + 1000, + fmt::format(Strings::remove_slice_n_slices_removed(), + slicesToDelete.size())); } Command* CommandFactory::createRemoveSliceCommand() diff --git a/src/app/commands/cmd_rotate.cpp b/src/app/commands/cmd_rotate.cpp index 2bf7c0c1f..b99bfb27a 100644 --- a/src/app/commands/cmd_rotate.cpp +++ b/src/app/commands/cmd_rotate.cpp @@ -46,8 +46,10 @@ class RotateJob : public SpriteJob { public: - RotateJob(const ContextReader& reader, int angle, const CelList& cels, bool rotateSprite) - : SpriteJob(reader, "Rotate Canvas") + RotateJob(const ContextReader& reader, + const std::string& jobName, + int angle, const CelList& cels, bool rotateSprite) + : SpriteJob(reader, jobName.c_str()) , m_cels(cels) , m_rotateSprite(rotateSprite) { m_angle = angle; @@ -237,7 +239,7 @@ void RotateCommand::onExecute(Context* context) ContextReader reader(context); { - RotateJob job(reader, m_angle, cels, rotateSprite); + RotateJob job(reader, friendlyName(), m_angle, cels, rotateSprite); job.startJob(); job.waitJob(); } diff --git a/src/app/commands/cmd_save_file.cpp b/src/app/commands/cmd_save_file.cpp index c2749a335..7e30f1a88 100644 --- a/src/app/commands/cmd_save_file.cpp +++ b/src/app/commands/cmd_save_file.cpp @@ -49,7 +49,7 @@ namespace app { class SaveFileJob : public Job, public IFileOpProgress { public: SaveFileJob(FileOp* fop) - : Job("Saving file") + : Job(Strings::save_file_saving().c_str()) , m_fop(fop) { } @@ -254,7 +254,7 @@ void SaveFileBaseCommand::saveDocumentInBackground( #ifdef ENABLE_UI if (context->isUIAvailable() && params().ui()) { StatusBar::instance()->setStatusText( - 2000, fmt::format("File <{}> saved.", + 2000, fmt::format(Strings::save_file_saved(), base::get_file_name(filename))); } #endif @@ -298,7 +298,7 @@ void SaveFileCommand::onExecute(Context* context) // save-as dialog to the user to select for first time the file-name // for this document. else { - saveAsDialog(context, "Save File", + saveAsDialog(context, Strings::save_file_title(), (params().filename.isSet() ? params().filename(): document->filename()), MarkAsSaved::On); @@ -321,7 +321,7 @@ SaveFileAsCommand::SaveFileAsCommand() void SaveFileAsCommand::onExecute(Context* context) { Doc* document = context->activeDocument(); - saveAsDialog(context, "Save As", + saveAsDialog(context, Strings::save_file_save_as(), (params().filename.isSet() ? params().filename(): document->filename()), MarkAsSaved::On); @@ -366,7 +366,7 @@ void SaveFileCopyAsCommand::onExecute(Context* context) [this, &win, &askOverwrite, context, doc]() -> std::string { std::string result = saveAsDialog( - context, "Export", + context, Strings::save_file_export(), win.outputFilenameValue(), MarkAsSaved::Off, SaveInBackground::Off, diff --git a/src/app/commands/cmd_save_mask.cpp b/src/app/commands/cmd_save_mask.cpp index 68de89149..4e4c78eb2 100644 --- a/src/app/commands/cmd_save_mask.cpp +++ b/src/app/commands/cmd_save_mask.cpp @@ -48,7 +48,7 @@ void SaveMaskCommand::onExecute(Context* context) base::paths exts = { "msk" }; base::paths selFilename; if (!app::show_file_selector( - "Save .msk File", "default.msk", exts, + Strings::save_selection_title(), "default.msk", exts, FileSelectorType::Save, selFilename)) return; diff --git a/src/app/commands/cmd_save_palette.cpp b/src/app/commands/cmd_save_palette.cpp index 2bafb866e..e52ce22cf 100644 --- a/src/app/commands/cmd_save_palette.cpp +++ b/src/app/commands/cmd_save_palette.cpp @@ -64,9 +64,10 @@ void SavePaletteCommand::onExecute(Context* ctx) base::paths exts = get_writable_palette_extensions(); base::paths selFilename; std::string initialPath = (m_saveAsPreset ? get_preset_palettes_dir(): ""); - if (!app::show_file_selector( - "Save Palette", initialPath, exts, - FileSelectorType::Save, selFilename)) + if (!app::show_file_selector(Strings::save_palette_title(), + initialPath, + exts, + FileSelectorType::Save, selFilename)) return; filename = selFilename.front(); diff --git a/src/app/commands/cmd_sprite_properties.cpp b/src/app/commands/cmd_sprite_properties.cpp index 885e95c41..0a3406363 100644 --- a/src/app/commands/cmd_sprite_properties.cpp +++ b/src/app/commands/cmd_sprite_properties.cpp @@ -122,18 +122,18 @@ void SpritePropertiesCommand::onExecute(Context* context) // Update widgets values switch (sprite->pixelFormat()) { case IMAGE_RGB: - imgtype_text = "RGB"; + imgtype_text = Strings::sprite_properties_rgb(); break; case IMAGE_GRAYSCALE: - imgtype_text = "Grayscale"; + imgtype_text = Strings::sprite_properties_grayscale(); break; case IMAGE_INDEXED: - imgtype_text = fmt::format("Indexed ({0} colors)", + imgtype_text = fmt::format(Strings::sprite_properties_indexed_color(), sprite->palette(0)->size()); break; default: ASSERT(false); - imgtype_text = "Unknown"; + imgtype_text = Strings::general_unknown(); break; } @@ -169,7 +169,8 @@ void SpritePropertiesCommand::onExecute(Context* context) LEFT); } else { - window.transparentColorPlaceholder()->addChild(new Label("(only for indexed images)")); + window.transparentColorPlaceholder()->addChild( + new Label(Strings::sprite_properties_indexed_image_only())); } // Pixel ratio @@ -205,7 +206,7 @@ void SpritePropertiesCommand::onExecute(Context* context) ContextWriter writer(context); Sprite* sprite(writer.sprite()); - Tx tx(writer.context(), "Assign Color Profile"); + Tx tx(writer.context(), Strings::sprite_properties_assign_color_profile()); tx(new cmd::AssignColorProfile( sprite, colorSpaces[selectedColorProfile]->gfxColorSpace())); tx.commit(); @@ -218,7 +219,7 @@ void SpritePropertiesCommand::onExecute(Context* context) ContextWriter writer(context); Sprite* sprite(writer.sprite()); - Tx tx(writer.context(), "Convert Color Profile"); + Tx tx(writer.context(), Strings::sprite_properties_convert_color_profile()); tx(new cmd::ConvertColorProfile( sprite, colorSpaces[selectedColorProfile]->gfxColorSpace())); tx.commit(); @@ -248,7 +249,7 @@ void SpritePropertiesCommand::onExecute(Context* context) if (index != sprite->transparentColor() || pixelRatio != sprite->pixelRatio() || newUserData != sprite->userData()) { - Tx tx(writer.context(), "Change Sprite Properties"); + Tx tx(writer.context(), Strings::sprite_properties_change_sprite_props()); DocApi api = writer.document()->getApi(tx); if (index != sprite->transparentColor()) diff --git a/src/app/commands/cmd_sprite_size.cpp b/src/app/commands/cmd_sprite_size.cpp index 546c6bac6..aabbd99ff 100644 --- a/src/app/commands/cmd_sprite_size.cpp +++ b/src/app/commands/cmd_sprite_size.cpp @@ -17,6 +17,7 @@ #include "app/commands/params.h" #include "app/doc_api.h" #include "app/ini_file.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/modules/palettes.h" #include "app/sprite_job.h" @@ -80,7 +81,7 @@ class SpriteSizeJob : public SpriteJob { public: SpriteSizeJob(const ContextReader& reader, int new_width, int new_height, ResizeMethod resize_method) - : SpriteJob(reader, "Sprite Size") { + : SpriteJob(reader, Strings::sprite_size_title().c_str()) { m_new_width = new_width; m_new_height = new_height; m_resize_method = resize_method; @@ -263,9 +264,9 @@ public: doc::algorithm::RESIZE_METHOD_BILINEAR == 1 && doc::algorithm::RESIZE_METHOD_ROTSPRITE == 2, "ResizeMethod enum has changed"); - method()->addItem("Nearest-neighbor"); - method()->addItem("Bilinear"); - method()->addItem("RotSprite"); + method()->addItem(Strings::sprite_size_method_nearest_neighbor()); + method()->addItem(Strings::sprite_size_method_bilinear()); + method()->addItem(Strings::sprite_size_method_rotsprite()); int resize_method; if (params.method.isSet()) resize_method = (int)params.method(); diff --git a/src/app/commands/cmd_unlink_cel.cpp b/src/app/commands/cmd_unlink_cel.cpp index a57b6b135..6e544968b 100644 --- a/src/app/commands/cmd_unlink_cel.cpp +++ b/src/app/commands/cmd_unlink_cel.cpp @@ -12,6 +12,7 @@ #include "app/cmd/unlink_cel.h" #include "app/commands/command.h" #include "app/context_access.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/tx.h" #include "app/ui/status_bar.h" @@ -84,7 +85,7 @@ void UnlinkCelCommand::onExecute(Context* context) if (nonEditableLayers) StatusBar::instance()->showTip(1000, - "There are locked layers"); + Strings::statusbar_tips_locked_layers()); update_screen_for_document(document); } diff --git a/src/app/commands/command.cpp b/src/app/commands/command.cpp index 4ac363209..64b5563b6 100644 --- a/src/app/commands/command.cpp +++ b/src/app/commands/command.cpp @@ -20,12 +20,7 @@ Command::Command(const char* id, CommandFlags flags) : m_id(id) , m_flags(flags) { - std::string strId = "commands."; - strId += this->id(); - if (auto s = Strings::instance()) - m_friendlyName = s->translate(strId.c_str()); - else - m_friendlyName = strId; + generateFriendlyName(); } Command::~Command() @@ -69,6 +64,15 @@ bool Command::isChecked(Context* context) } } +void Command::generateFriendlyName() +{ + std::string strId = "commands." + this->id(); + if (auto s = Strings::instance()) + m_friendlyName = s->translate(strId.c_str()); + else + m_friendlyName = strId; +} + void Command::execute(Context* context) { onExecute(context); diff --git a/src/app/commands/command.h b/src/app/commands/command.h index 02eb47353..f3da3ac58 100644 --- a/src/app/commands/command.h +++ b/src/app/commands/command.h @@ -35,6 +35,7 @@ namespace app { void loadParams(const Params& params); bool isEnabled(Context* context); bool isChecked(Context* context); + void generateFriendlyName(); protected: virtual bool onNeedsParams() const; diff --git a/src/app/commands/filters/cmd_brightness_contrast.cpp b/src/app/commands/filters/cmd_brightness_contrast.cpp index 0a04a94ab..be55a20da 100644 --- a/src/app/commands/filters/cmd_brightness_contrast.cpp +++ b/src/app/commands/filters/cmd_brightness_contrast.cpp @@ -17,6 +17,7 @@ #include "app/commands/new_params.h" #include "app/context.h" #include "app/ini_file.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/ui/color_button.h" #include "app/ui/color_sliders.h" @@ -47,16 +48,20 @@ class BrightnessContrastWindow : public FilterWindow { public: BrightnessContrastWindow(BrightnessContrastFilter& filter, FilterManagerImpl& filterMgr) - : FilterWindow("Brightness/Contrast", ConfigSection, &filterMgr, + : FilterWindow(Strings::brightness_contrast_title().c_str(), + ConfigSection, + &filterMgr, WithChannelsSelector, WithoutTiledCheckBox) , m_brightness(-100, 100, int(100.0 * filter.brightness())) , m_contrast(-100, 100, int(100.0 * filter.contrast())) , m_filter(filter) { - getContainer()->addChild(new ui::Label("Brightness:")); + getContainer()->addChild( + new ui::Label(Strings::brightness_contrast_brightness_label())); getContainer()->addChild(&m_brightness); - getContainer()->addChild(new ui::Label("Contrast:")); + getContainer()->addChild( + new ui::Label(Strings::brightness_contrast_contrast_label())); getContainer()->addChild(&m_contrast); m_brightness.Change.connect([this]{ onChange(); }); m_contrast.Change.connect([this]{ onChange(); }); diff --git a/src/app/commands/filters/cmd_replace_color.cpp b/src/app/commands/filters/cmd_replace_color.cpp index d42f588fa..a852c1df6 100644 --- a/src/app/commands/filters/cmd_replace_color.cpp +++ b/src/app/commands/filters/cmd_replace_color.cpp @@ -22,6 +22,7 @@ #include "app/commands/new_params.h" #include "app/context.h" #include "app/find_widget.h" +#include "app/i18n/strings.h" #include "app/ini_file.h" #include "app/load_widget.h" #include "app/pref/preferences.h" @@ -78,7 +79,9 @@ static const char* ConfigSection = "ReplaceColor"; class ReplaceColorWindow : public FilterWindow { public: ReplaceColorWindow(ReplaceColorFilterWrapper& filter, FilterManagerImpl& filterMgr) - : FilterWindow("Replace Color", ConfigSection, &filterMgr, + : FilterWindow(Strings::replace_color_title().c_str(), + ConfigSection, + &filterMgr, WithChannelsSelector, WithoutTiledCheckBox) , m_filter(filter) diff --git a/src/app/commands/filters/filter_window.cpp b/src/app/commands/filters/filter_window.cpp index dafc292a3..cb96d55ac 100644 --- a/src/app/commands/filters/filter_window.cpp +++ b/src/app/commands/filters/filter_window.cpp @@ -13,6 +13,7 @@ #include "app/commands/filters/filter_manager_impl.h" #include "app/commands/filters/filter_worker.h" +#include "app/i18n/strings.h" #include "app/ini_file.h" #include "app/modules/editors.h" #include "app/modules/gui.h" @@ -35,12 +36,14 @@ FilterWindow::FilterWindow(const char* title, const char* cfgSection, , m_hbox(HORIZONTAL) , m_vbox(VERTICAL) , m_container(VERTICAL) - , m_okButton("&OK") - , m_cancelButton("&Cancel") + , m_okButton(Strings::filters_ok()) + , m_cancelButton(Strings::filters_cancel()) , m_preview(filterMgr) , m_targetButton(filterMgr->pixelFormat(), (withChannels == WithChannelsSelector)) - , m_showPreview("&Preview") - , m_tiledCheck(withTiled == WithTiledCheckBox ? new CheckBox("&Tiled") : NULL) + , m_showPreview(Strings::filters_preview()) + , m_tiledCheck(withTiled == WithTiledCheckBox ? + new CheckBox(Strings::filters_tiled()) : + nullptr) { m_okButton.processMnemonicFromText(); m_cancelButton.processMnemonicFromText(); diff --git a/src/app/commands/filters/filter_worker.cpp b/src/app/commands/filters/filter_worker.cpp index bd2e1fdbe..a378cee55 100644 --- a/src/app/commands/filters/filter_worker.cpp +++ b/src/app/commands/filters/filter_worker.cpp @@ -170,8 +170,8 @@ void FilterWorker::run() console.printf("A problem has occurred.\n\nDetails:\n%s", m_error.c_str()); } else if (m_cancelled && !m_filterMgr->isTransaction()) { - StatusBar::instance() - ->showTip(2500, "No unlocked layers to apply filter"); + StatusBar::instance()->showTip(2500, + Strings::statusbar_tips_filter_no_unlocked_layer()); } #endif // ENABLE_UI } diff --git a/src/app/console.cpp b/src/app/console.cpp index 051d3fb94..bf7eefd85 100644 --- a/src/app/console.cpp +++ b/src/app/console.cpp @@ -13,6 +13,7 @@ #include "app/app.h" #include "app/context.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/ui/main_window.h" #include "app/ui/status_bar.h" @@ -35,9 +36,9 @@ Console::ConsoleWindow* Console::m_console = nullptr; class Console::ConsoleWindow final : public Window { public: - ConsoleWindow() : Window(Window::WithTitleBar, "Console"), + ConsoleWindow() : Window(Window::WithTitleBar, Strings::debugger_console()), m_textbox("", WORDWRAP), - m_button("Cancel") { + m_button(Strings::debugger_cancel()) { TRACE_CON("CON: ConsoleWindow this=", this); m_button.Click.connect([this]{ closeWindow(&m_button); }); diff --git a/src/app/tools/ink_type.cpp b/src/app/tools/ink_type.cpp index 0af9d25e1..d47bc137d 100644 --- a/src/app/tools/ink_type.cpp +++ b/src/app/tools/ink_type.cpp @@ -10,6 +10,7 @@ #endif #include "app/tools/ink_type.h" +#include "app/i18n/strings.h" namespace app { namespace tools { @@ -17,13 +18,13 @@ namespace tools { std::string ink_type_to_string(InkType inkType) { switch (inkType) { - case tools::InkType::SIMPLE: return "Simple Ink"; - case tools::InkType::ALPHA_COMPOSITING: return "Alpha Compositing"; - case tools::InkType::COPY_COLOR: return "Copy Color+Alpha"; - case tools::InkType::LOCK_ALPHA: return "Lock Alpha"; - case tools::InkType::SHADING: return "Shading"; + case tools::InkType::SIMPLE: return Strings::inks_simple_ink(); + case tools::InkType::ALPHA_COMPOSITING: return Strings::inks_alpha_compositing(); + case tools::InkType::COPY_COLOR: return Strings::inks_copy_color(); + case tools::InkType::LOCK_ALPHA: return Strings::inks_lock_alpha(); + case tools::InkType::SHADING: return Strings::inks_shading(); } - return "Unknown"; + return Strings::general_unknown(); } std::string ink_type_to_string_id(InkType inkType) diff --git a/src/app/ui/brush_popup.cpp b/src/app/ui/brush_popup.cpp index dc6fadd8a..62e0c543d 100644 --- a/src/app/ui/brush_popup.cpp +++ b/src/app/ui/brush_popup.cpp @@ -15,6 +15,7 @@ #include "app/brush_slot.h" #include "app/commands/command.h" #include "app/commands/commands.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/modules/palettes.h" #include "app/pref/preferences.h" @@ -160,10 +161,10 @@ private: void onClick() override { Menu menu; - AppMenuItem save("Save Brush Here"); - AppMenuItem lockItem("Locked"); - AppMenuItem deleteItem("Delete"); - AppMenuItem deleteAllItem("Delete All"); + AppMenuItem save(Strings::brush_slot_params_save_brush()); + AppMenuItem lockItem(Strings::brush_slot_params_locked()); + AppMenuItem deleteItem(Strings::brush_slot_params_delete()); + AppMenuItem deleteAllItem(Strings::brush_slot_params_delete_all()); lockItem.setSelected(m_brushes.isBrushSlotLocked(m_slot)); @@ -179,7 +180,8 @@ private: menu.addChild(new MenuSeparator); menu.addChild(&deleteAllItem); menu.addChild(new Label("")); - menu.addChild(new Separator("Saved Parameters", HORIZONTAL)); + menu.addChild( + new Separator(Strings::brush_slot_params_saved_parameters(), HORIZONTAL)); app::gen::BrushSlotParams params; menu.addChild(¶ms); @@ -263,7 +265,7 @@ private: class NewCustomBrushItem : public ButtonSet::Item { public: NewCustomBrushItem() { - setText("Save Brush"); + setText(Strings::brush_slot_params_save_brush()); } private: diff --git a/src/app/ui/color_bar.cpp b/src/app/ui/color_bar.cpp index e45234c3a..c11532fce 100644 --- a/src/app/ui/color_bar.cpp +++ b/src/app/ui/color_bar.cpp @@ -1456,7 +1456,7 @@ void ColorBar::onReverseColors() } Palette newPalette(*get_current_palette(), remap); - setPalette(&newPalette, "Reverse Colors"); + setPalette(&newPalette, Strings::color_bar_reverse_colors()); } void ColorBar::onSortBy(SortPaletteBy channel) @@ -1500,7 +1500,7 @@ void ColorBar::onSortBy(SortPaletteBy channel) // Create a new palette and apply the remap. This is the final new // palette for the sprite. Palette newPalette(palette, remapOrig); - setPalette(&newPalette, "Sort Colors"); + setPalette(&newPalette, Strings::color_bar_sort_colors()); } void ColorBar::onGradient(GradientType gradientType) @@ -1512,11 +1512,11 @@ void ColorBar::onGradient(GradientType gradientType) Palette newPalette(*get_current_palette()); if (gradientType == GradientType::LINEAR) { newPalette.makeGradient(index1, index2); - setPalette(&newPalette, "Gradient"); + setPalette(&newPalette, Strings::color_bar_gradient()); } else { newPalette.makeHueGradient(index1, index2); - setPalette(&newPalette, "Gradient by Hue"); + setPalette(&newPalette, Strings::color_bar_gradient_by_hue()); } } @@ -1919,19 +1919,19 @@ void ColorBar::showPaletteSortOptions() Menu menu; MenuItem - rev("Reverse Colors"), - grd("Gradient"), - grh("Gradient by Hue"), - hue("Sort by Hue"), - sat("Sort by Saturation"), - bri("Sort by Brightness"), - lum("Sort by Luminance"), - red("Sort by Red"), - grn("Sort by Green"), - blu("Sort by Blue"), - alp("Sort by Alpha"), - asc("Ascending"), - des("Descending"); + rev(Strings::color_bar_reverse_colors()), + grd(Strings::color_bar_gradient()), + grh(Strings::color_bar_gradient_by_hue()), + hue(Strings::color_bar_sort_by_hue()), + sat(Strings::color_bar_sort_by_saturation()), + bri(Strings::color_bar_sort_by_brightness()), + lum(Strings::color_bar_sort_by_luminance()), + red(Strings::color_bar_sort_by_red()), + grn(Strings::color_bar_sort_by_green()), + blu(Strings::color_bar_sort_by_blue()), + alp(Strings::color_bar_sort_by_alpha()), + asc(Strings::color_bar_ascending()), + des(Strings::color_bar_descending()); menu.addChild(&rev); menu.addChild(&grd); menu.addChild(&grh); diff --git a/src/app/ui/color_popup.cpp b/src/app/ui/color_popup.cpp index edcfe90ce..a21f2188c 100644 --- a/src/app/ui/color_popup.cpp +++ b/src/app/ui/color_popup.cpp @@ -19,6 +19,7 @@ #include "app/context_access.h" #include "app/doc.h" #include "app/file/palette_file.h" +#include "app/i18n/strings.h" #include "app/modules/gfx.h" #include "app/modules/gui.h" #include "app/modules/palettes.h" @@ -179,7 +180,7 @@ ColorPopup::ColorPopup(const ColorButtonOptions& options) nullptr) , m_simpleColors(nullptr) , m_oldAndNew(Shade(2), ColorShades::ClickEntries) - , m_maskLabel("Transparent Color Selected") + , m_maskLabel(Strings::color_popup_transparent_color_sel()) , m_canPin(options.canPinSelector) , m_insideChange(false) , m_disableHexUpdate(false) @@ -196,7 +197,7 @@ ColorPopup::ColorPopup(const ColorButtonOptions& options) m_simpleColors = new SimpleColors(this, &m_tooltips); } - ButtonSet::Item* item = m_colorType.addItem("Index"); + ButtonSet::Item* item = m_colorType.addItem(Strings::color_popup_index()); item->setFocusStop(false); if (!options.showIndexTab) item->setVisible(false); diff --git a/src/app/ui/color_wheel.cpp b/src/app/ui/color_wheel.cpp index 6cb906a37..e1e0a96df 100644 --- a/src/app/ui/color_wheel.cpp +++ b/src/app/ui/color_wheel.cpp @@ -12,6 +12,7 @@ #include "app/ui/color_wheel.h" #include "app/color_utils.h" +#include "app/i18n/strings.h" #include "app/pref/preferences.h" #include "app/ui/skin/skin_theme.h" #include "app/ui/status_bar.h" @@ -474,15 +475,15 @@ void ColorWheel::onResize(ui::ResizeEvent& ev) void ColorWheel::onOptions() { Menu menu; - MenuItem discrete("Discrete"); - MenuItem none("Without Harmonies"); - MenuItem complementary("Complementary"); - MenuItem monochromatic("Monochromatic"); - MenuItem analogous("Analogous"); - MenuItem split("Split-Complementary"); - MenuItem triadic("Triadic"); - MenuItem tetradic("Tetradic"); - MenuItem square("Square"); + MenuItem discrete(Strings::color_wheel_discrete()); + MenuItem none(Strings::color_wheel_no_harmonies()); + MenuItem complementary(Strings::color_wheel_complementary()); + MenuItem monochromatic(Strings::color_wheel_monochromatic()); + MenuItem analogous(Strings::color_wheel_analogous()); + MenuItem split(Strings::color_wheel_split_complementary()); + MenuItem triadic(Strings::color_wheel_triadic()); + MenuItem tetradic(Strings::color_wheel_tetradic()); + MenuItem square(Strings::color_wheel_square()); menu.addChild(&discrete); if (m_colorModel != ColorModel::NORMAL_MAP) { menu.addChild(new MenuSeparator); diff --git a/src/app/ui/context_bar.cpp b/src/app/ui/context_bar.cpp index 995cabdda..743ef31cf 100644 --- a/src/app/ui/context_bar.cpp +++ b/src/app/ui/context_bar.cpp @@ -97,8 +97,8 @@ public: ZoomButtons() : ButtonSet(3) { addItem("100%"); - addItem("Center"); - addItem("Fit Screen"); + addItem(Strings::context_bar_center()); + addItem(Strings::context_bar_fit_screen()); } private: @@ -142,7 +142,7 @@ class ContextBar::BrushBackField : public ButtonSet { public: BrushBackField() : ButtonSet(1) { - addItem("Back"); + addItem(Strings::context_bar_back()); } protected: @@ -294,9 +294,9 @@ public: // brush when we call ComboBox::addItem() (because the first // addItem() generates an onChange() event). m_lock = true; - addItem("Pattern aligned to source"); - addItem("Pattern aligned to destination"); - addItem("Paint brush"); + addItem(Strings::context_bar_pattern_aligned_to_src()); + addItem(Strings::context_bar_pattern_aligned_to_dest()); + addItem(Strings::context_bar_paint_brush()); m_lock = false; setSelectedItemIndex((int)Preferences::instance().brush.pattern()); @@ -356,7 +356,8 @@ protected: class ContextBar::ContiguousField : public CheckBox { public: - ContiguousField() : CheckBox("Contiguous") { + ContiguousField() + : CheckBox(Strings::context_bar_contiguous()) { initTheme(); } @@ -393,16 +394,16 @@ protected: Menu menu; MenuItem - stopAtGrid("Stop at Grid"), - activeLayer("Refer only active layer"), - allLayers("Refer visible layers"); + stopAtGrid(Strings::context_bar_stop_at_grid()), + activeLayer(Strings::context_bar_refer_active_layer()), + allLayers(Strings::context_bar_refer_visible_layer()); menu.addChild(&stopAtGrid); menu.addChild(new MenuSeparator()); menu.addChild(&activeLayer); menu.addChild(&allLayers); menu.addChild(new MenuSeparator); - menu.addChild(new Label("Pixel Connectivity:")); + menu.addChild(new Label(Strings::context_bar_pixel_connectivity())); HBox box; ButtonSet buttonset(2); @@ -525,7 +526,7 @@ public: addChild(&m_button); addChild(&m_shade); - m_shade.setText("Select colors in the palette"); + m_shade.setText(Strings::context_bar_select_palette_color()); m_shade.setMinColors(2); m_conn = colorBar->ChangeSelection.connect( [this]{ onChangeColorBarSelection(); }); @@ -582,8 +583,8 @@ private: Menu menu; MenuItem - reverse("Reverse Shade"), - save("Save Shade"); + reverse(Strings::context_bar_reverse_shade()), + save(Strings::context_bar_save_shade()); menu.addChild(&reverse); menu.addChild(&save); @@ -786,8 +787,10 @@ public: onOpaqueChange(); - tooltipManager->addTooltipFor(m_icon.at(0), "Transparent Color Options", BOTTOM); - tooltipManager->addTooltipFor(&m_maskColor, "Transparent Color", BOTTOM); + tooltipManager->addTooltipFor( + m_icon.at(0), Strings::context_bar_transparent_color_options(), BOTTOM); + tooltipManager->addTooltipFor( + &m_maskColor, Strings::context_bar_transparent_color(), BOTTOM); } private: @@ -797,9 +800,9 @@ private: Menu menu; MenuItem - opaque("Opaque"), - masked("Transparent"), - automatic("Adjust automatically depending on layer type"); + opaque(Strings::context_bar_opaque()), + masked(Strings::context_bar_transparent()), + automatic(Strings::context_bar_auto_adjust_layer()); menu.addChild(&opaque); menu.addChild(&masked); menu.addChild(new MenuSeparator); @@ -878,7 +881,7 @@ private: gfx::Rect bounds = this->bounds(); Menu menu; - CheckBox visible("Display pivot by default"); + CheckBox visible(Strings::context_bar_default_display_pivot()); HBox box; ButtonSet buttonset(3); buttonset.addItem(theme->parts.pivotNorthwest()); @@ -945,8 +948,10 @@ public: // algorithm when we call ComboBox::addItem() (because the first // addItem() generates an onChange() event). m_lockChange = true; - addItem(new Item("Fast Rotation", tools::RotationAlgorithm::FAST)); - addItem(new Item("RotSprite", tools::RotationAlgorithm::ROTSPRITE)); + addItem( + new Item(Strings::context_bar_fast_rotation(), tools::RotationAlgorithm::FAST)); + addItem( + new Item(Strings::context_bar_rotsprite(), tools::RotationAlgorithm::ROTSPRITE)); m_lockChange = false; setSelectedItemIndex((int)Preferences::instance().selection.rotationAlgorithm()); @@ -1219,7 +1224,9 @@ private: class ContextBar::FreehandAlgorithmField : public CheckBox { public: - FreehandAlgorithmField() : CheckBox("Pixel-perfect") { + FreehandAlgorithmField() + : CheckBox(Strings::context_bar_pixel_perfect()) + { initTheme(); } @@ -1277,8 +1284,10 @@ public: } void setupTooltips(TooltipManager* tooltipManager) { - tooltipManager->addTooltipFor(at(0), "Linear Gradient", BOTTOM); - tooltipManager->addTooltipFor(at(1), "Radial Gradient", BOTTOM); + tooltipManager->addTooltipFor( + at(0), Strings::context_bar_linear_gradient(), BOTTOM); + tooltipManager->addTooltipFor( + at(1), Strings::context_bar_radial_gradient(), BOTTOM); } render::GradientType gradientType() const { @@ -1298,8 +1307,8 @@ public: void setupTooltips(TooltipManager* tooltipManager) { // TODO Enter and Esc should be configurable keys - tooltipManager->addTooltipFor(at(0), "Drop pixels here (Enter)", BOTTOM); - tooltipManager->addTooltipFor(at(1), "Cancel drag and drop (Esc)", BOTTOM); + tooltipManager->addTooltipFor(at(0), Strings::context_bar_drop_pixel(), BOTTOM); + tooltipManager->addTooltipFor(at(1), Strings::context_bar_cancel_drag(), BOTTOM); } obs::signal DropPixels; @@ -1329,15 +1338,15 @@ public: m_channel.addItem("HSL"); m_channel.addItem("Gray+Alpha"); m_channel.addItem("Gray"); - m_channel.addItem("Best fit Index"); + m_channel.addItem(Strings::context_bar_best_fit_index()); - m_sample.addItem("All Layers"); - m_sample.addItem("Current Layer"); - m_sample.addItem("First Reference Layer"); + m_sample.addItem(Strings::context_bar_all_layers()); + m_sample.addItem(Strings::context_bar_current_layer()); + m_sample.addItem(Strings::context_bar_first_ref_layer()); - addChild(new Label("Pick:")); + addChild(new Label(Strings::context_bar_pick())); addChild(&m_channel); - addChild(new Label("Sample:")); + addChild(new Label(Strings::context_bar_sample())); addChild(&m_sample); m_channel.Change.connect([this]{ onChannelChange(); }); @@ -1366,7 +1375,9 @@ private: class ContextBar::AutoSelectLayerField : public CheckBox { public: - AutoSelectLayerField() : CheckBox("Auto Select Layer") { + AutoSelectLayerField() + : CheckBox(Strings::context_bar_auto_select_layer()) + { initTheme(); } @@ -1521,8 +1532,8 @@ public: { auto theme = SkinTheme::get(this); - m_sel.addItem("All"); - m_sel.addItem("None"); + m_sel.addItem(Strings::context_bar_all()); + m_sel.addItem(Strings::context_bar_none()); m_sel.ItemChange.connect( [this](ButtonSet::Item* item){ onSelAction(m_sel.selectedItem()); @@ -1548,10 +1559,14 @@ public: } void setupTooltips(TooltipManager* tooltipManager) { - tooltipManager->addTooltipFor(m_sel.at(0), "Select All Slices", BOTTOM); - tooltipManager->addTooltipFor(m_sel.at(1), "Deselect Slices", BOTTOM); - tooltipManager->addTooltipFor(m_action.at(0), "Slice Properties", BOTTOM); - tooltipManager->addTooltipFor(m_action.at(1), "Delete Slice", BOTTOM); + tooltipManager->addTooltipFor( + m_sel.at(0), Strings::context_bar_select_slices(), BOTTOM); + tooltipManager->addTooltipFor( + m_sel.at(1), Strings::context_bar_deselect_slices(), BOTTOM); + tooltipManager->addTooltipFor( + m_action.at(0), Strings::context_bar_slice_props(), BOTTOM); + tooltipManager->addTooltipFor( + m_action.at(1), Strings::context_bar_delete_slice(), BOTTOM); } void setDoc(Doc* doc) { @@ -2448,26 +2463,38 @@ const tools::DynamicsOptions& ContextBar::getDynamics() const void ContextBar::setupTooltips(TooltipManager* tooltipManager) { - tooltipManager->addTooltipFor(m_brushBack->at(0), "Discard Brush (Esc)", BOTTOM); - tooltipManager->addTooltipFor(m_brushType->at(0), "Brush Type", BOTTOM); - tooltipManager->addTooltipFor(m_brushSize, "Brush Size (in pixels)", BOTTOM); - tooltipManager->addTooltipFor(m_brushAngle, "Brush Angle (in degrees)", BOTTOM); - tooltipManager->addTooltipFor(m_inkType->at(0), "Ink", BOTTOM); - tooltipManager->addTooltipFor(m_inkOpacity, "Opacity (paint intensity)", BOTTOM); - tooltipManager->addTooltipFor(m_inkShades->at(0), "Shades", BOTTOM); - tooltipManager->addTooltipFor(m_sprayWidth, "Spray Width", BOTTOM); - tooltipManager->addTooltipFor(m_spraySpeed, "Spray Speed", BOTTOM); - tooltipManager->addTooltipFor(m_pivot->at(0), "Rotation Pivot", BOTTOM); - tooltipManager->addTooltipFor(m_rotAlgo, "Rotation Algorithm", BOTTOM); - tooltipManager->addTooltipFor(m_dynamics->at(0), "Dynamics", BOTTOM); + tooltipManager->addTooltipFor( + m_brushBack->at(0), Strings::context_bar_discard_brush(), BOTTOM); + tooltipManager->addTooltipFor( + m_brushType->at(0), Strings::context_bar_brush_type(), BOTTOM); + tooltipManager->addTooltipFor( + m_brushSize, Strings::context_bar_brush_size(), BOTTOM); + tooltipManager->addTooltipFor( + m_brushAngle, Strings::context_bar_brush_angle(), BOTTOM); + tooltipManager->addTooltipFor( + m_inkType->at(0), Strings::context_bar_ink(), BOTTOM); + tooltipManager->addTooltipFor( + m_inkOpacity, Strings::context_bar_opacity(), BOTTOM); + tooltipManager->addTooltipFor( + m_inkShades->at(0), Strings::context_bar_shades(), BOTTOM); + tooltipManager->addTooltipFor( + m_sprayWidth, Strings::context_bar_spray_width(), BOTTOM); + tooltipManager->addTooltipFor( + m_spraySpeed, Strings::context_bar_spray_speed(), BOTTOM); + tooltipManager->addTooltipFor( + m_pivot->at(0), Strings::context_bar_rotation_pivot(), BOTTOM); + tooltipManager->addTooltipFor( + m_rotAlgo, Strings::context_bar_rotation_algorithm(), BOTTOM); + tooltipManager->addTooltipFor( + m_dynamics->at(0), Strings::context_bar_dynamics(), BOTTOM); tooltipManager->addTooltipFor(m_freehandAlgo, key_tooltip("Freehand trace algorithm", CommandId::PixelPerfectMode()), BOTTOM); tooltipManager->addTooltipFor(m_contiguous, key_tooltip("Fill contiguous areas color", CommandId::ContiguousFill()), BOTTOM); - tooltipManager->addTooltipFor(m_paintBucketSettings->at(0), - "Extra paint bucket options", BOTTOM); + tooltipManager->addTooltipFor( + m_paintBucketSettings->at(0), Strings::context_bar_paint_bucket_option(), BOTTOM); m_selectionMode->setupTooltips(tooltipManager); m_gradientType->setupTooltips(tooltipManager); diff --git a/src/app/ui/dithering_selector.cpp b/src/app/ui/dithering_selector.cpp index 21de48680..54f7c9e80 100644 --- a/src/app/ui/dithering_selector.cpp +++ b/src/app/ui/dithering_selector.cpp @@ -13,6 +13,7 @@ #include "app/app.h" #include "app/extensions.h" +#include "app/i18n/strings.h" #include "app/modules/palettes.h" #include "app/ui/skin/skin_theme.h" #include "app/util/conversion_to_surface.h" @@ -206,29 +207,30 @@ void DitheringSelector::regenerate() switch (m_type) { case SelectBoth: addItem(new DitherItem(render::DitheringAlgorithm::None, - render::DitheringMatrix(), "No Dithering")); + render::DitheringMatrix(), + Strings::dithering_selector_no_dithering())); for (const auto& it : ditheringMatrices) { - addItem( - new DitherItem( - render::DitheringAlgorithm::Ordered, - it.matrix(), - "Ordered Dithering+" + it.name())); + addItem(new DitherItem( + render::DitheringAlgorithm::Ordered, + it.matrix(), + Strings::dithering_selector_ordered_dithering() + it.name())); } for (const auto& it : ditheringMatrices) { addItem( new DitherItem( render::DitheringAlgorithm::Old, it.matrix(), - "Old Dithering+" + it.name())); + Strings::dithering_selector_old_dithering() + it.name())); } addItem( new DitherItem( render::DitheringAlgorithm::ErrorDiffusion, render::DitheringMatrix(), - "Floyd-Steinberg Error Diffusion Dithering")); + Strings::dithering_selector_floyd_steinberg())); break; case SelectMatrix: - addItem(new DitherItem(render::DitheringMatrix(), "No Dithering")); + addItem(new DitherItem(render::DitheringMatrix(), + Strings::dithering_selector_no_dithering())); for (auto& it : ditheringMatrices) addItem(new DitherItem(it.matrix(), it.name())); break; diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp index a649c472a..619aee24d 100644 --- a/src/app/ui/editor/editor.cpp +++ b/src/app/ui/editor/editor.cpp @@ -2798,7 +2798,7 @@ void Editor::showAnimationSpeedMultiplierPopup(Option& playOnce, Menu menu; for (double option : options) { - MenuItem* item = new MenuItem(fmt::format("Speed x{}", option)); + MenuItem* item = new MenuItem(fmt::format(Strings::preview_speed_x(), option)); item->Click.connect([this, option]{ setAnimationSpeedMultiplier(option); }); item->setSelected(m_aniSpeed == option); menu.addChild(item); @@ -2808,7 +2808,7 @@ void Editor::showAnimationSpeedMultiplierPopup(Option& playOnce, // Play once option { - MenuItem* item = new MenuItem("Play Once"); + MenuItem* item = new MenuItem(Strings::preview_play_once()); item->Click.connect( [&playOnce]() { playOnce(!playOnce()); @@ -2819,7 +2819,7 @@ void Editor::showAnimationSpeedMultiplierPopup(Option& playOnce, // Play all option { - MenuItem* item = new MenuItem("Play All Frames (Ignore Tags)"); + MenuItem* item = new MenuItem(Strings::preview_play_all_no_tags()); item->Click.connect( [&playAll]() { playAll(!playAll()); @@ -2829,7 +2829,7 @@ void Editor::showAnimationSpeedMultiplierPopup(Option& playOnce, } if (withStopBehaviorOptions) { - MenuItem* item = new MenuItem("Rewind on Stop"); + MenuItem* item = new MenuItem(Strings::preview_rewind_on_stop()); item->Click.connect( []() { // Switch the "rewind_on_stop" option diff --git a/src/app/ui/editor/pixels_movement.cpp b/src/app/ui/editor/pixels_movement.cpp index 6784aa122..7c6168dba 100644 --- a/src/app/ui/editor/pixels_movement.cpp +++ b/src/app/ui/editor/pixels_movement.cpp @@ -19,6 +19,7 @@ #include "app/console.h" #include "app/doc.h" #include "app/doc_api.h" +#include "app/i18n/strings.h" #include "app/modules/gui.h" #include "app/pref/preferences.h" #include "app/site.h" @@ -1170,8 +1171,9 @@ retry:; // In case that we don't have enough memory for RotSprite int(corners.leftBottom().y-leftTop.y)); } catch (const std::bad_alloc&) { - StatusBar::instance()->showTip(1000, - "Not enough memory for RotSprite"); + StatusBar::instance()->showTip( + 1000, + Strings::statusbar_tips_not_enough_rotsprite_memory()); rotAlgo = tools::RotationAlgorithm::FAST; goto retry; diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp index 6ae1cc377..fbce4fb5c 100644 --- a/src/app/ui/editor/standby_state.cpp +++ b/src/app/ui/editor/standby_state.cpp @@ -180,12 +180,14 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg) if (layer) { // TODO we should be able to move the `Background' with tiled mode if (layer->isBackground()) { - StatusBar::instance()->showTip(1000, - "The background layer cannot be moved"); + StatusBar::instance()->showTip( + 1000, Strings::statusbar_tips_cannot_move_bg_layer()); } else if (!layer->isVisibleHierarchy()) { StatusBar::instance()->showTip( - 1000, fmt::format("Layer '{}' is hidden", layer->name())); + 1000, + fmt::format(Strings::statusbar_tips_layer_x_is_hidden(), + layer->name())); } else if (!layer->isMovable() || !layer->isEditableHierarchy()) { StatusBar::instance()->showTip( @@ -195,7 +197,7 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg) MovingCelCollect collect(editor, layer); if (collect.empty()) { StatusBar::instance()->showTip( - 1000, "Nothing to move"); + 1000, Strings::statusbar_tips_nothing_to_move()); } else { try { @@ -211,7 +213,7 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg) catch (const LockedDocException&) { // TODO break the background task that is locking this sprite StatusBar::instance()->showTip( - 1000, "Sprite is used by a backup/data recovery task"); + 1000, Strings::statusbar_tips_recovery_task_using_sprite()); } } } @@ -748,7 +750,8 @@ void StandbyState::transformSelection(Editor* editor, MouseMessage* msg, HandleT Layer* layer = editor->layer(); if (layer && layer->isReference()) { StatusBar::instance()->showTip( - 1000, fmt::format("Layer '{}' is reference, cannot be transformed", + 1000, + fmt::format(Strings::statusbar_tips_non_transformable_reference_layer(), layer->name())); return; } @@ -803,11 +806,13 @@ void StandbyState::transformSelection(Editor* editor, MouseMessage* msg, HandleT // Other editor is locking the document. // TODO steal the PixelsMovement of the other editor and use it for this one. - StatusBar::instance()->showTip(1000, "The sprite is locked in other editor"); + StatusBar::instance()->showTip( + 1000, Strings::statusbar_tips_sprite_locked_somewhere()); editor->showMouseCursor(kForbiddenCursor); } catch (const std::bad_alloc&) { - StatusBar::instance()->showTip(1000, "Not enough memory to transform the selection"); + StatusBar::instance()->showTip( + 1000, Strings::statusbar_tips_not_enough_transform_memory()); editor->showMouseCursor(kForbiddenCursor); } } diff --git a/src/app/ui/editor/tool_loop_impl.cpp b/src/app/ui/editor/tool_loop_impl.cpp index 539870085..85c843ffa 100644 --- a/src/app/ui/editor/tool_loop_impl.cpp +++ b/src/app/ui/editor/tool_loop_impl.cpp @@ -818,12 +818,14 @@ tools::ToolLoop* create_tool_loop( Layer* layer = site.layer(); if (!layer) { StatusBar::instance()->showTip( - 1000, "There is no active layer"); + 1000, Strings::statusbar_tips_no_active_layers()); return nullptr; } else if (!layer->isVisibleHierarchy()) { StatusBar::instance()->showTip( - 1000, fmt::format("Layer '{}' is hidden", layer->name())); + 1000, + fmt::format(Strings::statusbar_tips_layer_x_is_hidden(), + layer->name())); return nullptr; } // If the active layer is read-only. @@ -833,7 +835,9 @@ tools::ToolLoop* create_tool_loop( // If the active layer is reference. else if (layer->isReference()) { StatusBar::instance()->showTip( - 1000, fmt::format("Layer '{}' is reference, cannot be modified", layer->name())); + 1000, + fmt::format(Strings::statusbar_tips_unmodifiable_reference_layer(), + layer->name())); return nullptr; } } diff --git a/src/app/ui/file_selector.cpp b/src/app/ui/file_selector.cpp index 700e47998..b2f8801f4 100644 --- a/src/app/ui/file_selector.cpp +++ b/src/app/ui/file_selector.cpp @@ -485,7 +485,8 @@ bool FileSelector::show( // File type for all formats fileType()->addItem( - new CustomFileExtensionItem("All formats", allExtensions)); + new CustomFileExtensionItem(Strings::file_selector_all_formats(), + allExtensions)); // One file type for each supported image format for (const auto& e : allExtensions) { @@ -499,7 +500,7 @@ bool FileSelector::show( } // All files fileType()->addItem( - new CustomFileExtensionItem("All files", + new CustomFileExtensionItem(Strings::file_selector_all_files(), base::paths())); // Empty extensions means "*.*" // file name entry field diff --git a/src/app/ui/font_popup.cpp b/src/app/ui/font_popup.cpp index 450444d66..9dbfebda1 100644 --- a/src/app/ui/font_popup.cpp +++ b/src/app/ui/font_popup.cpp @@ -15,6 +15,7 @@ #include "app/commands/commands.h" #include "app/console.h" #include "app/font_path.h" +#include "app/i18n/strings.h" #include "app/match_words.h" #include "app/ui/search_entry.h" #include "app/ui/skin/skin_theme.h" @@ -133,7 +134,7 @@ private: }; FontPopup::FontPopup() - : PopupWindow("Fonts", + : PopupWindow(Strings::font_popup_title(), ClickBehavior::CloseOnClickInOtherWindow, EnterBehavior::DoNothingOnEnter) , m_popup(new gen::FontPopup()) @@ -181,7 +182,7 @@ FontPopup::FontPopup() } if (m_listBox.children().empty()) - m_listBox.addChild(new ListItem("No system fonts were found")); + m_listBox.addChild(new ListItem(Strings::font_popup_empty_fonts())); } void FontPopup::showPopup(Display* display, diff --git a/src/app/ui/keyboard_shortcuts.cpp b/src/app/ui/keyboard_shortcuts.cpp index 5b6de243c..e83f444d1 100644 --- a/src/app/ui/keyboard_shortcuts.cpp +++ b/src/app/ui/keyboard_shortcuts.cpp @@ -15,9 +15,9 @@ #include "app/app_menus.h" #include "app/commands/command.h" #include "app/commands/commands.h" -#include "app/commands/commands.h" #include "app/commands/params.h" #include "app/doc.h" +#include "app/i18n/strings.h" #include "app/tools/active_tool.h" #include "app/tools/ink.h" #include "app/tools/tool.h" @@ -36,41 +36,51 @@ #define XML_KEYBOARD_FILE_VERSION "1" +#define I18N_KEY(a) app::Strings::keyboard_shortcuts_##a() + namespace { - static struct { + struct KeyShortcutAction { const char* name; - const char* userfriendly; + std::string userfriendly; app::KeyAction action; app::KeyContext context; - } actions[] = { - { "CopySelection" , "Copy Selection" , app::KeyAction::CopySelection, app::KeyContext::TranslatingSelection }, - { "SnapToGrid" , "Snap To Grid" , app::KeyAction::SnapToGrid, app::KeyContext::TranslatingSelection }, - { "LockAxis" , "Lock Axis" , app::KeyAction::LockAxis, app::KeyContext::TranslatingSelection }, - { "FineControl" , "Fine Translating" , app::KeyAction::FineControl , app::KeyContext::TranslatingSelection }, - { "MaintainAspectRatio" , "Maintain Aspect Ratio", app::KeyAction::MaintainAspectRatio, app::KeyContext::ScalingSelection }, - { "ScaleFromCenter" , "Scale From Center" , app::KeyAction::ScaleFromCenter, app::KeyContext::ScalingSelection }, - { "FineControl" , "Fine Scaling" , app::KeyAction::FineControl , app::KeyContext::ScalingSelection }, - { "AngleSnap" , "Angle Snap" , app::KeyAction::AngleSnap, app::KeyContext::RotatingSelection }, - { "AddSelection" , "Add Selection" , app::KeyAction::AddSelection, app::KeyContext::SelectionTool }, - { "SubtractSelection" , "Subtract Selection" , app::KeyAction::SubtractSelection, app::KeyContext::SelectionTool }, - { "IntersectSelection" , "Intersect Selection" , app::KeyAction::IntersectSelection, app::KeyContext::SelectionTool }, - { "AutoSelectLayer" , "Auto Select Layer" , app::KeyAction::AutoSelectLayer, app::KeyContext::MoveTool }, - { "StraightLineFromLastPoint", "Straight Line from Last Point", app::KeyAction::StraightLineFromLastPoint, app::KeyContext::FreehandTool }, - { "AngleSnapFromLastPoint", "Angle Snap from Last Point", app::KeyAction::AngleSnapFromLastPoint, app::KeyContext::FreehandTool }, - { "MoveOrigin" , "Move Origin" , app::KeyAction::MoveOrigin, app::KeyContext::ShapeTool }, - { "SquareAspect" , "Square Aspect" , app::KeyAction::SquareAspect, app::KeyContext::ShapeTool }, - { "DrawFromCenter" , "Draw From Center" , app::KeyAction::DrawFromCenter, app::KeyContext::ShapeTool }, - { "RotateShape" , "Rotate Shape" , app::KeyAction::RotateShape, app::KeyContext::ShapeTool }, - { "LeftMouseButton" , "Trigger Left Mouse Button" , app::KeyAction::LeftMouseButton, app::KeyContext::Any }, - { "RightMouseButton" , "Trigger Right Mouse Button" , app::KeyAction::RightMouseButton, app::KeyContext::Any }, - { NULL , NULL , app::KeyAction::None, app::KeyContext::Any } }; + static std::vector g_actions; + + static const std::vector& actions() { + if (g_actions.empty()) { + g_actions = std::vector { + { "CopySelection" , I18N_KEY(copy_selection) , app::KeyAction::CopySelection, app::KeyContext::TranslatingSelection }, + { "SnapToGrid" , I18N_KEY(snap_to_grid) , app::KeyAction::SnapToGrid, app::KeyContext::TranslatingSelection }, + { "LockAxis" , I18N_KEY(lock_axis) , app::KeyAction::LockAxis, app::KeyContext::TranslatingSelection }, + { "FineControl" , I18N_KEY(fine_translating) , app::KeyAction::FineControl , app::KeyContext::TranslatingSelection }, + { "MaintainAspectRatio" , I18N_KEY(maintain_aspect_ratio) , app::KeyAction::MaintainAspectRatio, app::KeyContext::ScalingSelection }, + { "ScaleFromCenter" , I18N_KEY(scale_from_center) , app::KeyAction::ScaleFromCenter, app::KeyContext::ScalingSelection }, + { "FineControl" , I18N_KEY(fine_scaling) , app::KeyAction::FineControl , app::KeyContext::ScalingSelection }, + { "AngleSnap" , I18N_KEY(angle_snap) , app::KeyAction::AngleSnap, app::KeyContext::RotatingSelection }, + { "AddSelection" , I18N_KEY(add_selection) , app::KeyAction::AddSelection, app::KeyContext::SelectionTool }, + { "SubtractSelection" , I18N_KEY(subtract_selection) , app::KeyAction::SubtractSelection, app::KeyContext::SelectionTool }, + { "IntersectSelection" , I18N_KEY(intersect_selection) , app::KeyAction::IntersectSelection, app::KeyContext::SelectionTool }, + { "AutoSelectLayer" , I18N_KEY(auto_select_layer) , app::KeyAction::AutoSelectLayer, app::KeyContext::MoveTool }, + { "StraightLineFromLastPoint", I18N_KEY(line_from_last_point) , app::KeyAction::StraightLineFromLastPoint, app::KeyContext::FreehandTool }, + { "AngleSnapFromLastPoint", I18N_KEY(angle_from_last_point) , app::KeyAction::AngleSnapFromLastPoint, app::KeyContext::FreehandTool }, + { "MoveOrigin" , I18N_KEY(move_origin) , app::KeyAction::MoveOrigin, app::KeyContext::ShapeTool }, + { "SquareAspect" , I18N_KEY(square_aspect) , app::KeyAction::SquareAspect, app::KeyContext::ShapeTool }, + { "DrawFromCenter" , I18N_KEY(draw_from_center) , app::KeyAction::DrawFromCenter, app::KeyContext::ShapeTool }, + { "RotateShape" , I18N_KEY(rotate_shape) , app::KeyAction::RotateShape, app::KeyContext::ShapeTool }, + { "LeftMouseButton" , I18N_KEY(trigger_left_mouse_button) , app::KeyAction::LeftMouseButton, app::KeyContext::Any }, + { "RightMouseButton" , I18N_KEY(trigger_right_mouse_button) , app::KeyAction::RightMouseButton, app::KeyContext::Any } + }; + } + return g_actions; + } + static struct { const char* name; app::KeyContext context; - } contexts[] = { + } g_contexts[] = { { "" , app::KeyContext::Any }, { "Normal" , app::KeyContext::Normal }, { "Selection" , app::KeyContext::SelectionTool }, @@ -85,38 +95,47 @@ namespace { using Vec = app::DragVector; - static struct { + struct KeyShortcutWheelAction { const char* name; - const char* userfriendly; + const std::string userfriendly; Vec vector; - } wheel_actions[] = { - { "" , "" , Vec(0.0, 0.0) }, - { "Zoom" , "Zoom" , Vec(8.0, 0.0) }, - { "VScroll" , "Scroll: Vertically" , Vec(4.0, 0.0) }, - { "HScroll" , "Scroll: Horizontally" , Vec(4.0, 0.0) }, - { "FgColor" , "Color: Foreground Palette Entry" , Vec(8.0, 0.0) }, - { "BgColor" , "Color: Background Palette Entry" , Vec(8.0, 0.0) }, - { "FgTile" , "Tile: Foreground Tile Entry" , Vec(8.0, 0.0) }, - { "BgTile" , "Tile: Background Tile Entry" , Vec(8.0, 0.0) }, - { "Frame" , "Change Frame" , Vec(16.0, 0.0) }, - { "BrushSize" , "Change Brush Size" , Vec(4.0, 0.0) }, - { "BrushAngle" , "Change Brush Angle" , Vec(-4.0, 0.0) }, - { "ToolSameGroup" , "Change Tool (same group)" , Vec(8.0, 0.0) }, - { "ToolOtherGroup" , "Change Tool" , Vec(0.0, -8.0) }, - { "Layer" , "Change Layer" , Vec(0.0, 8.0) }, - { "InkType" , "Change Ink Type" , Vec(0.0, -16.0) }, - { "InkOpacity" , "Change Ink Opacity" , Vec(0.0, 1.0) }, - { "LayerOpacity" , "Change Layer Opacity" , Vec(0.0, 1.0) }, - { "CelOpacity" , "Change Cel Opacity" , Vec(0.0, 1.0) }, - { "Alpha" , "Color: Alpha" , Vec(4.0, 0.0) }, - { "HslHue" , "Color: HSL Hue" , Vec(1.0, 0.0) }, - { "HslSaturation", "Color: HSL Saturation" , Vec(4.0, 0.0) }, - { "HslLightness" , "Color: HSL Lightness" , Vec(0.0, 4.0) }, - { "HsvHue" , "Color: HSV Hue" , Vec(1.0, 0.0) }, - { "HsvSaturation", "Color: HSV Saturation" , Vec(4.0, 0.0) }, - { "HsvValue" , "Color: HSV Value" , Vec(0.0, 4.0) }, }; + static std::vector g_wheel_actions; + + static const std::vector& wheel_actions() { + if (g_wheel_actions.empty()) { + g_wheel_actions = std::vector { + { "" , "" , Vec(0.0, 0.0) }, + { "Zoom" , I18N_KEY(zoom) , Vec(8.0, 0.0) }, + { "VScroll" , I18N_KEY(scroll_vertically) , Vec(4.0, 0.0) }, + { "HScroll" , I18N_KEY(scroll_horizontally) , Vec(4.0, 0.0) }, + { "FgColor" , I18N_KEY(fg_color) , Vec(8.0, 0.0) }, + { "BgColor" , I18N_KEY(bg_color) , Vec(8.0, 0.0) }, + { "FgTile" , I18N_KEY(fg_tile) , Vec(8.0, 0.0) }, + { "BgTile" , I18N_KEY(bg_tile) , Vec(8.0, 0.0) }, + { "Frame" , I18N_KEY(change_frame) , Vec(16.0, 0.0) }, + { "BrushSize" , I18N_KEY(change_brush_size) , Vec(4.0, 0.0) }, + { "BrushAngle" , I18N_KEY(change_brush_angle) , Vec(-4.0, 0.0) }, + { "ToolSameGroup" , I18N_KEY(change_tool_same_group) , Vec(8.0, 0.0) }, + { "ToolOtherGroup", I18N_KEY(change_tool) , Vec(0.0, -8.0) }, + { "Layer" , I18N_KEY(change_layer) , Vec(0.0, 8.0) }, + { "InkType" , I18N_KEY(change_ink_type) , Vec(0.0, -16.0) }, + { "InkOpacity" , I18N_KEY(change_ink_opacity) , Vec(0.0, 1.0) }, + { "LayerOpacity" , I18N_KEY(change_layer_opacity) , Vec(0.0, 1.0) }, + { "CelOpacity" , I18N_KEY(change_cel_opacity) , Vec(0.0, 1.0) }, + { "Alpha" , I18N_KEY(color_alpha) , Vec(4.0, 0.0) }, + { "HslHue" , I18N_KEY(color_hsl_hue) , Vec(1.0, 0.0) }, + { "HslSaturation" , I18N_KEY(color_hsl_saturation) , Vec(4.0, 0.0) }, + { "HslLightness" , I18N_KEY(color_hsl_lightness) , Vec(0.0, 4.0) }, + { "HsvHue" , I18N_KEY(color_hsv_hue) , Vec(1.0, 0.0) }, + { "HsvSaturation" , I18N_KEY(color_hsv_saturation) , Vec(4.0, 0.0) }, + { "HsvValue" , I18N_KEY(color_hsv_value) , Vec(0.0, 4.0) } + }; + } + return g_wheel_actions; + } + const char* get_shortcut(TiXmlElement* elem) { const char* shortcut = NULL; @@ -136,10 +155,9 @@ namespace { std::string get_user_friendly_string_for_keyaction(app::KeyAction action, app::KeyContext context) { - for (int c=0; actions[c].name; ++c) { - if (action == actions[c].action && - context == actions[c].context) - return actions[c].userfriendly; + for (const auto& a : actions()) { + if (action == a.action && context == a.context) + return a.userfriendly; } return std::string(); } @@ -148,7 +166,7 @@ namespace { int c = int(wheelAction); if (c >= int(app::WheelAction::First) && c <= int(app::WheelAction::Last)) { - return wheel_actions[c].userfriendly; + return wheel_actions()[c].userfriendly; } else return std::string(); @@ -185,26 +203,25 @@ namespace { namespace base { template<> app::KeyAction convert_to(const std::string& from) { - app::KeyAction action = app::KeyAction::None; - for (int c=0; actions[c].name; ++c) { - if (from == actions[c].name) - return actions[c].action; + for (const auto& a : actions()) { + if (from == a.name) + return a.action; } - return action; + return app::KeyAction::None; } template<> std::string convert_to(const app::KeyAction& from) { - for (int c=0; actions[c].name; ++c) { - if (from == actions[c].action) - return actions[c].name; + for (const auto& a : actions()) { + if (from == a.action) + return a.name; } - return ""; + return std::string(); } template<> app::WheelAction convert_to(const std::string& from) { for (int c=int(app::WheelAction::First); c<=int(app::WheelAction::Last); ++c) { - if (from == wheel_actions[c].name) + if (from == wheel_actions()[c].name) return (app::WheelAction)c; } return app::WheelAction::None; @@ -214,24 +231,24 @@ namespace base { int c = int(from); if (c >= int(app::WheelAction::First) && c <= int(app::WheelAction::Last)) { - return wheel_actions[c].name; + return wheel_actions()[c].name; } else return std::string(); } template<> app::KeyContext convert_to(const std::string& from) { - for (int c=0; contexts[c].name; ++c) { - if (from == contexts[c].name) - return contexts[c].context; + for (int c=0; g_contexts[c].name; ++c) { + if (from == g_contexts[c].name) + return g_contexts[c].context; } return app::KeyContext::Any; } template<> std::string convert_to(const app::KeyContext& from) { - for (int c=0; contexts[c].name; ++c) { - if (from == contexts[c].context) - return contexts[c].name; + for (int c=0; g_contexts[c].name; ++c) { + if (from == g_contexts[c].context) + return g_contexts[c].name; } return std::string(); } @@ -358,7 +375,7 @@ KeyPtr Key::MakeDragAction(WheelAction dragAction) KeyPtr k(new Key(dragAction)); k->m_type = KeyType::DragAction; k->m_keycontext = KeyContext::Any; - k->m_dragVector = wheel_actions[(int)dragAction].vector; + k->m_dragVector = wheel_actions()[(int)dragAction].vector; return k; } @@ -554,6 +571,12 @@ void KeyboardShortcuts::destroyInstance() KeyboardShortcuts::KeyboardShortcuts() { + ASSERT(Strings::instance()); + Strings::instance()->LanguageChange.connect([]{ + // Clear collections so they are re-constructed with the new language + g_actions.clear(); + g_wheel_actions.clear(); + }); } KeyboardShortcuts::~KeyboardShortcuts() @@ -1300,21 +1323,21 @@ std::string convertKeyContextToUserFriendlyString(KeyContext keyContext) case KeyContext::Any: return std::string(); case KeyContext::Normal: - return "Normal"; + return I18N_KEY(key_context_normal); case KeyContext::SelectionTool: - return "Selection"; + return I18N_KEY(key_context_selection); case KeyContext::TranslatingSelection: - return "Translating Selection"; + return I18N_KEY(key_context_translating_selection); case KeyContext::ScalingSelection: - return "Scaling Selection"; + return I18N_KEY(key_context_scaling_selection); case KeyContext::RotatingSelection: - return "Rotating Selection"; + return I18N_KEY(key_context_rotating_selection); case KeyContext::MoveTool: - return "Move Tool"; + return I18N_KEY(key_context_move_tool); case KeyContext::FreehandTool: - return "Freehand Tool"; + return I18N_KEY(key_context_freehand_tool); case KeyContext::ShapeTool: - return "Shape Tool"; + return I18N_KEY(key_context_shape_tool); } return std::string(); } diff --git a/src/app/ui/layer_frame_comboboxes.cpp b/src/app/ui/layer_frame_comboboxes.cpp index 122fd891e..495e8c08f 100644 --- a/src/app/ui/layer_frame_comboboxes.cpp +++ b/src/app/ui/layer_frame_comboboxes.cpp @@ -11,6 +11,7 @@ #include "app/ui/layer_frame_comboboxes.h" +#include "app/i18n/strings.h" #include "app/restore_visible_layers.h" #include "app/site.h" #include "doc/anidir.h" @@ -56,12 +57,15 @@ std::string LayerListItem::buildName(const doc::Layer* layer) name.insert(0, layer->name()); layer = layer->parent(); } - name.insert(0, isGroup ? "Group: ": "Layer: "); + const std::string namePrefix = + (isGroup ? Strings::layer_combo_group() : + Strings::layer_combo_layer()) + " "; + name.insert(0, namePrefix); return name; } FrameListItem::FrameListItem(doc::Tag* tag) - : ListItem("Tag: " + tag->name()) + : ListItem(Strings::frame_combo_tag() + " " + tag->name()) , m_tag(tag) { setValue(m_tag->name()); @@ -89,10 +93,10 @@ void fill_area_combobox(const doc::Sprite* sprite, ui::ComboBox* area, const std void fill_layers_combobox(const doc::Sprite* sprite, ui::ComboBox* layers, const std::string& defLayer, const int defLayerIndex) { - int i = layers->addItem("Visible layers"); + int i = layers->addItem(Strings::layer_combo_visible_layers()); dynamic_cast(layers->getItem(i))->setValue(kAllLayers); - i = layers->addItem("Selected layers"); + i = layers->addItem(Strings::layer_combo_selected_layers()); dynamic_cast(layers->getItem(i))->setValue(kSelectedLayers); if (defLayer == kSelectedLayers) layers->setSelectedItemIndex(i); @@ -113,10 +117,10 @@ void fill_layers_combobox(const doc::Sprite* sprite, ui::ComboBox* layers, const void fill_frames_combobox(const doc::Sprite* sprite, ui::ComboBox* frames, const std::string& defFrame) { - int i = frames->addItem("All frames"); + int i = frames->addItem(Strings::frame_combo_all_frames()); dynamic_cast(frames->getItem(i))->setValue(kAllFrames); - i = frames->addItem("Selected frames"); + i = frames->addItem(Strings::frame_combo_selected_frames()); dynamic_cast(frames->getItem(i))->setValue(kSelectedFrames); if (defFrame == kSelectedFrames) frames->setSelectedItemIndex(i); @@ -139,9 +143,9 @@ void fill_anidir_combobox(ui::ComboBox* anidir, doc::AniDir defAnidir) int(doc::AniDir::REVERSE) == 1 && int(doc::AniDir::PING_PONG) == 2, "doc::AniDir has changed"); - anidir->addItem("Forward"); - anidir->addItem("Reverse"); - anidir->addItem("Ping-pong"); + anidir->addItem(Strings::anidir_combo_forward()); + anidir->addItem(Strings::anidir_combo_reverse()); + anidir->addItem(Strings::anidir_combo_ping_pong()); anidir->setSelectedItemIndex(int(defAnidir)); } diff --git a/src/app/ui/main_window.cpp b/src/app/ui/main_window.cpp index 743bfaf33..6f0aa9b1c 100644 --- a/src/app/ui/main_window.cpp +++ b/src/app/ui/main_window.cpp @@ -13,6 +13,7 @@ #include "app/app.h" #include "app/app_menus.h" +#include "app/commands/command.h" #include "app/commands/commands.h" #include "app/crash/data_recovery.h" #include "app/i18n/strings.h" @@ -159,12 +160,7 @@ MainWindow::MainWindow() // When the language is change, we reload the menu bar strings and // relayout the whole main window. - Strings::instance()->LanguageChange.connect( - [this]{ - m_menuBar->reload(); - layout(); - invalidate(); - }); + Strings::instance()->LanguageChange.connect([this] { onLanguageChange(); }); } MainWindow::~MainWindow() @@ -203,6 +199,22 @@ MainWindow::~MainWindow() m_menuBar->setMenu(NULL); } +void MainWindow::onLanguageChange() +{ + auto commands = Commands::instance(); + std::vector commandIDs; + commands->getAllIds(commandIDs); + + for (const auto& commandID : commandIDs) { + Command* command = commands->byId(commandID.c_str()); + command->generateFriendlyName(); + } + + m_menuBar->reload(); + layout(); + invalidate(); +} + DocView* MainWindow::getDocView() { return dynamic_cast(m_workspace->activeView()); diff --git a/src/app/ui/main_window.h b/src/app/ui/main_window.h index 5db196870..ff3c2a1ee 100644 --- a/src/app/ui/main_window.h +++ b/src/app/ui/main_window.h @@ -116,6 +116,7 @@ namespace app { void onSaveLayout(ui::SaveLayoutEvent& ev) override; void onResize(ui::ResizeEvent& ev) override; void onActiveViewChange(); + void onLanguageChange(); private: DocView* getDocView(); diff --git a/src/app/ui/news_listbox.cpp b/src/app/ui/news_listbox.cpp index 0f6ccbb97..0d95941a2 100644 --- a/src/app/ui/news_listbox.cpp +++ b/src/app/ui/news_listbox.cpp @@ -12,6 +12,7 @@ #include "app/ui/news_listbox.h" #include "app/app.h" +#include "app/i18n/strings.h" #include "app/pref/preferences.h" #include "app/res/http_loader.h" #include "app/ui/skin/skin_theme.h" @@ -168,7 +169,8 @@ private: class ProblemsItem : public NewsItem { public: - ProblemsItem() : NewsItem("", "Problems loading news. Retry.", "") { + ProblemsItem() + : NewsItem("", Strings::news_listbox_problem_loading(), "") { } protected: @@ -306,7 +308,8 @@ void NewsListBox::parseFile(const std::string& filename) .FirstChild("channel") .FirstChild("link").ToElement(); if (linkXml && linkXml->GetText()) - addChild(new NewsItem(linkXml->GetText(), "More...", "")); + addChild( + new NewsItem(linkXml->GetText(), Strings::news_listbox_more(), "")); if (view) view->updateView(); diff --git a/src/app/ui/preview_editor.cpp b/src/app/ui/preview_editor.cpp index 62c321011..7c9c5bd64 100644 --- a/src/app/ui/preview_editor.cpp +++ b/src/app/ui/preview_editor.cpp @@ -16,6 +16,7 @@ #include "app/doc_event.h" #include "app/ini_file.h" #include "app/loop_tag.h" +#include "app/i18n/strings.h" #include "app/modules/editors.h" #include "app/modules/gui.h" #include "app/pref/preferences.h" @@ -176,7 +177,7 @@ private: }; PreviewEditorWindow::PreviewEditorWindow() - : Window(WithTitleBar, "Preview") + : Window(WithTitleBar, Strings::preview_title()) , m_docView(NULL) , m_centerButton(new MiniCenterButton()) , m_playButton(new MiniPlayButton()) diff --git a/src/app/ui/status_bar.cpp b/src/app/ui/status_bar.cpp index 67f62f0bc..f557bf2a9 100644 --- a/src/app/ui/status_bar.cpp +++ b/src/app/ui/status_bar.cpp @@ -16,6 +16,7 @@ #include "app/doc_access.h" #include "app/doc_event.h" #include "app/doc_range.h" +#include "app/i18n/strings.h" #include "app/modules/editors.h" #include "app/modules/gfx.h" #include "app/modules/gui.h" @@ -587,7 +588,7 @@ class StatusBar::SnapToGridWindow : public ui::PopupWindow { public: SnapToGridWindow() : ui::PopupWindow("", ClickBehavior::DoNothingOnClick) - , m_button("Disable Snap to Grid") { + , m_button(Strings::statusbar_tips_disable_snap_grid()) { InitTheme.connect( [this]{ setBorder(gfx::Border(2 * guiscale())); @@ -692,7 +693,7 @@ StatusBar::StatusBar(TooltipManager* tooltipManager) Box* box1 = new Box(HORIZONTAL); Box* box4 = new Box(HORIZONTAL); - m_frameLabel = new Label("Frame:"); + m_frameLabel = new Label(Strings::statusbar_tips_frame()); m_currentFrame = new GotoFrameEntry(); m_newFrame = new Button("+"); m_newFrame->Click.connect([this]{ newFrame(); }); @@ -713,9 +714,12 @@ StatusBar::StatusBar(TooltipManager* tooltipManager) } // Tooltips - tooltipManager->addTooltipFor(m_currentFrame, "Current Frame", BOTTOM); - tooltipManager->addTooltipFor(m_zoomEntry, "Zoom Level", BOTTOM); - tooltipManager->addTooltipFor(m_newFrame, "New Frame", BOTTOM); + tooltipManager->addTooltipFor( + m_currentFrame, Strings::statusbar_tips_current_frame(), BOTTOM); + tooltipManager->addTooltipFor( + m_zoomEntry, Strings::statusbar_tips_zoom_level(), BOTTOM); + tooltipManager->addTooltipFor( + m_newFrame, Strings::statusbar_tips_new_frame(), BOTTOM); App::instance()->activeToolManager()->add_observer(this); diff --git a/src/app/ui/timeline/ani_controls.cpp b/src/app/ui/timeline/ani_controls.cpp index 8d12da65b..ac9cb38dc 100644 --- a/src/app/ui/timeline/ani_controls.cpp +++ b/src/app/ui/timeline/ani_controls.cpp @@ -13,6 +13,7 @@ #include "app/commands/command.h" #include "app/commands/commands.h" +#include "app/i18n/strings.h" #include "app/modules/editors.h" #include "app/ui/editor/editor.h" #include "app/ui/keyboard_shortcuts.h" @@ -124,12 +125,12 @@ std::string AniControls::getTooltipFor(int index) const Params(), KeyContext::Normal); if (key && !key->accels().empty()) { - tooltip += "\n\nShortcut: "; + tooltip += "\n\n" + Strings::ani_controls_shortcut() + " "; tooltip += key->accels().front().toString(); } if (index == ACTION_PLAY) { - tooltip += "\n\nRight-click: Show playback options"; + tooltip += "\n\n" + Strings::ani_controls_right_click(); } }