cadmus_core/view/settings_editor/kinds/
intermission.rs1use super::{SettingData, SettingIdentity, SettingKind, WidgetKind};
4use crate::fl;
5use crate::i18n::I18nDisplay;
6use crate::settings::{IntermKind, IntermissionDisplay, Settings};
7use crate::view::{Bus, EntryId, EntryKind, Event};
8
9fn fetch_intermission(kind: IntermKind, settings: &Settings) -> SettingData {
11 let display = &settings.intermissions[kind];
12
13 let (value, is_logo, is_cover) = match display {
14 IntermissionDisplay::Logo => (display.to_i18n_string(), true, false),
15 IntermissionDisplay::Cover => (display.to_i18n_string(), false, true),
16 IntermissionDisplay::Image(path) => {
17 let i18n_display = fl!("settings-intermission-custom");
18 let display_name = path
19 .file_name()
20 .and_then(|n| n.to_str())
21 .unwrap_or(i18n_display.as_str())
22 .to_string();
23 (display_name, false, false)
24 }
25 };
26
27 let entries = vec![
28 EntryKind::RadioButton(
29 IntermissionDisplay::Logo.to_i18n_string(),
30 EntryId::SetIntermission(kind, IntermissionDisplay::Logo),
31 is_logo,
32 ),
33 EntryKind::RadioButton(
34 IntermissionDisplay::Cover.to_i18n_string(),
35 EntryId::SetIntermission(kind, IntermissionDisplay::Cover),
36 is_cover,
37 ),
38 EntryKind::Command(
39 fl!("settings-intermission-custom-image"),
40 EntryId::EditIntermissionImage(kind),
41 ),
42 ];
43
44 SettingData {
45 value,
46 widget: WidgetKind::SubMenu(entries),
47 }
48}
49
50fn intermission_display_name(display: &IntermissionDisplay) -> String {
56 let i18n_display = fl!("settings-intermission-custom");
57 match display {
58 IntermissionDisplay::Image(path) => path
59 .file_name()
60 .and_then(|n| n.to_str())
61 .unwrap_or(i18n_display.as_str())
62 .to_string(),
63 _ => display.to_i18n_string(),
64 }
65}
66
67pub struct IntermissionSuspend;
69
70impl SettingKind for IntermissionSuspend {
71 fn identity(&self) -> SettingIdentity {
72 SettingIdentity::IntermissionSuspend
73 }
74
75 fn label(&self, _settings: &Settings) -> String {
76 fl!("settings-intermission-suspend-screen")
77 }
78
79 fn fetch(&self, settings: &Settings) -> SettingData {
80 fetch_intermission(IntermKind::Suspend, settings)
81 }
82
83 fn handle(&self, evt: &Event, settings: &mut Settings, _bus: &mut Bus) -> Option<String> {
84 if let Event::Select(EntryId::SetIntermission(IntermKind::Suspend, ref display)) = evt {
85 settings.intermissions[IntermKind::Suspend] = display.clone();
86 return Some(intermission_display_name(display));
87 }
88
89 if let Event::FileChooserClosed(Some(ref path)) = evt {
90 let display = IntermissionDisplay::Image(path.clone());
91 settings.intermissions[IntermKind::Suspend] = display.clone();
92 return Some(intermission_display_name(&display));
93 }
94
95 None
96 }
97
98 fn file_chooser_entry_id(&self) -> Option<EntryId> {
99 Some(EntryId::EditIntermissionImage(IntermKind::Suspend))
100 }
101}
102
103pub struct IntermissionPowerOff;
105
106impl SettingKind for IntermissionPowerOff {
107 fn identity(&self) -> SettingIdentity {
108 SettingIdentity::IntermissionPowerOff
109 }
110
111 fn label(&self, _settings: &Settings) -> String {
112 fl!("settings-intermission-power-off-screen")
113 }
114
115 fn fetch(&self, settings: &Settings) -> SettingData {
116 fetch_intermission(IntermKind::PowerOff, settings)
117 }
118
119 fn handle(&self, evt: &Event, settings: &mut Settings, _bus: &mut Bus) -> Option<String> {
120 if let Event::Select(EntryId::SetIntermission(IntermKind::PowerOff, ref display)) = evt {
121 settings.intermissions[IntermKind::PowerOff] = display.clone();
122 return Some(intermission_display_name(display));
123 }
124
125 if let Event::FileChooserClosed(Some(ref path)) = evt {
126 let display = IntermissionDisplay::Image(path.clone());
127 settings.intermissions[IntermKind::PowerOff] = display.clone();
128 return Some(intermission_display_name(&display));
129 }
130
131 None
132 }
133
134 fn file_chooser_entry_id(&self) -> Option<EntryId> {
135 Some(EntryId::EditIntermissionImage(IntermKind::PowerOff))
136 }
137}
138
139pub struct IntermissionShare;
141
142impl SettingKind for IntermissionShare {
143 fn identity(&self) -> SettingIdentity {
144 SettingIdentity::IntermissionShare
145 }
146
147 fn label(&self, _settings: &Settings) -> String {
148 fl!("settings-intermission-share-screen")
149 }
150
151 fn fetch(&self, settings: &Settings) -> SettingData {
152 fetch_intermission(IntermKind::Share, settings)
153 }
154
155 fn handle(&self, evt: &Event, settings: &mut Settings, _bus: &mut Bus) -> Option<String> {
156 if let Event::Select(EntryId::SetIntermission(IntermKind::Share, ref display)) = evt {
157 settings.intermissions[IntermKind::Share] = display.clone();
158 return Some(intermission_display_name(display));
159 }
160
161 if let Event::FileChooserClosed(Some(ref path)) = evt {
162 let display = IntermissionDisplay::Image(path.clone());
163 settings.intermissions[IntermKind::Share] = display.clone();
164 return Some(intermission_display_name(&display));
165 }
166
167 None
168 }
169
170 fn file_chooser_entry_id(&self) -> Option<EntryId> {
171 Some(EntryId::EditIntermissionImage(IntermKind::Share))
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178 use crate::settings::{IntermissionDisplay, Settings};
179 use crate::view::{Bus, EntryId, Event};
180 use std::collections::VecDeque;
181 use std::path::PathBuf;
182
183 mod intermission_suspend {
184 use super::*;
185
186 #[test]
187 fn handle_set_intermission_updates_settings() {
188 let setting = IntermissionSuspend;
189 let mut settings = Settings::default();
190 let mut bus: Bus = VecDeque::new();
191 let event = Event::Select(EntryId::SetIntermission(
192 IntermKind::Suspend,
193 IntermissionDisplay::Cover,
194 ));
195
196 let result = setting.handle(&event, &mut settings, &mut bus);
197
198 assert!(result.is_some());
199 assert_eq!(
200 settings.intermissions[IntermKind::Suspend],
201 IntermissionDisplay::Cover
202 );
203 }
204
205 #[test]
206 fn handle_file_chooser_closed_updates_settings() {
207 let setting = IntermissionSuspend;
208 let mut settings = Settings::default();
209 let mut bus: Bus = VecDeque::new();
210 let path = PathBuf::from("/selected/image.jpg");
211 let event = Event::FileChooserClosed(Some(path));
212
213 let result = setting.handle(&event, &mut settings, &mut bus);
214
215 assert!(result.is_some());
216 assert_eq!(
217 settings.intermissions[IntermKind::Suspend],
218 IntermissionDisplay::Image(PathBuf::from("/selected/image.jpg"))
219 );
220 }
221
222 #[test]
223 fn handle_returns_none_for_wrong_kind() {
224 let setting = IntermissionSuspend;
225 let mut settings = Settings::default();
226 let mut bus: Bus = VecDeque::new();
227 let event = Event::Select(EntryId::SetIntermission(
228 IntermKind::PowerOff,
229 IntermissionDisplay::Cover,
230 ));
231
232 let result = setting.handle(&event, &mut settings, &mut bus);
233
234 assert!(result.is_none());
235 }
236
237 #[test]
238 fn handle_returns_none_for_cancelled_file_chooser() {
239 let setting = IntermissionSuspend;
240 let mut settings = Settings::default();
241 let mut bus: Bus = VecDeque::new();
242
243 let result = setting.handle(&Event::FileChooserClosed(None), &mut settings, &mut bus);
244
245 assert!(result.is_none());
246 }
247 }
248
249 mod intermission_power_off {
250 use super::*;
251
252 #[test]
253 fn handle_set_intermission_updates_settings() {
254 let setting = IntermissionPowerOff;
255 let mut settings = Settings::default();
256 let mut bus: Bus = VecDeque::new();
257 let event = Event::Select(EntryId::SetIntermission(
258 IntermKind::PowerOff,
259 IntermissionDisplay::Cover,
260 ));
261
262 let result = setting.handle(&event, &mut settings, &mut bus);
263
264 assert!(result.is_some());
265 assert_eq!(
266 settings.intermissions[IntermKind::PowerOff],
267 IntermissionDisplay::Cover
268 );
269 }
270
271 #[test]
272 fn handle_file_chooser_closed_updates_settings() {
273 let setting = IntermissionPowerOff;
274 let mut settings = Settings::default();
275 let mut bus: Bus = VecDeque::new();
276 let path = PathBuf::from("/selected/poweroff.png");
277 let event = Event::FileChooserClosed(Some(path));
278
279 let result = setting.handle(&event, &mut settings, &mut bus);
280
281 assert!(result.is_some());
282 assert_eq!(
283 settings.intermissions[IntermKind::PowerOff],
284 IntermissionDisplay::Image(PathBuf::from("/selected/poweroff.png"))
285 );
286 }
287
288 #[test]
289 fn handle_returns_none_for_wrong_kind() {
290 let setting = IntermissionPowerOff;
291 let mut settings = Settings::default();
292 let mut bus: Bus = VecDeque::new();
293 let event = Event::Select(EntryId::SetIntermission(
294 IntermKind::Suspend,
295 IntermissionDisplay::Logo,
296 ));
297
298 let result = setting.handle(&event, &mut settings, &mut bus);
299
300 assert!(result.is_none());
301 }
302
303 #[test]
304 fn handle_returns_none_for_cancelled_file_chooser() {
305 let setting = IntermissionPowerOff;
306 let mut settings = Settings::default();
307 let mut bus: Bus = VecDeque::new();
308
309 let result = setting.handle(&Event::FileChooserClosed(None), &mut settings, &mut bus);
310
311 assert!(result.is_none());
312 }
313 }
314
315 mod intermission_share {
316 use super::*;
317
318 #[test]
319 fn handle_set_intermission_updates_settings() {
320 let setting = IntermissionShare;
321 let mut settings = Settings::default();
322 let mut bus: Bus = VecDeque::new();
323 let event = Event::Select(EntryId::SetIntermission(
324 IntermKind::Share,
325 IntermissionDisplay::Cover,
326 ));
327
328 let result = setting.handle(&event, &mut settings, &mut bus);
329
330 assert!(result.is_some());
331 assert_eq!(
332 settings.intermissions[IntermKind::Share],
333 IntermissionDisplay::Cover
334 );
335 }
336
337 #[test]
338 fn handle_file_chooser_closed_updates_settings() {
339 let setting = IntermissionShare;
340 let mut settings = Settings::default();
341 let mut bus: Bus = VecDeque::new();
342 let path = PathBuf::from("/selected/share.jpg");
343 let event = Event::FileChooserClosed(Some(path));
344
345 let result = setting.handle(&event, &mut settings, &mut bus);
346
347 assert!(result.is_some());
348 assert_eq!(
349 settings.intermissions[IntermKind::Share],
350 IntermissionDisplay::Image(PathBuf::from("/selected/share.jpg"))
351 );
352 }
353
354 #[test]
355 fn handle_returns_none_for_wrong_kind() {
356 let setting = IntermissionShare;
357 let mut settings = Settings::default();
358 let mut bus: Bus = VecDeque::new();
359 let event = Event::Select(EntryId::SetIntermission(
360 IntermKind::PowerOff,
361 IntermissionDisplay::Cover,
362 ));
363
364 let result = setting.handle(&event, &mut settings, &mut bus);
365
366 assert!(result.is_none());
367 }
368
369 #[test]
370 fn handle_returns_none_for_cancelled_file_chooser() {
371 let setting = IntermissionShare;
372 let mut settings = Settings::default();
373 let mut bus: Bus = VecDeque::new();
374
375 let result = setting.handle(&Event::FileChooserClosed(None), &mut settings, &mut bus);
376
377 assert!(result.is_none());
378 }
379 }
380}