@@ -4,7 +4,7 @@ extern crate thiserror;
4
4
mod iter;
5
5
6
6
pub use self :: iter:: Iter ;
7
-
7
+ use std :: borrow :: Cow ;
8
8
use std:: collections:: BTreeMap ;
9
9
use std:: path:: { Path , PathBuf } ;
10
10
@@ -27,38 +27,52 @@ pub struct DesktopEntry<'a> {
27
27
pub appid : & ' a str ,
28
28
pub groups : Groups < ' a > ,
29
29
pub path : & ' a Path ,
30
+ pub ubuntu_gettext_domain : Option < & ' a str > ,
30
31
}
31
32
32
33
impl < ' a > DesktopEntry < ' a > {
33
- pub fn action_entry ( & self , action : & str , key : & str , locale : Option < & str > ) -> Option < & ' a str > {
34
+ pub fn action_entry ( & ' a self , action : & str , key : & str ) -> Option < & ' a str > {
35
+ let group = self
36
+ . groups
37
+ . get ( [ "Desktop Action " , action] . concat ( ) . as_str ( ) ) ;
38
+
39
+ Self :: entry ( group, key)
40
+ }
41
+
42
+ pub fn action_entry_localized (
43
+ & ' a self ,
44
+ action : & str ,
45
+ key : & str ,
46
+ locale : Option < & str > ,
47
+ ) -> Option < Cow < ' a , str > > {
34
48
let group = self
35
49
. groups
36
50
. get ( [ "Desktop Action " , action] . concat ( ) . as_str ( ) ) ;
37
51
38
- Self :: localized_entry ( group, key, locale)
52
+ Self :: localized_entry ( self . ubuntu_gettext_domain , group, key, locale)
39
53
}
40
54
41
- pub fn action_exec ( & self , action : & str ) -> Option < & ' a str > {
42
- self . action_entry ( action, "Exec" , None )
55
+ pub fn action_exec ( & ' a self , action : & str ) -> Option < & ' a str > {
56
+ self . action_entry ( action, "Exec" )
43
57
}
44
58
45
- pub fn action_name ( & self , action : & str , locale : Option < & str > ) -> Option < & ' a str > {
46
- self . action_entry ( action, "Name" , locale)
59
+ pub fn action_name ( & ' a self , action : & str , locale : Option < & str > ) -> Option < Cow < ' a , str > > {
60
+ self . action_entry_localized ( action, "Name" , locale)
47
61
}
48
62
49
- pub fn actions ( & self ) -> Option < & ' a str > {
50
- self . desktop_entry ( "Actions" , None )
63
+ pub fn actions ( & ' a self ) -> Option < & ' a str > {
64
+ self . desktop_entry ( "Actions" )
51
65
}
52
66
53
- pub fn categories ( & self ) -> Option < & ' a str > {
54
- self . desktop_entry ( "Categories" , None )
67
+ pub fn categories ( & ' a self ) -> Option < & ' a str > {
68
+ self . desktop_entry ( "Categories" )
55
69
}
56
70
57
- pub fn comment ( & self , locale : Option < & str > ) -> Option < & ' a str > {
58
- self . desktop_entry ( "Comment" , locale)
71
+ pub fn comment ( & ' a self , locale : Option < & str > ) -> Option < Cow < ' a , str > > {
72
+ self . desktop_entry_localized ( "Comment" , locale)
59
73
}
60
74
61
- pub fn decode < ' b > ( path : & ' b Path , input : & ' b str ) -> Result < DesktopEntry < ' b > , DecodeError > {
75
+ pub fn decode ( path : & ' a Path , input : & ' a str ) -> Result < DesktopEntry < ' a > , DecodeError > {
62
76
let appid = path
63
77
. file_stem ( )
64
78
. ok_or ( DecodeError :: AppID ) ?
@@ -69,6 +83,8 @@ impl<'a> DesktopEntry<'a> {
69
83
70
84
let mut active_group = "" ;
71
85
86
+ let mut ubuntu_gettext_domain = None ;
87
+
72
88
for mut line in input. lines ( ) {
73
89
line = line. trim ( ) ;
74
90
if line. is_empty ( ) || line. starts_with ( '#' ) {
@@ -101,6 +117,11 @@ impl<'a> DesktopEntry<'a> {
101
117
}
102
118
}
103
119
120
+ if key == "X-Ubuntu-Gettext-Domain" {
121
+ ubuntu_gettext_domain = Some ( value) ;
122
+ continue ;
123
+ }
124
+
104
125
groups
105
126
. entry ( active_group)
106
127
. or_insert_with ( Default :: default)
@@ -114,74 +135,93 @@ impl<'a> DesktopEntry<'a> {
114
135
appid,
115
136
groups,
116
137
path,
138
+ ubuntu_gettext_domain,
117
139
} )
118
140
}
119
141
120
- pub fn desktop_entry ( & self , key : & str , locale : Option < & str > ) -> Option < & ' a str > {
121
- Self :: localized_entry ( self . groups . get ( "Desktop Entry" ) , key, locale)
142
+ pub fn desktop_entry ( & ' a self , key : & str ) -> Option < & ' a str > {
143
+ Self :: entry ( self . groups . get ( "Desktop Entry" ) , key)
144
+ }
145
+
146
+ pub fn desktop_entry_localized (
147
+ & ' a self ,
148
+ key : & str ,
149
+ locale : Option < & str > ,
150
+ ) -> Option < Cow < ' a , str > > {
151
+ Self :: localized_entry (
152
+ self . ubuntu_gettext_domain ,
153
+ self . groups . get ( "Desktop Entry" ) ,
154
+ key,
155
+ locale,
156
+ )
122
157
}
123
158
124
- pub fn exec ( & self ) -> Option < & ' a str > {
125
- self . desktop_entry ( "Exec" , None )
159
+ pub fn exec ( & ' a self ) -> Option < & ' a str > {
160
+ self . desktop_entry ( "Exec" )
126
161
}
127
162
128
- pub fn icon ( & self ) -> Option < & ' a str > {
129
- self . desktop_entry ( "Icon" , None )
163
+ pub fn icon ( & ' a self ) -> Option < & ' a str > {
164
+ self . desktop_entry ( "Icon" )
130
165
}
131
166
132
- pub fn id ( & self ) -> & str {
167
+ pub fn id ( & ' a self ) -> & str {
133
168
self . appid
134
169
}
135
170
136
- pub fn keywords ( & self ) -> Option < & ' a str > {
137
- self . desktop_entry ( "Keywords" , None )
171
+ pub fn keywords ( & ' a self ) -> Option < Cow < ' a , str > > {
172
+ self . desktop_entry_localized ( "Keywords" , None )
138
173
}
139
174
140
- pub fn mime_type ( & self ) -> Option < & ' a str > {
141
- self . desktop_entry ( "MimeType" , None )
175
+ pub fn mime_type ( & ' a self ) -> Option < & ' a str > {
176
+ self . desktop_entry ( "MimeType" )
142
177
}
143
178
144
- pub fn name ( & self , locale : Option < & str > ) -> Option < & ' a str > {
145
- self . desktop_entry ( "Name" , locale)
179
+ pub fn name ( & ' a self , locale : Option < & str > ) -> Option < Cow < ' a , str > > {
180
+ self . desktop_entry_localized ( "Name" , locale)
146
181
}
147
182
148
- pub fn no_display ( & self ) -> bool {
183
+ pub fn no_display ( & ' a self ) -> bool {
149
184
self . desktop_entry_bool ( "NoDisplay" )
150
185
}
151
186
152
- pub fn only_show_in ( & self ) -> Option < & ' a str > {
153
- self . desktop_entry ( "OnlyShowIn" , None )
187
+ pub fn only_show_in ( & ' a self ) -> Option < & ' a str > {
188
+ self . desktop_entry ( "OnlyShowIn" )
154
189
}
155
190
156
- pub fn prefers_non_default_gpu ( & self ) -> bool {
191
+ pub fn prefers_non_default_gpu ( & ' a self ) -> bool {
157
192
self . desktop_entry_bool ( "PrefersNonDefaultGPU" )
158
193
}
159
194
160
- pub fn startup_notify ( & self ) -> bool {
195
+ pub fn startup_notify ( & ' a self ) -> bool {
161
196
self . desktop_entry_bool ( "StartupNotify" )
162
197
}
163
198
164
- pub fn terminal ( & self ) -> bool {
199
+ pub fn terminal ( & ' a self ) -> bool {
165
200
self . desktop_entry_bool ( "Terminal" )
166
201
}
167
202
168
- pub fn type_ ( & self ) -> Option < & ' a str > {
169
- self . desktop_entry ( "Type" , None )
203
+ pub fn type_ ( & ' a self ) -> Option < & ' a str > {
204
+ self . desktop_entry ( "Type" )
205
+ }
206
+
207
+ fn desktop_entry_bool ( & ' a self , key : & str ) -> bool {
208
+ self . desktop_entry ( key) . map_or ( false , |v| v == "true" )
170
209
}
171
210
172
- fn desktop_entry_bool ( & self , key : & str ) -> bool {
173
- self . desktop_entry ( key , None ) . map_or ( false , |v| v == "true" )
211
+ fn entry ( group : Option < & ' a KeyMap < ' a > > , key : & str ) -> Option < & ' a str > {
212
+ group . and_then ( |group| group . get ( key ) ) . map ( |key| key . 0 )
174
213
}
175
214
176
215
fn localized_entry (
177
- group : Option < & KeyMap < ' a > > ,
216
+ ubuntu_gettext_domain : Option < & ' a str > ,
217
+ group : Option < & ' a KeyMap < ' a > > ,
178
218
key : & str ,
179
219
locale : Option < & str > ,
180
- ) -> Option < & ' a str > {
220
+ ) -> Option < Cow < ' a , str > > {
181
221
group. and_then ( |group| group. get ( key) ) . and_then ( |key| {
182
222
locale
183
- . and_then ( |locale| match key. 1 . get ( locale) {
184
- Some ( value) => Some ( * value) ,
223
+ . and_then ( |locale| match key. 1 . get ( locale) . cloned ( ) {
224
+ Some ( value) => Some ( value) ,
185
225
None => {
186
226
if let Some ( pos) = locale. find ( '_' ) {
187
227
key. 1 . get ( & locale[ ..pos] ) . cloned ( )
@@ -190,7 +230,9 @@ impl<'a> DesktopEntry<'a> {
190
230
}
191
231
}
192
232
} )
193
- . or ( Some ( key. 0 ) )
233
+ . map ( Cow :: Borrowed )
234
+ . or_else ( || ubuntu_gettext_domain. map ( |domain| Cow :: Owned ( dgettext ( domain, key. 0 ) ) ) )
235
+ . or ( Some ( Cow :: Borrowed ( key. 0 ) ) )
194
236
} )
195
237
}
196
238
}
@@ -249,3 +291,9 @@ pub fn default_paths() -> Vec<(PathSource, PathBuf)> {
249
291
( PathSource :: System , PathBuf :: from( "/usr/share/applications" ) ) ,
250
292
]
251
293
}
294
+
295
+ fn dgettext ( domain : & str , message : & str ) -> String {
296
+ use gettextrs:: { setlocale, LocaleCategory } ;
297
+ setlocale ( LocaleCategory :: LcAll , "" ) ;
298
+ gettextrs:: dgettext ( domain, message)
299
+ }
0 commit comments