fractal/session/view/content/room_history/message_row/
file.rs1use adw::subclass::prelude::*;
2use gettextrs::gettext;
3use gtk::{CompositeTemplate, glib, prelude::*};
4
5use super::ContentFormat;
6use crate::gettext_f;
7
8mod imp {
9 use std::cell::{Cell, RefCell};
10
11 use glib::subclass::InitializingObject;
12
13 use super::*;
14
15 #[derive(Debug, Default, CompositeTemplate, glib::Properties)]
16 #[template(
17 resource = "/org/gnome/Fractal/ui/session/view/content/room_history/message_row/file.ui"
18 )]
19 #[properties(wrapper_type = super::MessageFile)]
20 pub struct MessageFile {
21 #[property(get, set = Self::set_filename, explicit_notify, nullable)]
23 filename: RefCell<Option<String>>,
24 #[property(get, set = Self::set_compact, explicit_notify)]
26 compact: Cell<bool>,
27 }
28
29 #[glib::object_subclass]
30 impl ObjectSubclass for MessageFile {
31 const NAME: &'static str = "ContentMessageFile";
32 type Type = super::MessageFile;
33 type ParentType = adw::Bin;
34
35 fn class_init(klass: &mut Self::Class) {
36 Self::bind_template(klass);
37
38 klass.set_accessible_role(gtk::AccessibleRole::Group);
39 }
40
41 fn instance_init(obj: &InitializingObject<Self>) {
42 obj.init_template();
43 }
44 }
45
46 #[glib::derived_properties]
47 impl ObjectImpl for MessageFile {}
48
49 impl WidgetImpl for MessageFile {}
50 impl BinImpl for MessageFile {}
51
52 impl MessageFile {
53 fn set_filename(&self, filename: Option<String>) {
55 let filename = filename.filter(|s| !s.is_empty());
56
57 if filename == *self.filename.borrow() {
58 return;
59 }
60
61 let obj = self.obj();
62 let accessible_label = if let Some(filename) = &filename {
63 gettext_f("File: {filename}", &[("filename", filename)])
64 } else {
65 gettext("File")
66 };
67 obj.update_property(&[gtk::accessible::Property::Label(&accessible_label)]);
68
69 self.filename.replace(filename);
70 obj.notify_filename();
71 }
72
73 fn set_compact(&self, compact: bool) {
75 if self.compact.get() == compact {
76 return;
77 }
78
79 self.compact.set(compact);
80 self.obj().notify_compact();
81 }
82 }
83}
84
85glib::wrapper! {
86 pub struct MessageFile(ObjectSubclass<imp::MessageFile>)
88 @extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
89}
90
91impl MessageFile {
92 pub fn new() -> Self {
93 glib::Object::new()
94 }
95
96 pub(crate) fn set_format(&self, format: ContentFormat) {
98 self.set_compact(matches!(
99 format,
100 ContentFormat::Compact | ContentFormat::Ellipsized
101 ));
102 }
103}
104
105impl Default for MessageFile {
106 fn default() -> Self {
107 Self::new()
108 }
109}