1use gio;
6use glib::object::Cast;
7use glib::object::IsA;
8use glib::signal::connect_raw;
9use glib::signal::SignalHandlerId;
10use glib::translate::*;
11use glib::GString;
12use glib_sys;
13use gtk_sys;
14use std::boxed::Box as Box_;
15use std::fmt;
16use std::mem::transmute;
17use std::ptr;
18use CssSection;
19use Error;
20use StyleProvider;
21
22glib_wrapper! {
23 pub struct CssProvider(Object<gtk_sys::GtkCssProvider, gtk_sys::GtkCssProviderClass, CssProviderClass>) @implements StyleProvider;
24
25 match fn {
26 get_type => || gtk_sys::gtk_css_provider_get_type(),
27 }
28}
29
30impl CssProvider {
31 pub fn new() -> CssProvider {
32 assert_initialized_main_thread!();
33 unsafe { from_glib_full(gtk_sys::gtk_css_provider_new()) }
34 }
35
36 #[cfg_attr(feature = "v3_24", deprecated)]
37 pub fn get_default() -> Option<CssProvider> {
38 assert_initialized_main_thread!();
39 unsafe { from_glib_none(gtk_sys::gtk_css_provider_get_default()) }
40 }
41
42 pub fn get_named(name: &str, variant: Option<&str>) -> Option<CssProvider> {
43 assert_initialized_main_thread!();
44 unsafe {
45 from_glib_none(gtk_sys::gtk_css_provider_get_named(
46 name.to_glib_none().0,
47 variant.to_glib_none().0,
48 ))
49 }
50 }
51}
52
53impl Default for CssProvider {
54 fn default() -> Self {
55 Self::new()
56 }
57}
58
59pub const NONE_CSS_PROVIDER: Option<&CssProvider> = None;
60
61pub trait CssProviderExt: 'static {
62 fn load_from_data(&self, data: &[u8]) -> Result<(), Error>;
63
64 fn load_from_file<P: IsA<gio::File>>(&self, file: &P) -> Result<(), Error>;
65
66 fn load_from_path(&self, path: &str) -> Result<(), Error>;
67
68 #[cfg(any(feature = "v3_16", feature = "dox"))]
69 fn load_from_resource(&self, resource_path: &str);
70
71 fn to_string(&self) -> GString;
72
73 fn connect_parsing_error<F: Fn(&Self, &CssSection, &Error) + 'static>(
74 &self,
75 f: F,
76 ) -> SignalHandlerId;
77}
78
79impl<O: IsA<CssProvider>> CssProviderExt for O {
80 fn load_from_data(&self, data: &[u8]) -> Result<(), Error> {
81 let length = data.len() as isize;
82 unsafe {
83 let mut error = ptr::null_mut();
84 let _ = gtk_sys::gtk_css_provider_load_from_data(
85 self.as_ref().to_glib_none().0,
86 data.to_glib_none().0,
87 length,
88 &mut error,
89 );
90 if error.is_null() {
91 Ok(())
92 } else {
93 Err(from_glib_full(error))
94 }
95 }
96 }
97
98 fn load_from_file<P: IsA<gio::File>>(&self, file: &P) -> Result<(), Error> {
99 unsafe {
100 let mut error = ptr::null_mut();
101 let _ = gtk_sys::gtk_css_provider_load_from_file(
102 self.as_ref().to_glib_none().0,
103 file.as_ref().to_glib_none().0,
104 &mut error,
105 );
106 if error.is_null() {
107 Ok(())
108 } else {
109 Err(from_glib_full(error))
110 }
111 }
112 }
113
114 fn load_from_path(&self, path: &str) -> Result<(), Error> {
115 unsafe {
116 let mut error = ptr::null_mut();
117 let _ = gtk_sys::gtk_css_provider_load_from_path(
118 self.as_ref().to_glib_none().0,
119 path.to_glib_none().0,
120 &mut error,
121 );
122 if error.is_null() {
123 Ok(())
124 } else {
125 Err(from_glib_full(error))
126 }
127 }
128 }
129
130 #[cfg(any(feature = "v3_16", feature = "dox"))]
131 fn load_from_resource(&self, resource_path: &str) {
132 unsafe {
133 gtk_sys::gtk_css_provider_load_from_resource(
134 self.as_ref().to_glib_none().0,
135 resource_path.to_glib_none().0,
136 );
137 }
138 }
139
140 fn to_string(&self) -> GString {
141 unsafe {
142 from_glib_full(gtk_sys::gtk_css_provider_to_string(
143 self.as_ref().to_glib_none().0,
144 ))
145 }
146 }
147
148 fn connect_parsing_error<F: Fn(&Self, &CssSection, &Error) + 'static>(
149 &self,
150 f: F,
151 ) -> SignalHandlerId {
152 unsafe extern "C" fn parsing_error_trampoline<P, F: Fn(&P, &CssSection, &Error) + 'static>(
153 this: *mut gtk_sys::GtkCssProvider,
154 section: *mut gtk_sys::GtkCssSection,
155 error: *mut glib_sys::GError,
156 f: glib_sys::gpointer,
157 ) where
158 P: IsA<CssProvider>,
159 {
160 let f: &F = &*(f as *const F);
161 f(
162 &CssProvider::from_glib_borrow(this).unsafe_cast(),
163 &from_glib_borrow(section),
164 &from_glib_borrow(error),
165 )
166 }
167 unsafe {
168 let f: Box_<F> = Box_::new(f);
169 connect_raw(
170 self.as_ptr() as *mut _,
171 b"parsing-error\0".as_ptr() as *const _,
172 Some(transmute(parsing_error_trampoline::<Self, F> as usize)),
173 Box_::into_raw(f),
174 )
175 }
176 }
177}
178
179impl fmt::Display for CssProvider {
180 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
181 write!(f, "CssProvider")
182 }
183}