aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRubén Beltrán del Río <jj@r.bdr.sh>2026-01-17 11:22:22 +0100
committerRubén Beltrán del Río <jj@r.bdr.sh>2026-01-17 12:24:45 +0100
commit88d6bf80f5cdbbb90ead197bd41a67eb8c44e50e (patch)
tree401549b24fe8a747ef6739389b1b38f33ef016bb /src
parent17898fbabde35ab346c133114e78614e707c0eca (diff)
Make clippy stricter and fix
Diffstat (limited to 'src')
-rw-r--r--src/actions.rs4
-rw-r--r--src/dialogs.rs12
-rw-r--r--src/file_registry.rs2
-rw-r--r--src/handlers/export.rs28
-rw-r--r--src/handlers/view.rs6
-rw-r--r--src/i18n.rs4
-rw-r--r--src/main.rs239
-rw-r--r--src/preferences/models.rs21
-rw-r--r--src/preferences/pages/editor.rs24
-rw-r--r--src/preferences/pages/general.rs2
-rw-r--r--src/preferences/pages/map.rs65
-rw-r--r--src/preferences/pages/stages.rs72
-rw-r--r--src/preferences/pages/templates.rs16
-rw-r--r--src/preferences/window.rs187
-rw-r--r--src/stages.rs46
15 files changed, 449 insertions, 279 deletions
diff --git a/src/actions.rs b/src/actions.rs
index 859d559..fdea125 100644
--- a/src/actions.rs
+++ b/src/actions.rs
@@ -25,14 +25,14 @@ pub enum ImageFormat {
}
impl ImageFormat {
- pub fn extension(&self) -> &'static str {
+ pub fn extension(self) -> &'static str {
match self {
ImageFormat::Png => "png",
ImageFormat::Svg => "svg",
}
}
- pub fn mime_type(&self) -> &'static str {
+ pub fn mime_type(self) -> &'static str {
match self {
ImageFormat::Png => "image/png",
ImageFormat::Svg => "image/svg+xml",
diff --git a/src/dialogs.rs b/src/dialogs.rs
index 8f5b951..41b8c86 100644
--- a/src/dialogs.rs
+++ b/src/dialogs.rs
@@ -94,7 +94,7 @@ pub fn show_open_dialog(
/// Shows a file save dialog and handles the response.
pub fn show_save_dialog(
window: &gtk::Window,
- current_file: Option<PathBuf>,
+ current_file: Option<&PathBuf>,
close_after: bool,
sender: ComponentSender<AppModel>,
) {
@@ -110,7 +110,7 @@ pub fn show_save_dialog(
dialog.add_filter(&create_file_filter());
let default_filename = "map.wmap";
- if let Some(ref current_path) = current_file {
+ if let Some(current_path) = current_file {
if let Some(parent) = current_path.parent() {
let folder = gtk::gio::File::for_path(parent);
dialog.set_current_folder(Some(&folder)).ok();
@@ -191,7 +191,7 @@ fn create_image_filter(format: ImageFormat) -> gtk::FileFilter {
/// Shows an export image dialog and handles the response.
pub fn show_export_dialog(
window: &gtk::Window,
- current_file: Option<PathBuf>,
+ current_file: Option<&PathBuf>,
sender: ComponentSender<AppModel>,
) {
let dialog = gtk::FileChooserDialog::new(
@@ -217,13 +217,13 @@ pub fn show_export_dialog(
.unwrap_or("map")
.to_string();
- if let Some(ref current_path) = current_file
+ if let Some(current_path) = current_file
&& let Some(parent) = current_path.parent()
{
let folder = gtk::gio::File::for_path(parent);
dialog.set_current_folder(Some(&folder)).ok();
}
- dialog.set_current_name(&format!("{}.png", base_name));
+ dialog.set_current_name(&format!("{base_name}.png"));
// Update extension when filter changes
{
@@ -235,7 +235,7 @@ pub fn show_export_dialog(
} else {
"svg"
};
- dialog.set_current_name(&format!("{}.{}", base_name_clone, ext));
+ dialog.set_current_name(&format!("{base_name_clone}.{ext}"));
});
}
diff --git a/src/file_registry.rs b/src/file_registry.rs
index 73299f6..749697d 100644
--- a/src/file_registry.rs
+++ b/src/file_registry.rs
@@ -78,7 +78,7 @@ pub fn register_sender(sender: relm4::Sender<Action>) {
}
/// Broadcasts a message to all windows via their registered senders.
-pub fn broadcast_to_all_windows(message: Action) {
+pub fn broadcast_to_all_windows(message: &Action) {
WINDOW_SENDERS.with_borrow(|senders| {
for sender in senders {
sender.emit(message.clone());
diff --git a/src/handlers/export.rs b/src/handlers/export.rs
index a0a4451..bf9dfc5 100644
--- a/src/handlers/export.rs
+++ b/src/handlers/export.rs
@@ -18,23 +18,27 @@ use std::path::PathBuf;
use crate::AppModel;
use crate::actions::ImageFormat;
use crate::dialogs;
-use crate::tr;
use crate::stages::LocalizedStageType;
+use crate::tr;
use wmap_renderer::{render_to_png, render_to_svg};
/// Exports the map to an image file in the specified format.
-pub fn export_to_file(model: &AppModel, path: PathBuf, format: ImageFormat) {
+pub fn export_to_file(model: &AppModel, path: &PathBuf, format: ImageFormat) {
let result: Result<(), String> = match format {
- ImageFormat::Png => {
- render_to_png(&model.map, &model.stage_type.to_localized(), &model.render_configuration)
- .map_err(|e| e.to_string())
- .and_then(|data| std::fs::write(&path, data).map_err(|e| e.to_string()))
- }
- ImageFormat::Svg => {
- render_to_svg(&model.map, &model.stage_type.to_localized(), &model.render_configuration)
- .map_err(|e| e.to_string())
- .and_then(|data| std::fs::write(&path, data).map_err(|e| e.to_string()))
- }
+ ImageFormat::Png => render_to_png(
+ &model.map,
+ &model.stage_type.to_localized(),
+ &model.render_configuration,
+ )
+ .map_err(|e| e.to_string())
+ .and_then(|data| std::fs::write(path, data).map_err(|e| e.to_string())),
+ ImageFormat::Svg => render_to_svg(
+ &model.map,
+ &model.stage_type.to_localized(),
+ &model.render_configuration,
+ )
+ .map_err(|e| e.to_string())
+ .and_then(|data| std::fs::write(path, data).map_err(|e| e.to_string())),
};
if let Err(error) = result {
diff --git a/src/handlers/view.rs b/src/handlers/view.rs
index 58d44b2..660f7b9 100644
--- a/src/handlers/view.rs
+++ b/src/handlers/view.rs
@@ -27,8 +27,10 @@ pub fn change_orientation(model: &mut AppModel) {
/// Updates the selected stage type from dropdown selection.
pub fn stage_type_selected(model: &mut AppModel, index: usize) {
- if index < model.available_stage_types.len() {
- model.stage_type = model.available_stage_types[index].clone();
+ if index < model.available_stage_types.len()
+ && let Some(stage_type) = model.available_stage_types.get(index)
+ {
+ model.stage_type = stage_type.clone();
model.update_image();
}
}
diff --git a/src/i18n.rs b/src/i18n.rs
index 1c574e0..35955a1 100644
--- a/src/i18n.rs
+++ b/src/i18n.rs
@@ -16,7 +16,7 @@
//! Internationalization support using gettext.
-use gettextrs::{bindtextdomain, setlocale, textdomain, LocaleCategory};
+use gettextrs::{LocaleCategory, bindtextdomain, setlocale, textdomain};
/// The gettext domain for the application.
pub const GETTEXT_DOMAIN: &str = "systems.tranquil.Map";
@@ -43,7 +43,7 @@ pub fn init() {
}
}
- textdomain(GETTEXT_DOMAIN).expect("Failed to set gettext domain");
+ textdomain(GETTEXT_DOMAIN).ok();
}
/// Macro for translating strings at runtime.
diff --git a/src/main.rs b/src/main.rs
index c15ffc2..4feef3b 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -28,6 +28,7 @@ mod stages;
mod ui_helpers;
mod icon_names {
+ #![allow(clippy::doc_markdown)] // Generated code from relm4_icons_build
include!(concat!(env!("OUT_DIR"), "/icon_names.rs"));
}
@@ -93,7 +94,7 @@ macro_rules! register_action {
}};
}
-fn setup_actions(window: gtk::Window, sender: ComponentSender<AppModel>) {
+fn setup_actions(window: &gtk::Window, sender: &ComponentSender<AppModel>) {
let application = relm4::main_application();
let mut action_group = RelmActionGroup::<WindowActionGroup>::new();
@@ -179,11 +180,12 @@ fn setup_actions(window: gtk::Window, sender: ComponentSender<AppModel>) {
);
let sender = sender.clone();
- let action: RelmAction<NewFromTemplateAction> = RelmAction::new_with_target_value(move |_, template_id| {
- sender.input(Action::NewFromTemplateById(template_id))
- });
+ let action: RelmAction<NewFromTemplateAction> =
+ RelmAction::new_with_target_value(move |_, template_id| {
+ sender.input(Action::NewFromTemplateById(template_id));
+ });
action_group.add_action(action);
- action_group.register_for_widget(&window);
+ action_group.register_for_widget(window);
}
struct AppInit {
@@ -219,12 +221,15 @@ struct AppModel {
}
impl AppModel {
+ #[allow(clippy::cast_possible_truncation)]
fn update_image(&mut self) {
- if let Ok(surface) =
- render_to_surface(&self.map, &self.stage_type.to_localized(), &self.render_configuration)
- {
- self.surface_width = (surface.width() as f64 * self.zoom).round() as i32;
- self.surface_height = (surface.height() as f64 * self.zoom).round() as i32;
+ if let Ok(surface) = render_to_surface(
+ &self.map,
+ &self.stage_type.to_localized(),
+ &self.render_configuration,
+ ) {
+ self.surface_width = (f64::from(surface.width()) * self.zoom).round() as i32;
+ self.surface_height = (f64::from(surface.height()) * self.zoom).round() as i32;
self.surface = surface;
let zoom = self.zoom;
@@ -272,6 +277,7 @@ impl AppModel {
self.source.set_text(content);
}
+ #[allow(clippy::cast_possible_truncation)]
fn apply_preferences(&mut self) {
self.source_view
.set_wrap_mode(if self.preferences.soft_wrap_lines {
@@ -325,8 +331,7 @@ impl AppModel {
}
for stage_type in &stage_types {
- self.stage_type_list
- .append(&stage_type.localized_name());
+ self.stage_type_list.append(&stage_type.localized_name());
}
self.available_stage_types = stage_types;
@@ -337,7 +342,7 @@ impl AppModel {
for template in &self.preferences.map_templates {
self.templates_menu.append(
Some(&template.name),
- Some(&format!("window.new-from-template::{}", template.id))
+ Some(&format!("window.new-from-template::{}", template.id)),
);
}
}
@@ -358,6 +363,121 @@ impl AppModel {
file_registry::store_controller(controller);
}
+
+ fn init_stage_type_list() -> gtk::StringList {
+ let stage_types: Vec<String> = ALL_STAGE_TYPES
+ .iter()
+ .map(stages::LocalizedStageType::localized_name)
+ .collect();
+ let stage_type_refs: Vec<&str> = stage_types
+ .iter()
+ .map(std::string::String::as_str)
+ .collect();
+ gtk::StringList::new(&stage_type_refs)
+ }
+
+ fn init_source_buffer(
+ init: &AppInit,
+ sender: &ComponentSender<Self>,
+ ) -> (sourceview5::Buffer, String, Option<PathBuf>) {
+ let source = sourceview5::Buffer::new(None);
+ source.set_highlight_syntax(true);
+
+ let language_manager = LanguageManager::default();
+ if let Some(language) = language_manager.language("wmap") {
+ source.set_language(Some(&language));
+ }
+
+ let (initial_content, current_file) = if let Some(ref path) = init.file_path {
+ match std::fs::read_to_string(path) {
+ Ok(content) => (content, Some(path.clone())),
+ Err(_) => (String::new(), None),
+ }
+ } else {
+ (init.initial_content.clone().unwrap_or_default(), None)
+ };
+
+ source.set_text(&initial_content);
+
+ {
+ let sender = sender.clone();
+ source.connect_changed(move |_| {
+ sender.input(Action::SourceChanged);
+ });
+ }
+
+ (source, initial_content, current_file)
+ }
+
+ fn init_drawing_area(
+ initial_content: &str,
+ ) -> (
+ gtk::DrawingArea,
+ Map,
+ Configuration,
+ StageType,
+ ImageSurface,
+ ) {
+ let drawing_area = gtk::DrawingArea::new();
+ let map = parse(initial_content);
+ let mut render_configuration = Configuration::default();
+ let stage_type = StageType::Activities;
+ render_configuration.options.smart_label_positioning = true;
+ let surface = render_to_surface(&map, &stage_type.to_localized(), &render_configuration)
+ .or_else(|_| ImageSurface::create(cairo::Format::ARgb32, 1, 1))
+ .unwrap_or_else(|e| {
+ eprintln!("Fatal: Cairo failed to create surface: {e}");
+ std::process::exit(1);
+ });
+
+ (drawing_area, map, render_configuration, stage_type, surface)
+ }
+
+ fn init_main_menu(prefs: &preferences::UserPreferences) -> (gio::Menu, gio::Menu) {
+ let templates_menu = gio::Menu::new();
+ for template in &prefs.map_templates {
+ templates_menu.append(
+ Some(&template.name),
+ Some(&format!("window.new-from-template::{}", template.id)),
+ );
+ }
+
+ let main_menu = gio::Menu::new();
+ main_menu.append(Some(&tr!("command.file.new")), Some("window.new"));
+ main_menu.append_submenu(
+ Some(&tr!("command.file.new_from_template")),
+ &templates_menu,
+ );
+ main_menu.append(Some(&tr!("command.file.open")), Some("window.open"));
+ main_menu.append(Some(&tr!("command.file.save")), Some("window.save"));
+ main_menu.append(Some(&tr!("command.file.save_as")), Some("window.save-as"));
+ main_menu.append(Some(&tr!("command.file.close")), Some("window.close"));
+ main_menu.append(
+ Some(&tr!("command.file.export")),
+ Some("window.export-image"),
+ );
+
+ let layout_section = gio::Menu::new();
+ layout_section.append(
+ Some(&tr!("command.view.use_vertical_layout")),
+ Some("window.change-orientation"),
+ );
+ main_menu.append_section(None, &layout_section);
+
+ let zoom_section = gio::Menu::new();
+ zoom_section.append(Some(&tr!("command.view.zoom_in")), Some("window.zoom-in"));
+ zoom_section.append(Some(&tr!("command.view.zoom_out")), Some("window.zoom-out"));
+ main_menu.append_section(None, &zoom_section);
+
+ let prefs_section = gio::Menu::new();
+ prefs_section.append(
+ Some(&tr!("command.application.preferences")),
+ Some("window.preferences"),
+ );
+ main_menu.append_section(None, &prefs_section);
+
+ (templates_menu, main_menu)
+ }
}
#[relm4::component]
@@ -496,40 +616,11 @@ impl SimpleComponent for AppModel {
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
- let stage_types: Vec<String> = ALL_STAGE_TYPES
- .iter()
- .map(|stage_type| stage_type.localized_name())
- .collect();
- let stage_type_refs: Vec<&str> = stage_types.iter().map(|s| s.as_str()).collect();
- let stage_type_list = gtk::StringList::new(&stage_type_refs);
+ let stage_type_list = Self::init_stage_type_list();
- let source = sourceview5::Buffer::new(None);
- source.set_highlight_syntax(true);
-
- let language_manager = LanguageManager::default();
- if let Some(language) = language_manager.language("wmap") {
- source.set_language(Some(&language));
- }
-
- let (initial_content, current_file) = if let Some(ref path) = init.file_path {
- match std::fs::read_to_string(path) {
- Ok(content) => (content, Some(path.clone())),
- Err(_) => (String::new(), None),
- }
- } else {
- (init.initial_content.unwrap_or_default(), None)
- };
-
- source.set_text(&initial_content);
-
- {
- let sender = sender.clone();
- source.connect_changed(move |_| {
- sender.input(Action::SourceChanged);
- });
- }
+ let (source, initial_content, current_file) = Self::init_source_buffer(&init, &sender);
- setup_actions(root.clone(), sender.clone());
+ setup_actions(&root, &sender);
let source_view = sourceview5::View::with_buffer(&source);
source_view.set_monospace(true);
@@ -540,55 +631,15 @@ impl SimpleComponent for AppModel {
gtk::STYLE_PROVIDER_PRIORITY_APPLICATION,
);
- let drawing_area = gtk::DrawingArea::new();
- let map = parse(&initial_content);
- let mut render_configuration = Configuration::default();
- let stage_type = StageType::Activities;
- render_configuration.options.smart_label_positioning = true;
- let surface =
- render_to_surface(&map, &stage_type.to_localized(), &render_configuration).unwrap_or_else(|_| {
- ImageSurface::create(cairo::Format::ARgb32, 1, 1)
- .expect("errors.render.failed_to_create_surface")
- });
+ let (drawing_area, map, render_configuration, stage_type, surface) =
+ Self::init_drawing_area(&initial_content);
if let Some(ref path) = current_file {
file_registry::register_file(path, &root);
}
let prefs = preferences::storage::load();
-
- let templates_menu = gio::Menu::new();
- for template in &prefs.map_templates {
- templates_menu.append(
- Some(&template.name),
- Some(&format!("window.new-from-template::{}", template.id))
- );
- }
-
- let main_menu = gio::Menu::new();
- main_menu.append(Some(&tr!("command.file.new")), Some("window.new"));
- main_menu.append_submenu(Some(&tr!("command.file.new_from_template")), &templates_menu);
- main_menu.append(Some(&tr!("command.file.open")), Some("window.open"));
- main_menu.append(Some(&tr!("command.file.save")), Some("window.save"));
- main_menu.append(Some(&tr!("command.file.save_as")), Some("window.save-as"));
- main_menu.append(Some(&tr!("command.file.close")), Some("window.close"));
- main_menu.append(Some(&tr!("command.file.export")), Some("window.export-image"));
-
- let layout_section = gio::Menu::new();
- layout_section.append(
- Some(&tr!("command.view.use_vertical_layout")),
- Some("window.change-orientation"),
- );
- main_menu.append_section(None, &layout_section);
-
- let zoom_section = gio::Menu::new();
- zoom_section.append(Some(&tr!("command.view.zoom_in")), Some("window.zoom-in"));
- zoom_section.append(Some(&tr!("command.view.zoom_out")), Some("window.zoom-out"));
- main_menu.append_section(None, &zoom_section);
-
- let prefs_section = gio::Menu::new();
- prefs_section.append(Some(&tr!("command.application.preferences")), Some("window.preferences"));
- main_menu.append_section(None, &prefs_section);
+ let (templates_menu, main_menu) = Self::init_main_menu(&prefs);
let mut model = AppModel {
orientation: gtk::Orientation::Horizontal,
@@ -663,10 +714,10 @@ impl SimpleComponent for AppModel {
Action::ZoomOut => handlers::zoom::zoom_out(self),
Action::ExportImage => {
- dialogs::show_export_dialog(&self.window, self.current_file.clone(), sender)
+ dialogs::show_export_dialog(&self.window, self.current_file.as_ref(), sender);
}
Action::ExportToFile { path, format } => {
- handlers::export::export_to_file(self, path, format)
+ handlers::export::export_to_file(self, &path, format);
}
Action::New => {
@@ -687,18 +738,18 @@ impl SimpleComponent for AppModel {
}
}
Action::Open => {
- dialogs::show_open_dialog(&self.window, self.is_empty_document(), sender)
+ dialogs::show_open_dialog(&self.window, self.is_empty_document(), sender);
}
Action::Save { close_after } => handlers::file::save(self, close_after, &sender),
Action::SaveAs { close_after } => dialogs::show_save_dialog(
&self.window,
- self.current_file.clone(),
+ self.current_file.as_ref(),
close_after,
sender,
),
Action::LoadFile(path) => handlers::file::load_file(self, path),
Action::SaveToFile { path, close_after } => {
- handlers::file::save_to_file(self, path, close_after)
+ handlers::file::save_to_file(self, path, close_after);
}
Action::CloseWindow => handlers::file::close_window(self, &sender),
@@ -729,7 +780,7 @@ impl SimpleComponent for AppModel {
self.rebuild_stage_type_list();
self.rebuild_templates_menu();
self.update_image();
- file_registry::broadcast_to_all_windows(Action::ReloadPreferences);
+ file_registry::broadcast_to_all_windows(&Action::ReloadPreferences);
}
Action::PreferencesWindowClosed => {
self.preferences_window = None;
diff --git a/src/preferences/models.rs b/src/preferences/models.rs
index dee84e6..81fa4d1 100644
--- a/src/preferences/models.rs
+++ b/src/preferences/models.rs
@@ -17,7 +17,7 @@
use serde::{Deserialize, Serialize};
use uuid::Uuid;
-/// Stage labels for custom stages (matches Swift Stage struct)
+/// Stage labels for custom stages
#[derive(Debug, Clone, Serialize, Deserialize, Default, PartialEq)]
pub struct Stage {
pub i: String,
@@ -26,7 +26,7 @@ pub struct Stage {
pub iv: String,
}
-/// Custom stage definition (matches Swift CustomStage)
+/// Custom stage definition
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct CustomStage {
@@ -73,7 +73,7 @@ impl CustomStage {
}
}
-/// Template for new maps (matches Swift Template)
+/// Template for new maps
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Template {
@@ -106,7 +106,7 @@ impl Template {
}
}
-/// JSON import/export format (matches Swift UserPreferencesJSON)
+/// JSON import/export format
/// All fields optional to support partial imports
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
@@ -136,6 +136,7 @@ pub struct UserPreferencesJson {
/// Main preferences struct stored in app
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
+#[allow(clippy::struct_excessive_bools)] // These are independent boolean preferences, not a state machine
pub struct UserPreferences {
// Map preferences
pub show_map_background: bool,
@@ -218,10 +219,10 @@ impl UserPreferences {
self.use_custom_font = *v;
}
if let Some(ref v) = json.custom_font_name {
- self.custom_font_name = v.clone();
+ self.custom_font_name.clone_from(v);
}
if let Some(ref v) = json.default_export_format {
- self.default_export_format = v.clone();
+ self.default_export_format.clone_from(v);
}
if let Some(v) = json.use_smart_label_positioning {
self.use_smart_label_positioning = v;
@@ -230,7 +231,7 @@ impl UserPreferences {
self.use_custom_editor_font = *v;
}
if let Some(ref v) = json.custom_editor_font_name {
- self.custom_editor_font_name = v.clone();
+ self.custom_editor_font_name.clone_from(v);
}
if let Some(v) = json.editor_font_size {
self.editor_font_size = v;
@@ -239,13 +240,13 @@ impl UserPreferences {
self.soft_wrap_lines = v;
}
if let Some(ref v) = json.map_templates {
- self.map_templates = v.clone();
+ self.map_templates.clone_from(v);
}
if let Some(ref v) = json.custom_stages {
- self.custom_stages = v.clone();
+ self.custom_stages.clone_from(v);
}
if let Some(ref v) = json.view_style {
- self.view_style = v.clone();
+ self.view_style.clone_from(v);
}
if let Some(v) = json.zoom {
self.zoom = v;
diff --git a/src/preferences/pages/editor.rs b/src/preferences/pages/editor.rs
index d4acb94..336a488 100644
--- a/src/preferences/pages/editor.rs
+++ b/src/preferences/pages/editor.rs
@@ -33,7 +33,7 @@ pub struct EditorPage {
}
impl EditorPage {
- pub fn new(preferences: &UserPreferences, sender: Sender<PreferencesInput>) -> Self {
+ pub fn new(preferences: &UserPreferences, sender: &Sender<PreferencesInput>) -> Self {
let container = gtk::Box::new(gtk::Orientation::Vertical, 20);
container.set_margin_top(20);
container.set_margin_bottom(20);
@@ -57,7 +57,9 @@ impl EditorPage {
});
}
font_size_box.append(&font_size_spin);
- font_size_box.append(&gtk::Label::new(Some(&tr!("preferences.editor.font_size.unit"))));
+ font_size_box.append(&gtk::Label::new(Some(&tr!(
+ "preferences.editor.font_size.unit"
+ ))));
container.append(&font_size_box);
// Editor Style section
@@ -68,7 +70,10 @@ impl EditorPage {
container.append(&style_label);
// Soft Wrap Lines
- let soft_wrap_row = create_switch_row(&tr!("preferences.editor.editor_style.soft_wrap_lines"), preferences.soft_wrap_lines);
+ let soft_wrap_row = create_switch_row(
+ &tr!("preferences.editor.editor_style.soft_wrap_lines"),
+ preferences.soft_wrap_lines,
+ );
let soft_wrap_switch = soft_wrap_row.1.clone();
{
let sender = sender.clone();
@@ -80,8 +85,10 @@ impl EditorPage {
container.append(&soft_wrap_row.0);
// Use Custom Font
- let custom_font_row =
- create_switch_row(&tr!("preferences.editor.editor_style.use_custom_font"), preferences.use_custom_editor_font);
+ let custom_font_row = create_switch_row(
+ &tr!("preferences.editor.editor_style.use_custom_font"),
+ preferences.use_custom_editor_font,
+ );
let custom_font_switch = custom_font_row.1.clone();
container.append(&custom_font_row.0);
@@ -90,6 +97,8 @@ impl EditorPage {
font_row.append(&gtk::Label::new(Some(&tr!("preferences.editor.font"))));
let font_button = gtk::FontButton::new();
+
+ #[allow(clippy::cast_possible_truncation)]
font_button.set_font(&format!(
"{} {}",
preferences.custom_editor_font_name, preferences.editor_font_size as i32
@@ -140,15 +149,16 @@ impl EditorPage {
pub fn sync_from(&self, preferences: &UserPreferences) {
self.font_size_spin.set_value(preferences.editor_font_size);
- self.soft_wrap_switch.set_active(preferences.soft_wrap_lines);
+ self.soft_wrap_switch
+ .set_active(preferences.soft_wrap_lines);
self.custom_font_switch
.set_active(preferences.use_custom_editor_font);
self.font_button
.set_sensitive(preferences.use_custom_editor_font);
+ #[allow(clippy::cast_possible_truncation)] // Font size is always a small positive number
self.font_button.set_font(&format!(
"{} {}",
preferences.custom_editor_font_name, preferences.editor_font_size as i32
));
}
}
-
diff --git a/src/preferences/pages/general.rs b/src/preferences/pages/general.rs
index d70e9e6..ad15c82 100644
--- a/src/preferences/pages/general.rs
+++ b/src/preferences/pages/general.rs
@@ -28,7 +28,7 @@ pub struct GeneralPage {
}
impl GeneralPage {
- pub fn new(sender: Sender<PreferencesInput>) -> Self {
+ pub fn new(sender: &Sender<PreferencesInput>) -> Self {
let container = gtk::Box::new(gtk::Orientation::Vertical, 20);
container.set_margin_top(20);
container.set_margin_bottom(20);
diff --git a/src/preferences/pages/map.rs b/src/preferences/pages/map.rs
index 5ffd04a..4355c6f 100644
--- a/src/preferences/pages/map.rs
+++ b/src/preferences/pages/map.rs
@@ -34,7 +34,7 @@ pub struct MapPage {
}
impl MapPage {
- pub fn new(preferences: &UserPreferences, sender: Sender<PreferencesInput>) -> Self {
+ pub fn new(preferences: &UserPreferences, sender: &Sender<PreferencesInput>) -> Self {
let container = gtk::Box::new(gtk::Orientation::Vertical, 20);
container.set_margin_top(20);
container.set_margin_bottom(20);
@@ -42,15 +42,36 @@ impl MapPage {
container.set_margin_end(20);
container.set_valign(gtk::Align::Start);
- // Map Style section
+ let (show_background_switch, smart_positioning_switch, custom_font_switch, font_button) =
+ Self::init_style_section(&container, preferences, sender);
+
+ let export_format_dropdown = Self::init_export_section(&container, preferences, sender);
+
+ Self {
+ container,
+ show_background_switch,
+ smart_positioning_switch,
+ custom_font_switch,
+ font_button,
+ export_format_dropdown,
+ }
+ }
+
+ fn init_style_section(
+ container: &gtk::Box,
+ preferences: &UserPreferences,
+ sender: &Sender<PreferencesInput>,
+ ) -> (gtk::Switch, gtk::Switch, gtk::Switch, gtk::FontButton) {
let style_label = gtk::Label::new(Some(&tr!("preferences.map.map_style.title")));
style_label.add_css_class("heading");
style_label.set_halign(gtk::Align::Start);
container.append(&style_label);
// Show Background
- let background_row =
- create_switch_row(&tr!("preferences.map.map_style.show_background"), preferences.show_map_background);
+ let background_row = create_switch_row(
+ &tr!("preferences.map.map_style.show_background"),
+ preferences.show_map_background,
+ );
let show_background_switch = background_row.1.clone();
{
let sender = sender.clone();
@@ -77,7 +98,10 @@ impl MapPage {
container.append(&smart_row.0);
// Use Custom Font
- let custom_font_row = create_switch_row(&tr!("preferences.map.map_style.use_custom_font"), preferences.use_custom_font);
+ let custom_font_row = create_switch_row(
+ &tr!("preferences.map.map_style.use_custom_font"),
+ preferences.use_custom_font,
+ );
let custom_font_switch = custom_font_row.1.clone();
container.append(&custom_font_row.0);
@@ -115,7 +139,19 @@ impl MapPage {
});
}
- // Export section
+ (
+ show_background_switch,
+ smart_positioning_switch,
+ custom_font_switch,
+ font_button,
+ )
+ }
+
+ fn init_export_section(
+ container: &gtk::Box,
+ preferences: &UserPreferences,
+ sender: &Sender<PreferencesInput>,
+ ) -> gtk::DropDown {
let export_label = gtk::Label::new(Some(&tr!("preferences.map.export.title")));
export_label.add_css_class("heading");
export_label.set_halign(gtk::Align::Start);
@@ -123,9 +159,12 @@ impl MapPage {
container.append(&export_label);
let export_row = gtk::Box::new(gtk::Orientation::Horizontal, 10);
- export_row.append(&gtk::Label::new(Some(&tr!("preferences.map.export.default_format"))));
+ export_row.append(&gtk::Label::new(Some(&tr!(
+ "preferences.map.export.default_format"
+ ))));
- let formats = gtk::StringList::new(&[&tr!("export_formats.png"), &tr!("export_formats.svg")]);
+ let formats =
+ gtk::StringList::new(&[&tr!("export_formats.png"), &tr!("export_formats.svg")]);
let export_format_dropdown = gtk::DropDown::new(Some(formats), None::<gtk::Expression>);
let selected = match preferences.default_export_format.as_str() {
"svg" => 1,
@@ -145,14 +184,7 @@ impl MapPage {
export_row.append(&export_format_dropdown);
container.append(&export_row);
- Self {
- container,
- show_background_switch,
- smart_positioning_switch,
- custom_font_switch,
- font_button,
- export_format_dropdown,
- }
+ export_format_dropdown
}
pub fn widget(&self) -> gtk::Box {
@@ -176,4 +208,3 @@ impl MapPage {
self.export_format_dropdown.set_selected(selected);
}
}
-
diff --git a/src/preferences/pages/stages.rs b/src/preferences/pages/stages.rs
index 9f0685d..4bd24e1 100644
--- a/src/preferences/pages/stages.rs
+++ b/src/preferences/pages/stages.rs
@@ -60,25 +60,25 @@ impl StagesPage {
name_header.set_xalign(0.0);
header_row.append(&name_header);
- let i_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_i")));
- i_header.set_width_chars(12);
- i_header.set_xalign(0.0);
- header_row.append(&i_header);
+ let first_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_i")));
+ first_header.set_width_chars(12);
+ first_header.set_xalign(0.0);
+ header_row.append(&first_header);
- let ii_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_ii")));
- ii_header.set_width_chars(12);
- ii_header.set_xalign(0.0);
- header_row.append(&ii_header);
+ let second_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_ii")));
+ second_header.set_width_chars(12);
+ second_header.set_xalign(0.0);
+ header_row.append(&second_header);
- let iii_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_iii")));
- iii_header.set_width_chars(12);
- iii_header.set_xalign(0.0);
- header_row.append(&iii_header);
+ let third_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_iii")));
+ third_header.set_width_chars(12);
+ third_header.set_xalign(0.0);
+ header_row.append(&third_header);
- let iv_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_iv")));
- iv_header.set_width_chars(12);
- iv_header.set_xalign(0.0);
- header_row.append(&iv_header);
+ let fourth_header = gtk::Label::new(Some(&tr!("preferences.stages.column.stage_iv")));
+ fourth_header.set_width_chars(12);
+ fourth_header.set_xalign(0.0);
+ header_row.append(&fourth_header);
// Spacer for delete button column
let spacer = gtk::Box::new(gtk::Orientation::Horizontal, 0);
@@ -172,12 +172,12 @@ impl StagesPage {
hbox.append(&name_entry);
// Stage I entry
- let i_entry = gtk::Entry::new();
- i_entry.set_text(&stage.i);
- i_entry.set_width_chars(12);
+ let first_entry = gtk::Entry::new();
+ first_entry.set_text(&stage.i);
+ first_entry.set_width_chars(12);
{
let sender = self.sender.clone();
- i_entry.connect_changed(move |entry| {
+ first_entry.connect_changed(move |entry| {
sender.emit(PreferencesInput::SetCustomStageLabel(
id,
StageLabel::I,
@@ -185,15 +185,15 @@ impl StagesPage {
));
});
}
- hbox.append(&i_entry);
+ hbox.append(&first_entry);
// Stage II entry
- let ii_entry = gtk::Entry::new();
- ii_entry.set_text(&stage.ii);
- ii_entry.set_width_chars(12);
+ let second_entry = gtk::Entry::new();
+ second_entry.set_text(&stage.ii);
+ second_entry.set_width_chars(12);
{
let sender = self.sender.clone();
- ii_entry.connect_changed(move |entry| {
+ second_entry.connect_changed(move |entry| {
sender.emit(PreferencesInput::SetCustomStageLabel(
id,
StageLabel::Ii,
@@ -201,15 +201,15 @@ impl StagesPage {
));
});
}
- hbox.append(&ii_entry);
+ hbox.append(&second_entry);
// Stage III entry
- let iii_entry = gtk::Entry::new();
- iii_entry.set_text(&stage.iii);
- iii_entry.set_width_chars(12);
+ let third_entry = gtk::Entry::new();
+ third_entry.set_text(&stage.iii);
+ third_entry.set_width_chars(12);
{
let sender = self.sender.clone();
- iii_entry.connect_changed(move |entry| {
+ third_entry.connect_changed(move |entry| {
sender.emit(PreferencesInput::SetCustomStageLabel(
id,
StageLabel::Iii,
@@ -217,15 +217,15 @@ impl StagesPage {
));
});
}
- hbox.append(&iii_entry);
+ hbox.append(&third_entry);
// Stage IV entry
- let iv_entry = gtk::Entry::new();
- iv_entry.set_text(&stage.iv);
- iv_entry.set_width_chars(12);
+ let fourth_entry = gtk::Entry::new();
+ fourth_entry.set_text(&stage.iv);
+ fourth_entry.set_width_chars(12);
{
let sender = self.sender.clone();
- iv_entry.connect_changed(move |entry| {
+ fourth_entry.connect_changed(move |entry| {
sender.emit(PreferencesInput::SetCustomStageLabel(
id,
StageLabel::Iv,
@@ -233,7 +233,7 @@ impl StagesPage {
));
});
}
- hbox.append(&iv_entry);
+ hbox.append(&fourth_entry);
// Delete button
let delete_button = gtk::Button::from_icon_name("list-remove-symbolic");
diff --git a/src/preferences/pages/templates.rs b/src/preferences/pages/templates.rs
index acc679f..1760085 100644
--- a/src/preferences/pages/templates.rs
+++ b/src/preferences/pages/templates.rs
@@ -78,9 +78,9 @@ impl TemplatesPage {
{
let sender = sender.clone();
add_button.connect_clicked(move |_| {
- sender.emit(PreferencesInput::AddTemplate(
- tr!("dialog.template.default_label"),
- ));
+ sender.emit(PreferencesInput::AddTemplate(tr!(
+ "dialog.template.default_label"
+ )));
});
}
button_box.append(&add_button);
@@ -226,7 +226,7 @@ impl TemplatesPage {
self.list_box.connect_row_selected(move |_, row| {
if let Some(row) = row {
- let index = row.index() as usize;
+ let index: usize = row.index().try_into().unwrap_or(0);
if let Some(template) = templates.get(index) {
*selected_id.borrow_mut() = Some(template.id);
editor_buffer.set_text(&template.content);
@@ -251,7 +251,8 @@ impl TemplatesPage {
default_button.set_tooltip_text(Some(&tr!("preferences.templates.help.default")));
} else {
default_button.set_icon_name("radio-symbolic");
- default_button.set_tooltip_text(Some(&tr!("preferences.templates.help.set_as_default")));
+ default_button
+ .set_tooltip_text(Some(&tr!("preferences.templates.help.set_as_default")));
}
default_button.add_css_class("flat");
{
@@ -271,7 +272,10 @@ impl TemplatesPage {
let sender = self.sender.clone();
let id = template.id;
name_entry.connect_changed(move |entry| {
- sender.emit(PreferencesInput::SetTemplateName(id, entry.text().to_string()));
+ sender.emit(PreferencesInput::SetTemplateName(
+ id,
+ entry.text().to_string(),
+ ));
});
}
hbox.append(&name_entry);
diff --git a/src/preferences/window.rs b/src/preferences/window.rs
index 2118056..0997716 100644
--- a/src/preferences/window.rs
+++ b/src/preferences/window.rs
@@ -143,9 +143,9 @@ impl SimpleComponent for PreferencesWindow {
root: Self::Root,
sender: ComponentSender<Self>,
) -> ComponentParts<Self> {
- let general_page = general::GeneralPage::new(sender.input_sender().clone());
- let editor_page = editor::EditorPage::new(&preferences, sender.input_sender().clone());
- let map_page = map::MapPage::new(&preferences, sender.input_sender().clone());
+ let general_page = general::GeneralPage::new(&sender.input_sender().clone());
+ let editor_page = editor::EditorPage::new(&preferences, &sender.input_sender().clone());
+ let map_page = map::MapPage::new(&preferences, &sender.input_sender().clone());
let stages_page = stages::StagesPage::new(&preferences, sender.input_sender().clone());
let templates_page =
templates::TemplatesPage::new(&preferences, sender.input_sender().clone());
@@ -167,7 +167,6 @@ impl SimpleComponent for PreferencesWindow {
fn update(&mut self, message: Self::Input, sender: ComponentSender<Self>) {
match message {
- // General page actions
PreferencesInput::Export => {
general::show_export_dialog(sender.input_sender(), &self.window);
}
@@ -188,8 +187,6 @@ impl SimpleComponent for PreferencesWindow {
self.sync_ui_from_preferences();
self.save_and_notify(&sender);
}
-
- // Map preferences
PreferencesInput::SetShowMapBackground(v) => {
self.preferences.show_map_background = v;
self.save_and_notify(&sender);
@@ -210,8 +207,6 @@ impl SimpleComponent for PreferencesWindow {
self.preferences.use_smart_label_positioning = v;
self.save_and_notify(&sender);
}
-
- // Editor preferences
PreferencesInput::SetUseCustomEditorFont(v) => {
self.preferences.use_custom_editor_font = v;
self.save_and_notify(&sender);
@@ -228,88 +223,29 @@ impl SimpleComponent for PreferencesWindow {
self.preferences.soft_wrap_lines = v;
self.save_and_notify(&sender);
}
-
- // Templates
- PreferencesInput::AddTemplate(name) => {
- let template = super::models::Template::new(name, String::new(), false);
- self.preferences.map_templates.push(template);
- self.templates_page.refresh(&self.preferences);
- self.save_and_notify(&sender);
- }
- PreferencesInput::RemoveTemplate(id) => {
- self.preferences.map_templates.retain(|t| t.id != id);
- self.templates_page.refresh(&self.preferences);
- self.save_and_notify(&sender);
- }
+ PreferencesInput::AddTemplate(name) => self.handle_add_template(name, &sender),
+ PreferencesInput::RemoveTemplate(id) => self.handle_remove_template(id, &sender),
PreferencesInput::SetTemplateContent(id, content) => {
- if let Some(template) = self
- .preferences
- .map_templates
- .iter_mut()
- .find(|t| t.id == id)
- {
- template.content = content;
- self.save_and_notify(&sender);
- }
+ self.handle_set_template_content(id, content, &sender);
}
PreferencesInput::SetTemplateName(id, name) => {
- if let Some(template) = self
- .preferences
- .map_templates
- .iter_mut()
- .find(|t| t.id == id)
- {
- template.name = name;
- self.templates_page.refresh(&self.preferences);
- self.save_and_notify(&sender);
- }
+ self.handle_set_template_name(id, name, &sender);
}
PreferencesInput::SetDefaultTemplate(id) => {
self.preferences.set_default_template(id);
self.templates_page.refresh(&self.preferences);
self.save_and_notify(&sender);
}
-
- // Custom stages
- PreferencesInput::AddCustomStage => {
- let stage = super::models::CustomStage::placeholder_default();
- self.preferences.custom_stages.push(stage);
- self.stages_page.refresh(&self.preferences);
- self.save_and_notify(&sender);
- }
+ PreferencesInput::AddCustomStage => self.handle_add_custom_stage(&sender),
PreferencesInput::RemoveCustomStage(id) => {
- self.preferences.custom_stages.retain(|s| s.id != id);
- self.stages_page.refresh(&self.preferences);
- self.save_and_notify(&sender);
+ self.handle_remove_custom_stage(id, &sender);
}
PreferencesInput::SetCustomStageName(id, name) => {
- if let Some(stage) = self
- .preferences
- .custom_stages
- .iter_mut()
- .find(|s| s.id == id)
- {
- stage.name = name;
- self.save_and_notify(&sender);
- }
+ self.handle_set_custom_stage_name(id, name, &sender);
}
PreferencesInput::SetCustomStageLabel(id, label, value) => {
- if let Some(stage) = self
- .preferences
- .custom_stages
- .iter_mut()
- .find(|s| s.id == id)
- {
- match label {
- StageLabel::I => stage.stage.i = value,
- StageLabel::Ii => stage.stage.ii = value,
- StageLabel::Iii => stage.stage.iii = value,
- StageLabel::Iv => stage.stage.iv = value,
- }
- self.save_and_notify(&sender);
- }
+ self.handle_set_custom_stage_label(id, label, value, &sender);
}
-
PreferencesInput::Close => {
sender.output(PreferencesOutput::Closed).ok();
}
@@ -333,4 +269,105 @@ impl PreferencesWindow {
self.stages_page.refresh(&self.preferences);
self.templates_page.refresh(&self.preferences);
}
+
+ fn handle_add_template(&mut self, name: String, sender: &ComponentSender<Self>) {
+ let template = super::models::Template::new(name, String::new(), false);
+ self.preferences.map_templates.push(template);
+ self.templates_page.refresh(&self.preferences);
+ self.save_and_notify(sender);
+ }
+
+ fn handle_remove_template(&mut self, id: uuid::Uuid, sender: &ComponentSender<Self>) {
+ self.preferences.map_templates.retain(|t| t.id != id);
+ self.templates_page.refresh(&self.preferences);
+ self.save_and_notify(sender);
+ }
+
+ fn handle_set_template_content(
+ &mut self,
+ id: uuid::Uuid,
+ content: String,
+ sender: &ComponentSender<Self>,
+ ) {
+ if let Some(template) = self
+ .preferences
+ .map_templates
+ .iter_mut()
+ .find(|t| t.id == id)
+ {
+ template.content = content;
+ self.save_and_notify(sender);
+ }
+ }
+
+ fn handle_set_template_name(
+ &mut self,
+ id: uuid::Uuid,
+ name: String,
+ sender: &ComponentSender<Self>,
+ ) {
+ if let Some(template) = self
+ .preferences
+ .map_templates
+ .iter_mut()
+ .find(|t| t.id == id)
+ {
+ template.name = name;
+ self.templates_page.refresh(&self.preferences);
+ self.save_and_notify(sender);
+ }
+ }
+
+ fn handle_add_custom_stage(&mut self, sender: &ComponentSender<Self>) {
+ let stage = super::models::CustomStage::placeholder_default();
+ self.preferences.custom_stages.push(stage);
+ self.stages_page.refresh(&self.preferences);
+ self.save_and_notify(sender);
+ }
+
+ fn handle_remove_custom_stage(&mut self, id: uuid::Uuid, sender: &ComponentSender<Self>) {
+ self.preferences.custom_stages.retain(|s| s.id != id);
+ self.stages_page.refresh(&self.preferences);
+ self.save_and_notify(sender);
+ }
+
+ fn handle_set_custom_stage_name(
+ &mut self,
+ id: uuid::Uuid,
+ name: String,
+ sender: &ComponentSender<Self>,
+ ) {
+ if let Some(stage) = self
+ .preferences
+ .custom_stages
+ .iter_mut()
+ .find(|s| s.id == id)
+ {
+ stage.name = name;
+ self.save_and_notify(sender);
+ }
+ }
+
+ fn handle_set_custom_stage_label(
+ &mut self,
+ id: uuid::Uuid,
+ label: StageLabel,
+ value: String,
+ sender: &ComponentSender<Self>,
+ ) {
+ if let Some(stage) = self
+ .preferences
+ .custom_stages
+ .iter_mut()
+ .find(|s| s.id == id)
+ {
+ match label {
+ StageLabel::I => stage.stage.i = value,
+ StageLabel::Ii => stage.stage.ii = value,
+ StageLabel::Iii => stage.stage.iii = value,
+ StageLabel::Iv => stage.stage.iv = value,
+ }
+ self.save_and_notify(sender);
+ }
+ }
}
diff --git a/src/stages.rs b/src/stages.rs
index 8de8f89..3ab1f5a 100644
--- a/src/stages.rs
+++ b/src/stages.rs
@@ -14,8 +14,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
-use wmap_renderer::StageType;
use crate::tr;
+use wmap_renderer::StageType;
/// All available stage types for rendering Wardley Maps.
/// Order determines dropdown menu order.
@@ -77,7 +77,13 @@ impl LocalizedStageType for StageType {
StageType::Behavior => tr!("stages.behavior.name"),
StageType::Cynefin => tr!("stages.cynefin.name"),
StageType::EvolutionStage => tr!("stages.evolution_stage.name"),
- StageType::Custom{name, i: _, ii: _, iii: _, iv: _} => name.to_string()
+ StageType::Custom {
+ name,
+ i: _,
+ ii: _,
+ iii: _,
+ iv: _,
+ } => name.clone(),
}
}
fn localized_i(&self) -> String {
@@ -104,7 +110,13 @@ impl LocalizedStageType for StageType {
StageType::Behavior => tr!("stages.behavior.i"),
StageType::Cynefin => tr!("stages.cynefin.i"),
StageType::EvolutionStage => tr!("stages.evolution_stage.i"),
- StageType::Custom{name: _, i, ii: _, iii: _, iv: _} => i.to_string()
+ StageType::Custom {
+ name: _,
+ i,
+ ii: _,
+ iii: _,
+ iv: _,
+ } => i.clone(),
}
}
fn localized_ii(&self) -> String {
@@ -131,7 +143,13 @@ impl LocalizedStageType for StageType {
StageType::Behavior => tr!("stages.behavior.ii"),
StageType::Cynefin => tr!("stages.cynefin.ii"),
StageType::EvolutionStage => tr!("stages.evolution_stage.ii"),
- StageType::Custom{name: _, i: _, ii, iii: _, iv: _} => ii.to_string()
+ StageType::Custom {
+ name: _,
+ i: _,
+ ii,
+ iii: _,
+ iv: _,
+ } => ii.clone(),
}
}
fn localized_iii(&self) -> String {
@@ -158,7 +176,13 @@ impl LocalizedStageType for StageType {
StageType::Behavior => tr!("stages.behavior.iii"),
StageType::Cynefin => tr!("stages.cynefin.iii"),
StageType::EvolutionStage => tr!("stages.evolution_stage.iii"),
- StageType::Custom{name: _, i: _, ii: _, iii, iv: _} => iii.to_string()
+ StageType::Custom {
+ name: _,
+ i: _,
+ ii: _,
+ iii,
+ iv: _,
+ } => iii.clone(),
}
}
fn localized_iv(&self) -> String {
@@ -185,17 +209,23 @@ impl LocalizedStageType for StageType {
StageType::Behavior => tr!("stages.behavior.iv"),
StageType::Cynefin => tr!("stages.cynefin.iv"),
StageType::EvolutionStage => tr!("stages.evolution_stage.iv"),
- StageType::Custom{name: _, i: _, ii: _, iii: _, iv} => iv.to_string()
+ StageType::Custom {
+ name: _,
+ i: _,
+ ii: _,
+ iii: _,
+ iv,
+ } => iv.clone(),
}
}
fn to_localized(&self) -> StageType {
- StageType::Custom{
+ StageType::Custom {
name: self.localized_name(),
i: self.localized_i(),
ii: self.localized_ii(),
iii: self.localized_iii(),
- iv: self.localized_iv()
+ iv: self.localized_iv(),
}
}
}