egui: give more systematic names to translatable strings

The names are now based on where the strings are used in the GUI. This
will hopefully make it easier for translators to locate where they are
in the user interface.

I've prefixed all translatable string names with "tr-" to prevent
accidentally substitute unrelated strings in a mass replace.

Once I push this commit, I will also protect `locales/**`, so that
all future changes to strings pass a PR review process to reduce the
probability of errors. This will also make it easier to have a freeze
for translatable strings if we end up having a release schedule in the
future.
This commit is contained in:
Mikolaj Wielgus 2024-10-03 20:13:53 +02:00
parent 24f0a1c699
commit f21808776e
7 changed files with 166 additions and 166 deletions

View File

@ -1,31 +1,31 @@
action-undo = Zurück tr-menu-edit_undo = Zurück
action-redo = Vorwärts tr-menu-edit_redo = Vorwärts
show-layer-manager = Zeige Layer-Verwaltung tr-menu-view_show-layer-manager = Zeige Layer-Verwaltung
specctra-session-file = Specctra-Sitzungsdatei tr-menu-open_specctra-session-file = Specctra-Sitzungsdatei
frame-timestep = Frame-Zeitschritt tr-menu-view_frame-timestep = Frame-Zeitschritt
menu-file = Datei tr-menu-file = Datei
menu-edit = Bearbeiten tr-menu-edit = Bearbeiten
menu-view = Ansicht tr-menu-view = Ansicht
menu-place = Ort tr-menu-place = Ort
menu-route = Route tr-menu-route = Route
menu-inspect = Inspizieren tr-menu-inspect = Inspizieren
menu-options = Optionen tr-menu-options = Optionen
menu-debug = Debugging tr-menu-debug = Debugging
action-open-dsn = Öffnen tr-menu-file-open = Öffnen
action-export-ses = Sitzungsdatei exportieren tr-menu-file-export-session-file = Sitzungsdatei exportieren
action-import-cmd = Historie importieren tr-menu-file-import-history = Historie importieren
action-export-cmd = Historie exportieren tr-menu-file-export-history = Historie exportieren
action-quit = Beenden tr-menu-file-quit = Beenden
action-autoroute = Autorouten tr-menu-route-autoroute = Autorouten
action-place-via = Platziere DuKo tr-menu-place-place-via = Platziere DuKo
action-remove-bands = Entferne Bänder tr-menu-edit_remove-bands = Entferne Bänder
action-compare-detours = Vergleiche Umwege tr-menu-inspect_compare-detours = Vergleiche Umwege
presort-by-pairwise-detours = Nach paarweisen Umwegen vorsortieren tr-menu-route-options_presort-by-pairwise-detours = Nach paarweisen Umwegen vorsortieren
squeeze-through-under-bands = Presse unter Bänder tr-menu-route-options_squeeze-through-under-bands = Presse unter Bänder
wrap-around-bands = Wickle um Bänder tr-menu-route-options_wrap-around-bands = Wickle um Bänder
zoom-to-fit = Zoom automatisch einpassen tr-menu-view_zoom-to-fit = Zoom automatisch einpassen
show-ratsnest = Zeige Ratsnest tr-menu-view_show-ratsnest = Zeige Ratsnest
show-navmesh = Zeige Navmesh tr-menu-view_show-navmesh = Zeige Navmesh
show-bboxes = Zeige BBoxes tr-menu-view_show-bboxes = Zeige BBoxes
show-origin-destination = Zeige Ursprung-Ziel tr-menu-view_show-origin-destination = Zeige Ursprung-Ziel
action-measure-length = Länge messen tr-menu-inspect_measure-length = Länge messen

View File

@ -1,56 +1,56 @@
menu-file = File tr-menu-file = File
menu-edit = Edit tr-menu-edit = Edit
menu-view = View tr-menu-view = View
menu-place = Place tr-menu-place = Place
menu-route = Route tr-menu-route = Route
menu-inspect = Inspect tr-menu-inspect = Inspect
menu-options = Options tr-menu-options = Options
menu-debug = Debug tr-menu-debug = Debug
action-open-dsn = Open tr-menu-file-open = Open
action-export-ses = Export Session File tr-menu-file-export-session-file = Export Session File
action-import-cmd = Import History tr-menu-file-import-history = Import History
action-export-cmd = Export History tr-menu-file-export-history = Export History
action-quit = Quit tr-menu-file-quit = Quit
action-autoroute = Autoroute tr-menu-route-autoroute = Autoroute
action-place-via = Place Via tr-menu-place-place-via = Place Via
action-remove-bands = Remove Bands tr-menu-edit_remove-bands = Remove Bands
action-compare-detours = Compare Detours tr-menu-inspect_compare-detours = Compare Detours
action-measure-length = Measure Length tr-menu-inspect_measure-length = Measure Length
action-undo = Undo tr-menu-edit_undo = Undo
action-redo = Redo tr-menu-edit_redo = Redo
action-abort = Abort tr-menu-edit_abort = Abort
presort-by-pairwise-detours = Presort by Pairwise Detours tr-menu-route-options_presort-by-pairwise-detours = Presort by Pairwise Detours
squeeze-through-under-bands = Squeeze through under Bands tr-menu-route-options_squeeze-through-under-bands = Squeeze through under Bands
wrap-around-bands = Wrap around Bands tr-menu-route-options_wrap-around-bands = Wrap around Bands
zoom-to-fit = Zoom to Fit tr-menu-view_zoom-to-fit = Zoom to Fit
show-ratsnest = Show Ratsnest tr-menu-view_show-ratsnest = Show Ratsnest
show-navmesh = Show Navmesh tr-menu-view_show-navmesh = Show Navmesh
show-bboxes = Show BBoxes tr-menu-view_show-bboxes = Show BBoxes
show-origin-destination = Show OriginDestination tr-menu-view_show-origin-destination = Show OriginDestination
show-layer-manager = Show Layer Manager tr-menu-view_show-layer-manager = Show Layer Manager
frame-timestep = Frame Timestep tr-menu-view_frame-timestep = Frame Timestep
specctra-session-file = Specctra session file tr-menu-open_specctra-session-file = Specctra session file
title-error-messages = Error Messages tr-dialog-tr-error-messages = Error Messages
reset-error-messages = Reset Messages tr-dialog-tr-error-messages_reset = Reset Messages
discard-item = Discard tr-dialog-tr-error-messages_discard = Discard
specctra-dsn-loader = Specctra DSN file loader tr-module-specctra-dsn-file-loader = Specctra DSN file loader
history-loader = History file loader tr-module-history-file-loader = History file loader
invoker = Invoker tr-module-invoker = Invoker
error-file-load = unable to read file tr-error_unable-to-read-file = unable to read file
error-file-specctra-dsn-parse = file failed to parse as Specctra DSN tr-error_failed-to-parse-as-specctra-dsn = file failed to parse as Specctra DSN
error-file-history-parse = file failed to parse as History JSON tr-error_failed-to-parse-as-history-json = file failed to parse as History JSON
error-overlay-init = unable to initialize overlay tr-error_unable-to-initialize-overlay = unable to initialize overlay
error-autorouter-init = unable to initialize autorouter tr-error_unable-to-initialize-autorouter = unable to initialize autorouter

View File

@ -1,24 +1,24 @@
menu-file = Bestand tr-menu-file = Bestand
menu-debug = Debug tr-menu-debug = Debug
action-export-ses = Sessiebestand exporteren tr-menu-file-export-session-file = Sessiebestand exporteren
action-export-cmd = Geschiedenis exporteren tr-menu-file-export-history = Geschiedenis exporteren
action-quit = Stop tr-menu-file-quit = Stop
action-place-via = Plaats Via tr-menu-place-place-via = Plaats Via
action-remove-bands = Banden verwijderen tr-menu-edit_remove-bands = Banden verwijderen
action-compare-detours = Vergelijk Omwegen tr-menu-inspect_compare-detours = Vergelijk Omwegen
action-undo = Ongedaan maken tr-menu-edit_undo = Ongedaan maken
action-redo = Opnieuw doen tr-menu-edit_redo = Opnieuw doen
show-navmesh = Toon Navmesh tr-menu-view_show-navmesh = Toon Navmesh
show-bboxes = Toon BBoxen tr-menu-view_show-bboxes = Toon BBoxen
action-open-dsn = Open tr-menu-file-open = Open
action-autoroute = Automatische route tr-menu-route-autoroute = Automatische route
action-import-cmd = Geschiedenis importeren tr-menu-file-import-history = Geschiedenis importeren
show-ratsnest = Toon Rattennest tr-menu-view_show-ratsnest = Toon Rattennest
show-origin-destination = Toon Herkomst-Bestemming tr-menu-view_show-origin-destination = Toon Herkomst-Bestemming
specctra-session-file = Specctra-sessiebestand tr-menu-open_specctra-session-file = Specctra-sessiebestand
action-measure-length = Lengte meten tr-menu-inspect_measure-length = Lengte meten
menu-options = Opties tr-menu-options = Opties
menu-view = Bekijken tr-menu-view = Bekijken
menu-route = Route tr-menu-route = Route
menu-edit = Bewerken tr-menu-edit = Bewerken
menu-inspect = Inspecteren tr-menu-inspect = Inspecteren

View File

@ -1,22 +1,22 @@
action-place-via = Wstaw przelotkę tr-menu-place-place-via = Wstaw przelotkę
menu-debug = Debuguj tr-menu-debug = Debuguj
action-open-dsn = Otwórz tr-menu-file-open = Otwórz
action-export-cmd = Eksportuj historię tr-menu-file-export-history = Eksportuj historię
action-autoroute = Autotrasuj tr-menu-route-autoroute = Autotrasuj
action-remove-bands = Usuń taśmy tr-menu-edit_remove-bands = Usuń taśmy
action-measure-length = Zmierz długość tr-menu-inspect_measure-length = Zmierz długość
action-undo = Cofnij tr-menu-edit_undo = Cofnij
show-ratsnest = Pokaż szczurze gniazdo tr-menu-view_show-ratsnest = Pokaż szczurze gniazdo
specctra-session-file = Plik sesji Specctra tr-menu-open_specctra-session-file = Plik sesji Specctra
menu-file = Plik tr-menu-file = Plik
action-redo = Ponów tr-menu-edit_redo = Ponów
action-export-ses = Eksportuj plik sesji tr-menu-file-export-session-file = Eksportuj plik sesji
action-import-cmd = Importuj historię tr-menu-file-import-history = Importuj historię
action-quit = Wyjdź tr-menu-file-quit = Wyjdź
action-compare-detours = Porównaj objazdy tr-menu-inspect_compare-detours = Porównaj objazdy
show-navmesh = Pokaż siatkę nawigacyjną tr-menu-view_show-navmesh = Pokaż siatkę nawigacyjną
show-bboxes = Pokaż obwiednie tr-menu-view_show-bboxes = Pokaż obwiednie
show-origin-destination = Pokaż pochodzenie i destynację tr-menu-view_show-origin-destination = Pokaż pochodzenie i destynację
menu-options = Opcje tr-menu-options = Opcje
wrap-around-bands = Owiń wokół taśm tr-menu-route-options_wrap-around-bands = Owiń wokół taśm
squeeze-through-under-bands = Ściśnij pod taśmami tr-menu-route-options_squeeze-through-under-bands = Ściśnij pod taśmami

View File

@ -107,7 +107,7 @@ impl App {
match self.load_specctra_dsn(input) { match self.load_specctra_dsn(input) {
Ok(()) => {} Ok(()) => {}
Err(err) => { Err(err) => {
self.error_dialog.push_error("specctra-dsn-loader", err); self.error_dialog.push_error("tr-module-specctra-dsn-file-loader", err);
} }
} }
} }
@ -122,15 +122,15 @@ impl App {
Ok(res) => invoker.replay(res), Ok(res) => invoker.replay(res),
Err(err) => { Err(err) => {
self.error_dialog.push_error( self.error_dialog.push_error(
"history-loader", "tr-module-history-file-loader",
format!("{}; {}", tr.text("error-file-history-parse"), err), format!("{}; {}", tr.text("tr-error_failed-to-parse-as-history-json"), err),
); );
} }
}, },
Err(err) => { Err(err) => {
self.error_dialog.push_error( self.error_dialog.push_error(
"history-loader", "tr-module-history-file-loader",
format!("{}; {}", tr.text("error-file-load"), err), format!("{}; {}", tr.text("tr-error_unable-to-read-file"), err),
); );
} }
} }
@ -141,7 +141,7 @@ impl App {
Ok(ActivityStatus::Running) => true, Ok(ActivityStatus::Running) => true,
Ok(ActivityStatus::Finished(..)) => false, Ok(ActivityStatus::Finished(..)) => false,
Err(err) => { Err(err) => {
self.error_dialog.push_error("invoker", format!("{}", err)); self.error_dialog.push_error("tr-module-invoker", format!("{}", err));
false false
} }
}; };
@ -156,15 +156,15 @@ impl App {
input: std::io::Result<I>, input: std::io::Result<I>,
) -> Result<(), String> { ) -> Result<(), String> {
let tr = &self.translator; let tr = &self.translator;
let bufread = input.map_err(|err| format!("{}; {}", tr.text("error-file-load"), err))?; let bufread = input.map_err(|err| format!("{}; {}", tr.text("tr-error_unable-to-read-file"), err))?;
let design = SpecctraDesign::load(bufread) let design = SpecctraDesign::load(bufread)
.map_err(|err| format!("{}; {}", tr.text("error-file-specctra-dsn-parse"), err))?; .map_err(|err| format!("{}; {}", tr.text("tr-error_failed-to-parse-as-specctra-dsn"), err))?;
let board = design.make_board(); let board = design.make_board();
let overlay = Overlay::new(&board) let overlay = Overlay::new(&board)
.map_err(|err| format!("{}; {}", tr.text("error-overlay-init"), err))?; .map_err(|err| format!("{}; {}", tr.text("tr-error_unable-to-initialize-overlay"), err))?;
let layers = Layers::new(&board); let layers = Layers::new(&board);
let autorouter = Autorouter::new(board) let autorouter = Autorouter::new(board)
.map_err(|err| format!("{}; {}", tr.text("error-autorouter-init"), err))?; .map_err(|err| format!("{}; {}", tr.text("tr-error_unable-to-initialize-autorouter"), err))?;
self.maybe_overlay = Some(overlay); self.maybe_overlay = Some(overlay);
self.maybe_layers = Some(layers); self.maybe_layers = Some(layers);
self.maybe_design = Some(design); self.maybe_design = Some(design);

View File

@ -33,17 +33,17 @@ impl ErrorDialog {
pub fn update(&mut self, ctx: &egui::Context, tr: &Translator) { pub fn update(&mut self, ctx: &egui::Context, tr: &Translator) {
let mut messages_cleared = false; let mut messages_cleared = false;
egui::Window::new(tr.text("title-error-messages")) egui::Window::new(tr.text("tr-dialog-tr-error-messages"))
.id("error-messages-dialog".into()) .id("tr-error-messages-dialog".into())
.open(&mut self.window_open) .open(&mut self.window_open)
.scroll(true) .scroll(true)
.show(ctx, |ui| { .show(ctx, |ui| {
if ui.button(tr.text("reset-error-messages")).clicked() { if ui.button(tr.text("tr-dialog-tr-error-messages_reset")).clicked() {
self.messages.clear(); self.messages.clear();
messages_cleared = true; messages_cleared = true;
} }
egui::Grid::new("error-messages-grid").show(ui, |ui| { egui::Grid::new("tr-error-messages-grid").show(ui, |ui| {
let mut messages_to_discard = BTreeSet::<usize>::new(); let mut messages_to_discard = BTreeSet::<usize>::new();
let style = Arc::clone(ui.style()); let style = Arc::clone(ui.style());
for (msg_id, msg) in self.messages.iter().enumerate() { for (msg_id, msg) in self.messages.iter().enumerate() {
@ -72,7 +72,7 @@ impl ErrorDialog {
// TODO: perhaps alternatively, use small icon instead? // TODO: perhaps alternatively, use small icon instead?
// (provide alt text in that case!) // (provide alt text in that case!)
if ui.add(egui::Button::new(tr.text("discard-item"))).clicked() { if ui.add(egui::Button::new(tr.text("tr-dialog-tr-error-messages_discard"))).clicked() {
messages_to_discard.insert(msg_id); messages_to_discard.insert(msg_id);
} }
ui.label(WidgetText::LayoutJob(loj)); ui.label(WidgetText::LayoutJob(loj));

View File

@ -68,67 +68,67 @@ impl MenuBar {
maybe_design: &Option<SpecctraDesign>, maybe_design: &Option<SpecctraDesign>,
) -> Result<(), InvokerError> { ) -> Result<(), InvokerError> {
let mut open_design = Trigger::new(Action::new( let mut open_design = Trigger::new(Action::new(
tr.text("action-open-dsn"), tr.text("tr-menu-file-open"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
egui::Key::O, egui::Key::O,
)); ));
let mut export_session = Trigger::new(Action::new( let mut export_session = Trigger::new(Action::new(
tr.text("action-export-ses"), tr.text("tr-menu-file-export-session-file"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
egui::Key::S, egui::Key::S,
)); ));
let mut import_history = Trigger::new(Action::new( let mut import_history = Trigger::new(Action::new(
tr.text("action-import-cmd"), tr.text("tr-menu-file-import-history"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
egui::Key::I, egui::Key::I,
)); ));
let mut export_history = Trigger::new(Action::new( let mut export_history = Trigger::new(Action::new(
tr.text("action-export-cmd"), tr.text("tr-menu-file-export-history"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
egui::Key::E, egui::Key::E,
)); ));
let mut quit = Trigger::new(Action::new( let mut quit = Trigger::new(Action::new(
tr.text("action-quit"), tr.text("tr-menu-file-quit"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
egui::Key::Q, egui::Key::Q,
)); ));
let mut undo = Trigger::new(Action::new( let mut undo = Trigger::new(Action::new(
tr.text("action-undo"), tr.text("tr-menu-edit_undo"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
egui::Key::Z, egui::Key::Z,
)); ));
let mut redo = Trigger::new(Action::new( let mut redo = Trigger::new(Action::new(
tr.text("action-redo"), tr.text("tr-menu-edit_redo"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
egui::Key::Y, egui::Key::Y,
)); ));
let mut abort = Trigger::new(Action::new( let mut abort = Trigger::new(Action::new(
tr.text("action-abort"), tr.text("tr-menu-edit_abort"),
egui::Modifiers::NONE, egui::Modifiers::NONE,
egui::Key::Escape, egui::Key::Escape,
)); ));
let mut remove_bands = Trigger::new(Action::new( let mut remove_bands = Trigger::new(Action::new(
tr.text("action-remove-bands"), tr.text("tr-menu-edit_remove-bands"),
egui::Modifiers::NONE, egui::Modifiers::NONE,
egui::Key::Delete, egui::Key::Delete,
)); ));
let mut place_via = Switch::new(Action::new( let mut place_via = Switch::new(Action::new(
tr.text("action-place-via"), tr.text("tr-menu-place-place-via"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
egui::Key::P, egui::Key::P,
)); ));
let mut autoroute = Trigger::new(Action::new( let mut autoroute = Trigger::new(Action::new(
tr.text("action-autoroute"), tr.text("tr-menu-route-autoroute"),
egui::Modifiers::CTRL, egui::Modifiers::CTRL,
egui::Key::A, egui::Key::A,
)); ));
let mut compare_detours = Trigger::new(Action::new( let mut compare_detours = Trigger::new(Action::new(
tr.text("action-compare-detours"), tr.text("tr-menu-inspect_compare-detours"),
egui::Modifiers::NONE, egui::Modifiers::NONE,
egui::Key::Minus, egui::Key::Minus,
)); ));
let mut measure_length = Trigger::new(Action::new( let mut measure_length = Trigger::new(Action::new(
tr.text("action-measure-length"), tr.text("tr-menu-inspect_measure-length"),
egui::Modifiers::NONE, egui::Modifiers::NONE,
egui::Key::Plus, egui::Key::Plus,
)); ));
@ -136,7 +136,7 @@ impl MenuBar {
egui::TopBottomPanel::top("menu_bar") egui::TopBottomPanel::top("menu_bar")
.show(ctx, |ui| { .show(ctx, |ui| {
egui::menu::bar(ui, |ui| { egui::menu::bar(ui, |ui| {
ui.menu_button(tr.text("menu-file"), |ui| { ui.menu_button(tr.text("tr-menu-file"), |ui| {
open_design.button(ctx, ui); open_design.button(ctx, ui);
export_session.button(ctx, ui); export_session.button(ctx, ui);
@ -153,7 +153,7 @@ impl MenuBar {
} }
}); });
ui.menu_button(tr.text("menu-edit"), |ui| { ui.menu_button(tr.text("tr-menu-edit"), |ui| {
undo.button(ctx, ui); undo.button(ctx, ui);
redo.button(ctx, ui); redo.button(ctx, ui);
@ -166,63 +166,63 @@ impl MenuBar {
remove_bands.button(ctx, ui); remove_bands.button(ctx, ui);
}); });
ui.menu_button(tr.text("menu-view"), |ui| { ui.menu_button(tr.text("tr-menu-view"), |ui| {
ui.toggle_value( ui.toggle_value(
&mut viewport.scheduled_zoom_to_fit, &mut viewport.scheduled_zoom_to_fit,
tr.text("zoom-to-fit"), tr.text("tr-menu-view_zoom-to-fit"),
); );
ui.separator(); ui.separator();
ui.checkbox(&mut self.show_ratsnest, tr.text("show-ratsnest")); ui.checkbox(&mut self.show_ratsnest, tr.text("tr-menu-view_show-ratsnest"));
ui.checkbox(&mut self.show_navmesh, tr.text("show-navmesh")); ui.checkbox(&mut self.show_navmesh, tr.text("tr-menu-view_show-navmesh"));
ui.checkbox(&mut self.show_bboxes, tr.text("show-bboxes")); ui.checkbox(&mut self.show_bboxes, tr.text("tr-menu-view_show-bboxes"));
ui.checkbox( ui.checkbox(
&mut self.show_origin_destination, &mut self.show_origin_destination,
tr.text("show-origin-destination"), tr.text("tr-menu-view_show-origin-destination"),
); );
ui.separator(); ui.separator();
ui.checkbox(&mut self.show_layer_manager, tr.text("show-layer-manager")); ui.checkbox(&mut self.show_layer_manager, tr.text("tr-menu-view_show-layer-manager"));
ui.separator(); ui.separator();
ui.label(tr.text("frame-timestep")); ui.label(tr.text("tr-menu-view_frame-timestep"));
ui.add( ui.add(
egui::widgets::Slider::new(&mut self.frame_timestep, 0.0..=3.0) egui::widgets::Slider::new(&mut self.frame_timestep, 0.0..=3.0)
.suffix(" s"), .suffix(" s"),
); );
}); });
ui.menu_button(tr.text("menu-place"), |ui| { ui.menu_button(tr.text("tr-menu-place"), |ui| {
place_via.toggle_widget(ctx, ui, &mut self.is_placing_via); place_via.toggle_widget(ctx, ui, &mut self.is_placing_via);
}); });
ui.menu_button(tr.text("menu-route"), |ui| { ui.menu_button(tr.text("tr-menu-route"), |ui| {
autoroute.button(ctx, ui); autoroute.button(ctx, ui);
ui.separator(); ui.separator();
ui.menu_button(tr.text("menu-options"), |ui| { ui.menu_button(tr.text("tr-menu-options"), |ui| {
ui.checkbox( ui.checkbox(
&mut self.autorouter_options.presort_by_pairwise_detours, &mut self.autorouter_options.presort_by_pairwise_detours,
tr.text("presort-by-pairwise-detours"), tr.text("tr-menu-route-options_presort-by-pairwise-detours"),
); );
ui.checkbox( ui.checkbox(
&mut self &mut self
.autorouter_options .autorouter_options
.router_options .router_options
.squeeze_through_under_bands, .squeeze_through_under_bands,
tr.text("squeeze-through-under-bands"), tr.text("tr-menu-route-options_squeeze-through-under-bands"),
); );
ui.checkbox( ui.checkbox(
&mut self.autorouter_options.router_options.wrap_around_bands, &mut self.autorouter_options.router_options.wrap_around_bands,
tr.text("wrap-around-bands"), tr.text("tr-menu-route-options_wrap-around-bands"),
); );
}); });
}); });
ui.menu_button(tr.text("menu-inspect"), |ui| { ui.menu_button(tr.text("tr-menu-inspect"), |ui| {
compare_detours.button(ctx, ui); compare_detours.button(ctx, ui);
measure_length.button(ctx, ui); measure_length.button(ctx, ui);
}); });
@ -262,7 +262,7 @@ impl MenuBar {
} }
} }
let task = dialog let task = dialog
.add_filter(tr.text("specctra-session-file"), &["ses"]) .add_filter(tr.text("tr-menu-open_specctra-session-file"), &["ses"])
.save_file(); .save_file();
execute(async move { execute(async move {