cadmus_core/view/settings_editor/kinds/
import.rs1use super::{SettingData, SettingIdentity, SettingKind, ToggleSettings, WidgetKind};
4use crate::fl;
5use crate::settings::{FileExtension, Settings};
6use crate::view::{Bus, EntryId, EntryKind, Event, ToggleEvent};
7
8pub struct ImportStartupTrigger;
10
11impl SettingKind for ImportStartupTrigger {
12 fn identity(&self) -> SettingIdentity {
13 SettingIdentity::ImportStartupTrigger
14 }
15
16 fn label(&self, _settings: &Settings) -> String {
17 fl!("settings-import-startup-trigger")
18 }
19
20 fn fetch(&self, settings: &Settings) -> SettingData {
21 SettingData {
22 value: settings.import.startup_trigger.to_string(),
23 widget: WidgetKind::Toggle {
24 left_label: fl!("settings-general-toggle-on"),
25 right_label: fl!("settings-general-toggle-off"),
26 enabled: settings.import.startup_trigger,
27 tap_event: Event::Toggle(ToggleEvent::Setting(
28 ToggleSettings::ImportStartupTrigger,
29 )),
30 },
31 }
32 }
33
34 fn handle(
35 &self,
36 evt: &Event,
37 settings: &mut Settings,
38 _bus: &mut Bus,
39 ) -> (Option<String>, bool) {
40 if let Event::Toggle(ToggleEvent::Setting(ToggleSettings::ImportStartupTrigger)) = evt {
41 settings.import.startup_trigger = !settings.import.startup_trigger;
42 return (Some(settings.import.startup_trigger.to_string()), true);
43 }
44 (None, false)
45 }
46}
47
48pub struct ImportSyncMetadata;
50
51impl SettingKind for ImportSyncMetadata {
52 fn identity(&self) -> SettingIdentity {
53 SettingIdentity::ImportSyncMetadata
54 }
55
56 fn label(&self, _settings: &Settings) -> String {
57 fl!("settings-import-sync-metadata")
58 }
59
60 fn fetch(&self, settings: &Settings) -> SettingData {
61 SettingData {
62 value: settings.import.sync_metadata.to_string(),
63 widget: WidgetKind::Toggle {
64 left_label: fl!("settings-general-toggle-on"),
65 right_label: fl!("settings-general-toggle-off"),
66 enabled: settings.import.sync_metadata,
67 tap_event: Event::Toggle(ToggleEvent::Setting(ToggleSettings::ImportSyncMetadata)),
68 },
69 }
70 }
71
72 fn handle(
73 &self,
74 evt: &Event,
75 settings: &mut Settings,
76 _bus: &mut Bus,
77 ) -> (Option<String>, bool) {
78 if let Event::Toggle(ToggleEvent::Setting(ToggleSettings::ImportSyncMetadata)) = evt {
79 settings.import.sync_metadata = !settings.import.sync_metadata;
80 return (Some(settings.import.sync_metadata.to_string()), true);
81 }
82 (None, false)
83 }
84}
85
86pub struct AllowedKindsSetting;
88
89impl SettingKind for AllowedKindsSetting {
90 fn identity(&self) -> SettingIdentity {
91 SettingIdentity::AllowedKinds
92 }
93
94 fn label(&self, _settings: &Settings) -> String {
95 fl!("settings-import-allowed-kinds")
96 }
97
98 fn fetch(&self, settings: &Settings) -> SettingData {
99 let entries = FileExtension::all()
100 .iter()
101 .copied()
102 .map(|kind| {
103 EntryKind::CheckBox(
104 kind.to_string().to_uppercase(),
105 EntryId::ToggleAllowedKind(kind),
106 settings.import.allowed_kinds.contains(&kind),
107 )
108 })
109 .collect();
110
111 SettingData {
112 value: kinds_summary(settings.import.allowed_kinds.len()),
113 widget: WidgetKind::SubMenu(entries),
114 }
115 }
116
117 fn handle(
118 &self,
119 evt: &Event,
120 settings: &mut Settings,
121 _bus: &mut Bus,
122 ) -> (Option<String>, bool) {
123 if let Event::Select(EntryId::ToggleAllowedKind(kind)) = evt {
124 if !settings.import.allowed_kinds.remove(kind) {
125 settings.import.allowed_kinds.insert(*kind);
126 }
127
128 return (
129 Some(kinds_summary(settings.import.allowed_kinds.len())),
130 true,
131 );
132 }
133
134 (None, false)
135 }
136
137 fn keep_menu_open(&self) -> bool {
138 true
139 }
140}
141
142fn kinds_summary(selected: usize) -> String {
143 format!("{selected} / {}", FileExtension::all().len())
144}
145
146#[cfg(test)]
147mod tests {
148 use super::*;
149 use crate::settings::{FileExtension, Settings};
150 use crate::view::settings_editor::kinds::ToggleSettings;
151 use crate::view::{Bus, EntryKind, Event, ToggleEvent};
152 use std::collections::VecDeque;
153
154 mod import_startup_trigger {
155 use super::*;
156
157 #[test]
158 fn handle_toggle_disables_when_enabled() {
159 let setting = ImportStartupTrigger;
160 let mut settings = Settings::default();
161 settings.import.startup_trigger = true;
162 let mut bus: Bus = VecDeque::new();
163 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::ImportStartupTrigger));
164
165 let result = setting.handle(&event, &mut settings, &mut bus);
166
167 assert!(result.0.is_some());
168 assert!(!settings.import.startup_trigger);
169 }
170
171 #[test]
172 fn handle_toggle_enables_when_disabled() {
173 let setting = ImportStartupTrigger;
174 let mut settings = Settings::default();
175 settings.import.startup_trigger = false;
176 let mut bus: Bus = VecDeque::new();
177 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::ImportStartupTrigger));
178
179 let result = setting.handle(&event, &mut settings, &mut bus);
180
181 assert!(result.0.is_some());
182 assert!(settings.import.startup_trigger);
183 }
184
185 #[test]
186 fn handle_returns_none_for_wrong_event() {
187 let setting = ImportStartupTrigger;
188 let mut settings = Settings::default();
189 let mut bus: Bus = VecDeque::new();
190 use crate::view::EntryId;
191
192 let result = setting.handle(&Event::Select(EntryId::About), &mut settings, &mut bus);
193
194 assert!(result.0.is_none());
195 }
196
197 #[test]
198 fn handle_returns_none_for_wrong_toggle() {
199 let setting = ImportStartupTrigger;
200 let mut settings = Settings::default();
201 let mut bus: Bus = VecDeque::new();
202
203 let result = setting.handle(
204 &Event::Toggle(ToggleEvent::Setting(ToggleSettings::SleepCover)),
205 &mut settings,
206 &mut bus,
207 );
208
209 assert!(result.0.is_none());
210 }
211 }
212
213 mod import_sync_metadata {
214 use super::*;
215
216 #[test]
217 fn handle_toggle_disables_when_enabled() {
218 let setting = ImportSyncMetadata;
219 let mut settings = Settings::default();
220 settings.import.sync_metadata = true;
221 let mut bus: Bus = VecDeque::new();
222 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::ImportSyncMetadata));
223
224 let result = setting.handle(&event, &mut settings, &mut bus);
225
226 assert!(result.0.is_some());
227 assert!(!settings.import.sync_metadata);
228 }
229
230 #[test]
231 fn handle_toggle_enables_when_disabled() {
232 let setting = ImportSyncMetadata;
233 let mut settings = Settings::default();
234 settings.import.sync_metadata = false;
235 let mut bus: Bus = VecDeque::new();
236 let event = Event::Toggle(ToggleEvent::Setting(ToggleSettings::ImportSyncMetadata));
237
238 let result = setting.handle(&event, &mut settings, &mut bus);
239
240 assert!(result.0.is_some());
241 assert!(settings.import.sync_metadata);
242 }
243
244 #[test]
245 fn handle_returns_none_for_wrong_event() {
246 let setting = ImportSyncMetadata;
247 let mut settings = Settings::default();
248 let mut bus: Bus = VecDeque::new();
249 use crate::view::EntryId;
250
251 let result = setting.handle(&Event::Select(EntryId::About), &mut settings, &mut bus);
252
253 assert!(result.0.is_none());
254 }
255
256 #[test]
257 fn handle_returns_none_for_wrong_toggle() {
258 let setting = ImportSyncMetadata;
259 let mut settings = Settings::default();
260 let mut bus: Bus = VecDeque::new();
261
262 let result = setting.handle(
263 &Event::Toggle(ToggleEvent::Setting(ToggleSettings::SleepCover)),
264 &mut settings,
265 &mut bus,
266 );
267
268 assert!(result.0.is_none());
269 }
270 }
271
272 mod allowed_kinds_setting {
273 use super::*;
274
275 #[test]
276 fn fetch_builds_checkbox_submenu_for_all_extensions() {
277 let setting = AllowedKindsSetting;
278 let settings = Settings::default();
279
280 let data = setting.fetch(&settings);
281
282 assert_eq!(
283 data.value,
284 kinds_summary(settings.import.allowed_kinds.len())
285 );
286 let WidgetKind::SubMenu(entries) = data.widget else {
287 panic!("expected submenu widget");
288 };
289 assert_eq!(entries.len(), FileExtension::all().len());
290 assert!(matches!(
291 entries.first(),
292 Some(EntryKind::CheckBox(_, EntryId::ToggleAllowedKind(_), _))
293 ));
294 }
295
296 #[test]
297 fn handle_toggle_adds_and_removes_extensions() {
298 let setting = AllowedKindsSetting;
299 let mut settings = Settings::default();
300 settings.import.allowed_kinds.remove(&FileExtension::Cbr);
301 let mut bus: Bus = VecDeque::new();
302
303 let add = setting.handle(
304 &Event::Select(EntryId::ToggleAllowedKind(FileExtension::Cbr)),
305 &mut settings,
306 &mut bus,
307 );
308 assert_eq!(
309 add.0,
310 Some(kinds_summary(settings.import.allowed_kinds.len()))
311 );
312 assert!(settings.import.allowed_kinds.contains(&FileExtension::Cbr));
313
314 let remove = setting.handle(
315 &Event::Select(EntryId::ToggleAllowedKind(FileExtension::Cbr)),
316 &mut settings,
317 &mut bus,
318 );
319 assert_eq!(
320 remove.0,
321 Some(kinds_summary(settings.import.allowed_kinds.len()))
322 );
323 assert!(!settings.import.allowed_kinds.contains(&FileExtension::Cbr));
324 }
325 }
326}