Codebase list lightdm-gtk-greeter-settings / ca8c3ef
Merging 2.0 branch Andrew P. 9 years ago
22 changed file(s) with 5248 addition(s) and 2813 deletion(s). Raw diff Collapse all Expand all
00 <?xml version="1.0" encoding="UTF-8"?>
11 <!-- Generated with glade 3.18.3 -->
22 <interface>
3 <requires lib="gtk+" version="3.4"/>
3 <requires lib="gtk+" version="3.8"/>
4 <requires lib="" version="3.8"/>
45 <requires lib="gtk_greeter_settings" version="1.0"/>
5 <object class="GtkFileFilter" id="greeter_default-user-image_path_dialog_filter">
6 <mime-types>
7 <mime-type>image/*</mime-type>
8 </mime-types>
9 </object>
10 <object class="GtkImage" id="greeter_default-user-image_path_dialog_preview">
11 <property name="visible">True</property>
12 <property name="can_focus">False</property>
13 <property name="yalign">0</property>
14 <property name="pixel_size">64</property>
15 <property name="icon_name">unknown</property>
16 <property name="icon_size">6</property>
17 </object>
186 <object class="GtkListStore" id="greeter_indicators_model">
197 <columns>
208 <!-- column-name name -->
219 <column type="gchararray"/>
2210 <!-- column-name tooltip -->
2311 <column type="gchararray"/>
24 <!-- column-name editable -->
25 <column type="gboolean"/>
2612 <!-- column-name has-state -->
2713 <column type="gboolean"/>
2814 <!-- column-name state -->
2915 <column type="gboolean"/>
16 <!-- column-name options -->
17 <column type="GObject"/>
18 <!-- column-name icon -->
19 <column type="gchararray"/>
20 <!-- column-name markup -->
21 <column type="gchararray"/>
3022 </columns>
31 <data>
32 <row>
33 <col id="0">~host</col>
34 <col id="1" translatable="yes" context="option|indicators">Host name</col>
35 <col id="2">False</col>
36 <col id="3">True</col>
37 <col id="4">False</col>
38 </row>
39 <row>
40 <col id="0">~clock</col>
41 <col id="1" translatable="yes" context="option|indicators">Clock</col>
42 <col id="2">False</col>
43 <col id="3">True</col>
44 <col id="4">False</col>
45 </row>
46 <row>
47 <col id="0">~layout</col>
48 <col id="1" translatable="yes" context="option|indicators">Layout indicator</col>
49 <col id="2">False</col>
50 <col id="3">True</col>
51 <col id="4">False</col>
52 </row>
53 <row>
54 <col id="0">~session</col>
55 <col id="1" translatable="yes" context="option|indicators">Sessions menu (xfce, unity, gnome etc.)</col>
56 <col id="2">False</col>
57 <col id="3">True</col>
58 <col id="4">False</col>
59 </row>
60 <row>
61 <col id="0">~language</col>
62 <col id="1" translatable="yes" context="option|indicators">Languages menu</col>
63 <col id="2">False</col>
64 <col id="3">True</col>
65 <col id="4">False</col>
66 </row>
67 <row>
68 <col id="0">~a11y</col>
69 <col id="1" translatable="yes" context="option|indicators">Accessibility menu</col>
70 <col id="2">False</col>
71 <col id="3">True</col>
72 <col id="4">False</col>
73 </row>
74 <row>
75 <col id="0">~power</col>
76 <col id="1" translatable="yes" context="option|indicators">Power menu</col>
77 <col id="2">False</col>
78 <col id="3">True</col>
79 <col id="4">False</col>
80 </row>
81 </data>
8223 </object>
8324 <object class="GtkAdjustment" id="greeter_position_x_adjustment">
8425 <property name="upper">10000</property>
9536 <property name="step_increment">1</property>
9637 <property name="page_increment">10</property>
9738 </object>
98 <object class="GtkListStore" id="greeter_xft-hintstyle_model">
99 <columns>
100 <!-- column-name value -->
101 <column type="gchararray"/>
102 <!-- column-name title -->
103 <column type="gchararray"/>
104 </columns>
105 <data>
106 <row>
107 <col id="0">hintnone</col>
108 <col id="1" translatable="yes" context="option|hintstyle">None</col>
109 </row>
110 <row>
111 <col id="0">hintslight</col>
112 <col id="1" translatable="yes" context="option|hintstyle">Slight</col>
113 </row>
114 <row>
115 <col id="0">hintmedium</col>
116 <col id="1" translatable="yes" context="option|hintstyle">Medium</col>
117 </row>
118 <row>
119 <col id="0">hintfull</col>
120 <col id="1" translatable="yes" context="option|hintstyle">Full</col>
121 </row>
122 </data>
123 </object>
124 <object class="GtkListStore" id="greeter_xft-rgba_model">
125 <columns>
126 <!-- column-name value -->
127 <column type="gchararray"/>
128 <!-- column-name title -->
129 <column type="gchararray"/>
130 </columns>
131 <data>
132 <row>
133 <col id="0">none</col>
134 <col id="1" translatable="yes" context="option|rgba">None</col>
135 </row>
136 <row>
137 <col id="0">rgb</col>
138 <col id="1" translatable="yes" context="option|rgba">RGB</col>
139 </row>
140 <row>
141 <col id="0">bgr</col>
142 <col id="1" translatable="yes" context="option|rgba">BGR</col>
143 </row>
144 <row>
145 <col id="0">vrgb</col>
146 <col id="1" translatable="yes" context="option|rgba">Vertical RGB</col>
147 </row>
148 <row>
149 <col id="0">vbgr</col>
150 <col id="1" translatable="yes" context="option|rgba">Vertical BGR</col>
151 </row>
152 </data>
153 </object>
154 <object class="GtkImage" id="icon_cancel">
155 <property name="visible">True</property>
156 <property name="can_focus">False</property>
157 <property name="icon_name">dialog-cancel</property>
158 </object>
15939 <object class="GtkImage" id="icon_close">
16040 <property name="visible">True</property>
16141 <property name="can_focus">False</property>
16242 <property name="icon_name">dialog-close</property>
163 </object>
164 <object class="GtkImage" id="icon_image">
165 <property name="visible">True</property>
166 <property name="can_focus">False</property>
167 <property name="icon_name">image</property>
168 </object>
169 <object class="GtkImage" id="icon_ok">
170 <property name="visible">True</property>
171 <property name="can_focus">False</property>
172 <property name="icon_name">dialog-ok</property>
173 </object>
174 <object class="GtkImage" id="icon_open">
175 <property name="visible">True</property>
176 <property name="can_focus">False</property>
177 <property name="icon_name">document-open</property>
178 </object>
179 <object class="GtkMenu" id="greeter_default-user-image_menu">
180 <property name="visible">True</property>
181 <property name="can_focus">False</property>
182 <child>
183 <object class="GtkImageMenuItem" id="greeter_default-user-image_icon_item">
184 <property name="label">Icon</property>
185 <property name="visible">True</property>
186 <property name="can_focus">False</property>
187 <property name="image">icon_image</property>
188 <property name="use_stock">False</property>
189 </object>
190 </child>
191 <child>
192 <object class="GtkImageMenuItem" id="greeter_default-user-image_path_item">
193 <property name="label">Path</property>
194 <property name="visible">True</property>
195 <property name="can_focus">False</property>
196 <property name="image">icon_open</property>
197 <property name="use_stock">False</property>
198 </object>
199 </child>
20043 </object>
20144 <object class="GtkImage" id="icon_reset">
20245 <property name="visible">True</property>
24790 <property name="row_spacing">8</property>
24891 <property name="column_spacing">12</property>
24992 <child>
250 <object class="GtkLabel" id="greeter_gtk-theme_label">
251 <property name="visible">True</property>
252 <property name="can_focus">False</property>
93 <object class="GtkFontButton" id="greeter_font-name_value">
94 <property name="visible">True</property>
95 <property name="can_focus">False</property>
96 <property name="receives_default">True</property>
25397 <property name="halign">start</property>
254 <property name="hexpand">True</property>
255 <property name="label" translatable="yes" context="option|gtk-theme">Theme</property>
256 <attributes>
257 <attribute name="weight" value="semibold"/>
258 </attributes>
259 </object>
260 <packing>
261 <property name="left_attach">0</property>
262 <property name="top_attach">0</property>
263 </packing>
264 </child>
265 <child>
266 <object class="GtkLabel" id="greeter_icon-theme-name_label">
267 <property name="visible">True</property>
268 <property name="can_focus">False</property>
269 <property name="halign">start</property>
270 <property name="hexpand">True</property>
271 <property name="label" translatable="yes" context="option|icons-theme">Icons</property>
272 <attributes>
273 <attribute name="weight" value="semibold"/>
274 </attributes>
275 </object>
276 <packing>
277 <property name="left_attach">0</property>
278 <property name="top_attach">1</property>
279 </packing>
280 </child>
281 <child>
282 <object class="GtkLabel" id="greeter_font-name_label">
283 <property name="visible">True</property>
284 <property name="can_focus">False</property>
285 <property name="halign">start</property>
286 <property name="hexpand">True</property>
287 <property name="label" translatable="yes" context="option|font">Font</property>
288 <attributes>
289 <attribute name="weight" value="semibold"/>
290 </attributes>
291 </object>
292 <packing>
293 <property name="left_attach">0</property>
294 <property name="top_attach">2</property>
295 </packing>
296 </child>
297 <child>
298 <object class="GtkFontButton" id="greeter_font-name_value">
299 <property name="visible">True</property>
300 <property name="can_focus">False</property>
301 <property name="receives_default">True</property>
30298 <property name="font">Sans 12</property>
30399 </object>
304100 <packing>
321117 <object class="GtkSwitch" id="greeter_xft-antialias_value">
322118 <property name="visible">True</property>
323119 <property name="can_focus">False</property>
324 <property name="halign">end</property>
120 <property name="halign">start</property>
325121 </object>
326122 <packing>
327123 <property name="left_attach">1</property>
328124 <property name="top_attach">0</property>
125 </packing>
126 </child>
127 <child>
128 <object class="GtkBox" id="box8">
129 <property name="visible">True</property>
130 <property name="can_focus">False</property>
131 <property name="halign">start</property>
132 <property name="orientation">vertical</property>
133 <property name="spacing">8</property>
134 <child>
135 <object class="GtkComboBoxText" id="greeter_xft-rgba_value">
136 <property name="visible">True</property>
137 <property name="can_focus">False</property>
138 <property name="active">0</property>
139 <items>
140 <item id="none" translatable="yes" context="option|greeter|xft-rgba">None</item>
141 <item id="rgb" translatable="yes" context="option|greeter|xft-rgba">RGB</item>
142 <item id="bgr" translatable="yes" context="option|greeter|xft-rgba">BGR</item>
143 <item id="vrgb" translatable="yes" context="option|greeter|xft-rgba">Vertical RGB</item>
144 <item id="vbgr" translatable="yes" context="option|greeter|xft-rgba">Vertical BGR</item>
145 </items>
146 </object>
147 <packing>
148 <property name="expand">False</property>
149 <property name="fill">True</property>
150 <property name="position">0</property>
151 </packing>
152 </child>
153 <child>
154 <object class="GtkComboBoxText" id="greeter_xft-hintstyle_value">
155 <property name="visible">True</property>
156 <property name="can_focus">False</property>
157 <property name="active">0</property>
158 <items>
159 <item id="hintnone" translatable="yes" context="option|greeter|xft-hintstyle">None</item>
160 <item id="hintslight" translatable="yes" context="option|greeter|xft-hintstyle">Slight</item>
161 <item id="hintmedium" translatable="yes" context="option|greeter|xft-hintstyle">Medium</item>
162 <item id="hintfull" translatable="yes" context="option|greeter|xft-hintstyle">Full</item>
163 </items>
164 </object>
165 <packing>
166 <property name="expand">False</property>
167 <property name="fill">True</property>
168 <property name="position">1</property>
169 </packing>
170 </child>
171 </object>
172 <packing>
173 <property name="left_attach">1</property>
174 <property name="top_attach">2</property>
175 <property name="height">2</property>
329176 </packing>
330177 </child>
331178 <child>
352199 </packing>
353200 </child>
354201 <child>
355 <object class="GtkComboBox" id="greeter_xft-rgba_value">
356 <property name="visible">True</property>
357 <property name="can_focus">False</property>
358 <property name="model">greeter_xft-rgba_model</property>
359 <property name="active">0</property>
360 <property name="id_column">0</property>
202 <object class="GtkEventBox" id="greeter_xft-antialias_label_holder">
203 <property name="visible">True</property>
204 <property name="can_focus">False</property>
361205 <child>
362 <object class="GtkCellRendererText" id="cellrenderertext1"/>
363 <attributes>
364 <attribute name="text">1</attribute>
365 </attributes>
206 <object class="GtkCheckButton" id="greeter_xft-antialias_use">
207 <property name="label" translatable="yes" context="option|greeter|xft-antialias">Antialias</property>
208 <property name="visible">True</property>
209 <property name="can_focus">False</property>
210 <property name="receives_default">False</property>
211 <property name="has_tooltip">True</property>
212 <property name="tooltip_text" translatable="yes">Enable this option to override system defaults</property>
213 <property name="margin_left">24</property>
214 <property name="hexpand">True</property>
215 <property name="xalign">0.5</property>
216 <property name="draw_indicator">True</property>
217 </object>
366218 </child>
367219 </object>
368220 <packing>
369 <property name="left_attach">1</property>
370 <property name="top_attach">2</property>
221 <property name="left_attach">0</property>
222 <property name="top_attach">0</property>
371223 </packing>
372224 </child>
373225 <child>
374 <object class="GtkCheckButton" id="greeter_xft-rgba_use">
375 <property name="label" translatable="yes" context="option|rgba">Subpixel rendering</property>
376 <property name="visible">True</property>
377 <property name="can_focus">False</property>
378 <property name="receives_default">False</property>
379 <property name="has_tooltip">True</property>
380 <property name="tooltip_text" translatable="yes">Enable this option to override system defaults</property>
381 <property name="margin_left">24</property>
382 <property name="hexpand">True</property>
383 <property name="xalign">0</property>
384 <property name="draw_indicator">True</property>
226 <object class="GtkEventBox" id="greeter_xft-dpi_label_holder">
227 <property name="visible">True</property>
228 <property name="can_focus">False</property>
229 <child>
230 <object class="GtkCheckButton" id="greeter_xft-dpi_use">
231 <property name="label" translatable="yes" context="option|greeter|xft-dpi">DPI</property>
232 <property name="visible">True</property>
233 <property name="can_focus">False</property>
234 <property name="receives_default">False</property>
235 <property name="has_tooltip">True</property>
236 <property name="tooltip_text" translatable="yes">Enable this option to override system defaults</property>
237 <property name="margin_left">24</property>
238 <property name="hexpand">True</property>
239 <property name="xalign">0.5</property>
240 <property name="draw_indicator">True</property>
241 </object>
242 </child>
243 </object>
244 <packing>
245 <property name="left_attach">0</property>
246 <property name="top_attach">1</property>
247 </packing>
248 </child>
249 <child>
250 <object class="GtkEventBox" id="greeter_xft-rgba_label_holder">
251 <property name="visible">True</property>
252 <property name="can_focus">False</property>
253 <child>
254 <object class="GtkCheckButton" id="greeter_xft-rgba_use">
255 <property name="label" translatable="yes" context="option|greeter|xft-rgba">Subpixel rendering</property>
256 <property name="visible">True</property>
257 <property name="can_focus">False</property>
258 <property name="receives_default">False</property>
259 <property name="has_tooltip">True</property>
260 <property name="tooltip_text" translatable="yes">Enable this option to override system defaults</property>
261 <property name="margin_left">24</property>
262 <property name="hexpand">True</property>
263 <property name="xalign">0.5</property>
264 <property name="draw_indicator">True</property>
265 </object>
266 </child>
385267 </object>
386268 <packing>
387269 <property name="left_attach">0</property>
389271 </packing>
390272 </child>
391273 <child>
392 <object class="GtkCheckButton" id="greeter_xft-dpi_use">
393 <property name="label" translatable="yes" context="option|dpi">DPI</property>
394 <property name="visible">True</property>
395 <property name="can_focus">False</property>
396 <property name="receives_default">False</property>
397 <property name="has_tooltip">True</property>
398 <property name="tooltip_text" translatable="yes">Enable this option to override system defaults</property>
399 <property name="margin_left">24</property>
400 <property name="hexpand">True</property>
401 <property name="xalign">0</property>
402 <property name="draw_indicator">True</property>
403 </object>
404 <packing>
405 <property name="left_attach">0</property>
406 <property name="top_attach">1</property>
407 </packing>
408 </child>
409 <child>
410 <object class="GtkCheckButton" id="greeter_xft-antialias_use">
411 <property name="label" translatable="yes" context="option|antialias">Antialias</property>
412 <property name="visible">True</property>
413 <property name="can_focus">False</property>
414 <property name="receives_default">False</property>
415 <property name="has_tooltip">True</property>
416 <property name="tooltip_text" translatable="yes">Enable this option to override system defaults</property>
417 <property name="margin_left">24</property>
418 <property name="hexpand">True</property>
419 <property name="xalign">0</property>
420 <property name="draw_indicator">True</property>
421 </object>
422 <packing>
423 <property name="left_attach">0</property>
424 <property name="top_attach">0</property>
425 </packing>
426 </child>
427 <child>
428 <object class="GtkCheckButton" id="greeter_xft-hintstyle_use">
429 <property name="label" translatable="yes" context="option|hintstyle">Hinting</property>
430 <property name="visible">True</property>
431 <property name="can_focus">False</property>
432 <property name="receives_default">False</property>
433 <property name="has_tooltip">True</property>
434 <property name="tooltip_text" translatable="yes">Enable this option to override system defaults</property>
435 <property name="margin_left">24</property>
436 <property name="hexpand">True</property>
437 <property name="xalign">0</property>
438 <property name="draw_indicator">True</property>
274 <object class="GtkEventBox" id="greeter_xft-hintstyle_label_holder">
275 <property name="visible">True</property>
276 <property name="can_focus">False</property>
277 <child>
278 <object class="GtkCheckButton" id="greeter_xft-hintstyle_use">
279 <property name="label" translatable="yes" context="option|greeter|xft-hintstyle">Hinting</property>
280 <property name="visible">True</property>
281 <property name="can_focus">False</property>
282 <property name="receives_default">False</property>
283 <property name="has_tooltip">True</property>
284 <property name="tooltip_text" translatable="yes">Enable this option to override system defaults</property>
285 <property name="margin_left">24</property>
286 <property name="hexpand">True</property>
287 <property name="xalign">0.5</property>
288 <property name="draw_indicator">True</property>
289 </object>
290 </child>
439291 </object>
440292 <packing>
441293 <property name="left_attach">0</property>
442294 <property name="top_attach">3</property>
443295 </packing>
444296 </child>
445 <child>
446 <object class="GtkComboBox" id="greeter_xft-hintstyle_value">
447 <property name="visible">True</property>
448 <property name="can_focus">False</property>
449 <property name="model">greeter_xft-hintstyle_model</property>
450 <property name="active">0</property>
451 <property name="id_column">0</property>
452 <child>
453 <object class="GtkCellRendererText" id="cellrenderertext2"/>
454 <attributes>
455 <attribute name="text">1</attribute>
456 </attributes>
457 </child>
458 </object>
459 <packing>
460 <property name="left_attach">1</property>
461 <property name="top_attach">3</property>
462 </packing>
463 </child>
464297 </object>
465298 </child>
466299 <child type="label">
478311 </packing>
479312 </child>
480313 <child>
481 <object class="GtkRadioButton" id="greeter_background_image_choice">
482 <property name="label" translatable="yes" context="option|background">Image</property>
483 <property name="visible">True</property>
484 <property name="can_focus">False</property>
485 <property name="receives_default">False</property>
314 <object class="GtkFileChooserButton" id="greeter_background_image_value">
315 <property name="visible">True</property>
316 <property name="can_focus">False</property>
486317 <property name="halign">start</property>
487 <property name="margin_left">24</property>
488 <property name="hexpand">True</property>
489 <property name="xalign">0</property>
490 <property name="active">True</property>
491 <property name="draw_indicator">True</property>
492 </object>
493 <packing>
494 <property name="left_attach">0</property>
495 <property name="top_attach">5</property>
496 </packing>
497 </child>
498 <child>
499 <object class="GtkFileChooserButton" id="greeter_background_image_value">
500 <property name="visible">True</property>
501 <property name="can_focus">False</property>
502 <property name="filter">greeter_default-user-image_path_dialog_filter</property>
318 <property name="create_folders">False</property>
503319 </object>
504320 <packing>
505321 <property name="left_attach">1</property>
507323 </packing>
508324 </child>
509325 <child>
510 <object class="GtkRadioButton" id="greeter_background_color_choice">
511 <property name="label" translatable="yes" context="option|background">Color</property>
512 <property name="visible">True</property>
513 <property name="can_focus">False</property>
514 <property name="receives_default">False</property>
326 <object class="GtkColorButton" id="greeter_background_color_value">
327 <property name="visible">True</property>
328 <property name="can_focus">False</property>
329 <property name="receives_default">True</property>
515330 <property name="halign">start</property>
516 <property name="margin_left">24</property>
517 <property name="hexpand">True</property>
518 <property name="xalign">0</property>
519 <property name="active">True</property>
520 <property name="draw_indicator">True</property>
521 <property name="group">greeter_background_image_choice</property>
522 </object>
523 <packing>
524 <property name="left_attach">0</property>
525 <property name="top_attach">6</property>
526 </packing>
527 </child>
528 <child>
529 <object class="GtkColorButton" id="greeter_background_color_value">
530 <property name="visible">True</property>
531 <property name="can_focus">False</property>
532 <property name="receives_default">True</property>
533331 </object>
534332 <packing>
535333 <property name="left_attach">1</property>
537335 </packing>
538336 </child>
539337 <child>
540 <object class="GtkLabel" id="greeter_default-user-image_label">
541 <property name="visible">True</property>
542 <property name="can_focus">False</property>
543 <property name="halign">start</property>
544 <property name="valign">start</property>
545 <property name="label" translatable="yes" context="option|user-image">Default user image</property>
546 <attributes>
547 <attribute name="weight" value="semibold"/>
548 </attributes>
549 </object>
550 <packing>
551 <property name="left_attach">0</property>
552 <property name="top_attach">8</property>
553 </packing>
554 </child>
555 <child>
556338 <object class="GtkComboBoxText" id="greeter_theme-name_values">
557339 <property name="visible">True</property>
558340 <property name="can_focus">False</property>
341 <property name="hexpand">True</property>
559342 <property name="has_entry">True</property>
560343 <child internal-child="entry">
561344 <object class="GtkEntry" id="greeter_theme-name_value">
585368 </packing>
586369 </child>
587370 <child>
588 <object class="GtkToggleButton" id="greeter_default-user-image_button">
589 <property name="visible">True</property>
590 <property name="can_focus">False</property>
371 <object class="GtkBox" id="box5">
372 <property name="visible">True</property>
373 <property name="can_focus">False</property>
374 <child>
375 <object class="GtkEventBox" id="greeter_background_label_holder">
376 <property name="visible">True</property>
377 <property name="can_focus">False</property>
378 <child>
379 <object class="GtkBox" id="box13">
380 <property name="visible">True</property>
381 <property name="can_focus">False</property>
382 <child>
383 <object class="GtkLabel" id="greeter_background_label">
384 <property name="visible">True</property>
385 <property name="can_focus">False</property>
386 <property name="halign">start</property>
387 <property name="label" translatable="yes" context="option|greeter|background">Background</property>
388 <attributes>
389 <attribute name="weight" value="semibold"/>
390 </attributes>
391 </object>
392 <packing>
393 <property name="expand">False</property>
394 <property name="fill">True</property>
395 <property name="position">0</property>
396 </packing>
397 </child>
398 <child>
399 <object class="GtkImage" id="greeter_background_error">
400 <property name="can_focus">False</property>
401 <property name="yalign">0</property>
402 <property name="pixel_size">12</property>
403 <property name="icon_name">dialog-warning</property>
404 <property name="icon_size">1</property>
405 </object>
406 <packing>
407 <property name="expand">False</property>
408 <property name="fill">True</property>
409 <property name="position">1</property>
410 </packing>
411 </child>
412 </object>
413 </child>
414 </object>
415 <packing>
416 <property name="expand">False</property>
417 <property name="fill">True</property>
418 <property name="position">0</property>
419 </packing>
420 </child>
421 <child>
422 <object class="GtkLabel" id="multihead_label">
423 <property name="visible">True</property>
424 <property name="can_focus">True</property>
425 <property name="label" translatable="yes" context="option|multihead"> &lt;i&gt;(or use &lt;a href=""&gt;multihead setup&lt;/a&gt; for individual monitors)&lt;/i&gt;</property>
426 <property name="use_markup">True</property>
427 </object>
428 <packing>
429 <property name="expand">False</property>
430 <property name="fill">True</property>
431 <property name="position">1</property>
432 </packing>
433 </child>
434 </object>
435 <packing>
436 <property name="left_attach">0</property>
437 <property name="top_attach">4</property>
438 <property name="width">2</property>
439 </packing>
440 </child>
441 <child>
442 <object class="GtkSwitch" id="greeter_hide-user-image_value">
443 <property name="visible">True</property>
444 <property name="can_focus">True</property>
445 <property name="halign">start</property>
446 </object>
447 <packing>
448 <property name="left_attach">1</property>
449 <property name="top_attach">8</property>
450 </packing>
451 </child>
452 <child>
453 <object class="GtkMenuButton" id="greeter_default-user-image_button">
454 <property name="visible">True</property>
455 <property name="can_focus">True</property>
591456 <property name="receives_default">True</property>
592457 <property name="halign">start</property>
593 <property name="valign">start</property>
594458 <child>
595459 <object class="GtkImage" id="greeter_default-user-image_image">
460 <property name="width_request">64</property>
461 <property name="height_request">64</property>
596462 <property name="visible">True</property>
597463 <property name="can_focus">False</property>
598464 <property name="pixel_size">64</property>
602468 </object>
603469 <packing>
604470 <property name="left_attach">1</property>
605 <property name="top_attach">8</property>
606 </packing>
607 </child>
608 <child>
609 <object class="GtkCheckButton" id="greeter_user-background_value">
610 <property name="label" translatable="yes">Use user wallpaper if available</property>
611 <property name="visible">True</property>
612 <property name="can_focus">True</property>
471 <property name="top_attach">9</property>
472 </packing>
473 </child>
474 <child>
475 <object class="GtkRadioButton" id="greeter_background_color_choice">
476 <property name="label" translatable="yes" context="option|greeter|background">Color</property>
477 <property name="visible">True</property>
478 <property name="can_focus">False</property>
613479 <property name="receives_default">False</property>
480 <property name="halign">start</property>
614481 <property name="margin_left">24</property>
615 <property name="xalign">0</property>
616 <property name="image_position">right</property>
482 <property name="xalign">0.5</property>
483 <property name="active">True</property>
617484 <property name="draw_indicator">True</property>
618485 </object>
619486 <packing>
620487 <property name="left_attach">0</property>
621 <property name="top_attach">7</property>
622 <property name="width">2</property>
623 </packing>
624 </child>
625 <child>
626 <object class="GtkBox" id="box5">
627 <property name="visible">True</property>
628 <property name="can_focus">False</property>
629 <child>
630 <object class="GtkLabel" id="greeter_background_label">
488 <property name="top_attach">6</property>
489 </packing>
490 </child>
491 <child>
492 <object class="GtkRadioButton" id="greeter_background_image_choice">
493 <property name="label" translatable="yes" context="option|greeter|background">Image</property>
494 <property name="visible">True</property>
495 <property name="can_focus">False</property>
496 <property name="receives_default">False</property>
497 <property name="halign">start</property>
498 <property name="margin_left">24</property>
499 <property name="xalign">0.5</property>
500 <property name="active">True</property>
501 <property name="draw_indicator">True</property>
502 <property name="group">greeter_background_color_choice</property>
503 </object>
504 <packing>
505 <property name="left_attach">0</property>
506 <property name="top_attach">5</property>
507 </packing>
508 </child>
509 <child>
510 <object class="GtkEventBox" id="greeter_theme-name_label_holder">
511 <property name="visible">True</property>
512 <property name="can_focus">False</property>
513 <child>
514 <object class="GtkBox" id="greeter_theme-name_label_box">
515 <property name="visible">True</property>
516 <property name="can_focus">False</property>
517 <child>
518 <object class="GtkLabel" id="greeter_theme-name_label">
519 <property name="visible">True</property>
520 <property name="can_focus">False</property>
521 <property name="halign">start</property>
522 <property name="label" translatable="yes" context="option|greeter|theme-name">Theme</property>
523 <attributes>
524 <attribute name="weight" value="semibold"/>
525 </attributes>
526 </object>
527 <packing>
528 <property name="expand">False</property>
529 <property name="fill">True</property>
530 <property name="position">0</property>
531 </packing>
532 </child>
533 <child>
534 <object class="GtkImage" id="greeter_theme-name_error">
535 <property name="can_focus">False</property>
536 <property name="yalign">0</property>
537 <property name="pixel_size">12</property>
538 <property name="icon_name">dialog-warning</property>
539 <property name="icon_size">1</property>
540 </object>
541 <packing>
542 <property name="expand">False</property>
543 <property name="fill">True</property>
544 <property name="position">1</property>
545 </packing>
546 </child>
547 </object>
548 </child>
549 </object>
550 <packing>
551 <property name="left_attach">0</property>
552 <property name="top_attach">0</property>
553 </packing>
554 </child>
555 <child>
556 <object class="GtkEventBox" id="greeter_icon-theme-name_label_holder">
557 <property name="visible">True</property>
558 <property name="can_focus">False</property>
559 <child>
560 <object class="GtkBox" id="greeter_icon-theme-name_label_box">
561 <property name="visible">True</property>
562 <property name="can_focus">False</property>
563 <child>
564 <object class="GtkLabel" id="greeter_icon-theme-name_label">
565 <property name="visible">True</property>
566 <property name="can_focus">False</property>
567 <property name="halign">start</property>
568 <property name="label" translatable="yes" context="option|greeter|icon-theme-name">Icons</property>
569 <attributes>
570 <attribute name="weight" value="semibold"/>
571 </attributes>
572 </object>
573 <packing>
574 <property name="expand">False</property>
575 <property name="fill">True</property>
576 <property name="position">0</property>
577 </packing>
578 </child>
579 <child>
580 <object class="GtkImage" id="greeter_icon-theme-name_error">
581 <property name="can_focus">False</property>
582 <property name="yalign">0</property>
583 <property name="pixel_size">12</property>
584 <property name="icon_name">dialog-warning</property>
585 <property name="icon_size">1</property>
586 </object>
587 <packing>
588 <property name="expand">False</property>
589 <property name="fill">True</property>
590 <property name="position">1</property>
591 </packing>
592 </child>
593 </object>
594 </child>
595 </object>
596 <packing>
597 <property name="left_attach">0</property>
598 <property name="top_attach">1</property>
599 </packing>
600 </child>
601 <child>
602 <object class="GtkEventBox" id="greeter_font-name_label_holder">
603 <property name="visible">True</property>
604 <property name="can_focus">False</property>
605 <child>
606 <object class="GtkLabel" id="greeter_font-name_label">
631607 <property name="visible">True</property>
632608 <property name="can_focus">False</property>
633609 <property name="halign">start</property>
634 <property name="label" translatable="yes" context="option|background">Background</property>
610 <property name="label" translatable="yes" context="option|greeter|font-name">Font</property>
635611 <attributes>
636612 <attribute name="weight" value="semibold"/>
637613 </attributes>
638614 </object>
639 <packing>
640 <property name="expand">False</property>
641 <property name="fill">True</property>
642 <property name="position">0</property>
643 </packing>
644 </child>
645 <child>
646 <object class="GtkLabel" id="multihead_label">
615 </child>
616 </object>
617 <packing>
618 <property name="left_attach">0</property>
619 <property name="top_attach">2</property>
620 </packing>
621 </child>
622 <child>
623 <object class="GtkEventBox" id="greeter_hide-user-image_label_holder">
624 <property name="visible">True</property>
625 <property name="can_focus">False</property>
626 <child>
627 <object class="GtkLabel" id="greeter_hide-user-image_label">
628 <property name="visible">True</property>
629 <property name="can_focus">False</property>
630 <property name="halign">start</property>
631 <property name="label" translatable="yes" context="option|greeter|hide-user-image">User image</property>
632 <attributes>
633 <attribute name="weight" value="semibold"/>
634 </attributes>
635 </object>
636 </child>
637 </object>
638 <packing>
639 <property name="left_attach">0</property>
640 <property name="top_attach">8</property>
641 </packing>
642 </child>
643 <child>
644 <object class="GtkEventBox" id="greeter_default-user-image_label_holder">
645 <property name="visible">True</property>
646 <property name="can_focus">False</property>
647 <child>
648 <object class="GtkBox" id="greeter_default-user-image_label_box">
649 <property name="visible">True</property>
650 <property name="can_focus">False</property>
651 <property name="valign">start</property>
652 <child>
653 <object class="GtkLabel" id="greeter_default-user-image_label">
654 <property name="visible">True</property>
655 <property name="can_focus">False</property>
656 <property name="halign">start</property>
657 <property name="valign">start</property>
658 <property name="margin_left">24</property>
659 <property name="label" translatable="yes" context="option|greeter|default-user-image">Default user image</property>
660 </object>
661 <packing>
662 <property name="expand">False</property>
663 <property name="fill">True</property>
664 <property name="position">0</property>
665 </packing>
666 </child>
667 <child>
668 <object class="GtkImage" id="greeter_default-user-image_error">
669 <property name="can_focus">False</property>
670 <property name="yalign">0</property>
671 <property name="pixel_size">12</property>
672 <property name="icon_name">dialog-warning</property>
673 <property name="icon_size">1</property>
674 </object>
675 <packing>
676 <property name="expand">False</property>
677 <property name="fill">True</property>
678 <property name="position">1</property>
679 </packing>
680 </child>
681 </object>
682 </child>
683 </object>
684 <packing>
685 <property name="left_attach">0</property>
686 <property name="top_attach">9</property>
687 </packing>
688 </child>
689 <child>
690 <object class="GtkEventBox" id="greeter_user-background_label_holder">
691 <property name="visible">True</property>
692 <property name="can_focus">False</property>
693 <child>
694 <object class="GtkCheckButton" id="greeter_user-background_value">
695 <property name="label" translatable="yes" context="option|greeter|user-background">Use user wallpaper if available</property>
647696 <property name="visible">True</property>
648697 <property name="can_focus">True</property>
649 <property name="label" translatable="yes"> &lt;i&gt;(or you can use &lt;a href=""&gt;multihead setup for individual monitors&lt;/a&gt;)&lt;/i&gt;</property>
650 <property name="use_markup">True</property>
651 <property name="angle">0.029999999999999999</property>
652 </object>
653 <packing>
654 <property name="expand">False</property>
655 <property name="fill">True</property>
656 <property name="position">1</property>
657 </packing>
658 </child>
659 </object>
660 <packing>
661 <property name="left_attach">0</property>
662 <property name="top_attach">4</property>
698 <property name="receives_default">False</property>
699 <property name="margin_left">24</property>
700 <property name="xalign">0.5</property>
701 <property name="image_position">right</property>
702 <property name="draw_indicator">True</property>
703 </object>
704 </child>
705 </object>
706 <packing>
707 <property name="left_attach">0</property>
708 <property name="top_attach">7</property>
663709 <property name="width">2</property>
664710 </packing>
665711 </child>
672718 <object class="GtkLabel" id="label1">
673719 <property name="visible">True</property>
674720 <property name="can_focus">False</property>
675 <property name="label" translatable="yes">Appearance</property>
721 <property name="label" translatable="yes" context="tabs">Appearance</property>
676722 </object>
677723 <packing>
724 <property name="tab_expand">True</property>
678725 <property name="tab_fill">False</property>
679726 </packing>
680727 </child>
691738 <property name="row_spacing">8</property>
692739 <property name="column_spacing">12</property>
693740 <child>
694 <object class="GtkLabel" id="greeter_indicators_label">
695 <property name="visible">True</property>
696 <property name="can_focus">False</property>
697 <property name="halign">start</property>
698 <property name="hexpand">True</property>
699 <property name="label" translatable="yes" context="option|indicators">Redefine indicators</property>
700 <attributes>
701 <attribute name="weight" value="semibold"/>
702 </attributes>
703 </object>
704 <packing>
705 <property name="left_attach">0</property>
706 <property name="top_attach">4</property>
707 </packing>
708 </child>
709 <child>
710741 <object class="GtkSwitch" id="greeter_indicators_use">
711742 <property name="visible">True</property>
712743 <property name="can_focus">False</property>
741772 <property name="halign">start</property>
742773 <property name="margin_left">24</property>
743774 <property name="hexpand">True</property>
744 <property name="label" translatable="yes" context="option|clock-format">%H %I - hours, %M - minutes, %S - seconds
775 <property name="label" translatable="yes" context="option|greeter|clock-format">%H %I - hours, %M - minutes, %S - seconds
745776 %d - day, %m - month, %y %Y - year
746777 %a %A - day of the week, %b %B - month name</property>
747778 <attributes>
763794 <property name="orientation">vertical</property>
764795 <child>
765796 <object class="GtkScrolledWindow" id="scrolledwindow1">
766 <property name="height_request">160</property>
797 <property name="height_request">170</property>
767798 <property name="visible">True</property>
768799 <property name="can_focus">True</property>
769800 <property name="hexpand">True</property>
779810 <property name="headers_visible">False</property>
780811 <property name="headers_clickable">False</property>
781812 <property name="reorderable">True</property>
782 <property name="search_column">0</property>
813 <property name="search_column">3</property>
783814 <property name="tooltip_column">1</property>
784815 <child internal-child="selection">
785816 <object class="GtkTreeSelection" id="greeter_indicators_selection">
788819 </child>
789820 <child>
790821 <object class="GtkTreeViewColumn" id="greeter_indicators_state_column">
822 <property name="visible">False</property>
791823 <property name="sizing">autosize</property>
792824 <property name="title">column</property>
793825 <property name="clickable">True</property>
794826 <child>
795827 <object class="GtkCellRendererToggle" id="greeter_indicators_state_renderer"/>
796828 <attributes>
797 <attribute name="visible">3</attribute>
798 <attribute name="active">4</attribute>
829 <attribute name="visible">2</attribute>
830 <attribute name="active">3</attribute>
799831 </attributes>
800832 </child>
801833 </object>
806838 <property name="title">column</property>
807839 <property name="expand">True</property>
808840 <child>
841 <object class="GtkCellRendererPixbuf" id="greeter_indicators_image_renderer"/>
842 <attributes>
843 <attribute name="icon-name">5</attribute>
844 </attributes>
845 </child>
846 <child>
809847 <object class="GtkCellRendererText" id="greeter_indicators_name_renderer"/>
810848 <attributes>
811 <attribute name="editable">3</attribute>
812 <attribute name="text">0</attribute>
849 <attribute name="markup">6</attribute>
813850 </attributes>
814851 </child>
815852 </object>
832869 <object class="GtkToolButton" id="greeter_indicators_add">
833870 <property name="visible">True</property>
834871 <property name="can_focus">False</property>
835 <property name="tooltip_text" translatable="yes" context="option|indicators">Add indicator to list</property>
836 <property name="label" translatable="yes" context="option|indicators">Add</property>
872 <property name="tooltip_text" translatable="yes" context="option|greeter|indicators">Add indicator to list</property>
873 <property name="label" translatable="yes" context="option|greeter|indicators">Add</property>
837874 <property name="use_underline">True</property>
838875 <property name="icon_name">list-add-symbolic</property>
839876 </object>
846883 <object class="GtkToolButton" id="greeter_indicators_remove">
847884 <property name="visible">True</property>
848885 <property name="can_focus">False</property>
849 <property name="tooltip_text" translatable="yes" context="option|indicators">Remove indicator from list</property>
850 <property name="label" translatable="yes" context="option|indicators">Remove</property>
886 <property name="tooltip_text" translatable="yes" context="option|greeter|indicators">Remove indicator from list</property>
887 <property name="label" translatable="yes" context="option|greeter|indicators">Remove</property>
851888 <property name="use_underline">True</property>
852889 <property name="icon_name">list-remove-symbolic</property>
853890 </object>
860897 <object class="GtkToolButton" id="greeter_indicators_up">
861898 <property name="visible">True</property>
862899 <property name="can_focus">False</property>
863 <property name="tooltip_text" translatable="yes" context="option|indicators">Move up</property>
864 <property name="label" translatable="yes" context="option|indicators">Up</property>
900 <property name="tooltip_text" translatable="yes" context="option|greeter|indicators">Move up</property>
901 <property name="label" translatable="yes" context="option|greeter|indicators">Up</property>
865902 <property name="use_underline">True</property>
866903 <property name="icon_name">go-up-symbolic</property>
867904 </object>
874911 <object class="GtkToolButton" id="greeter_indicators_down">
875912 <property name="visible">True</property>
876913 <property name="can_focus">False</property>
877 <property name="tooltip_text" translatable="yes" context="option|indicators">Move down</property>
878 <property name="label" translatable="yes" context="option|indicators">Down</property>
914 <property name="tooltip_text" translatable="yes" context="option|greeter|indicators">Move down</property>
915 <property name="label" translatable="yes" context="option|greeter|indicators">Down</property>
879916 <property name="use_underline">True</property>
880917 <property name="icon_name">go-down-symbolic</property>
881918 </object>
884921 <property name="homogeneous">True</property>
885922 </packing>
886923 </child>
924 <child>
925 <object class="GtkToolButton" id="greeter_indicators_tools">
926 <property name="visible">True</property>
927 <property name="can_focus">False</property>
928 <property name="label" translatable="yes" context="option|greeter|indicators">Templates</property>
929 <property name="use_underline">True</property>
930 <property name="icon_name">preferences-other</property>
931 </object>
932 <packing>
933 <property name="expand">False</property>
934 <property name="homogeneous">False</property>
935 </packing>
936 </child>
887937 <style>
888938 <class name="inline-toolbar"/>
889939 </style>
908958 <property name="margin_left">24</property>
909959 <property name="spacing">6</property>
910960 <child>
911 <object class="GtkLabel" id="greeter_clock-format_label">
912 <property name="visible">True</property>
913 <property name="can_focus">False</property>
914 <property name="label" translatable="yes" context="option|clock-format">Clock format:</property>
961 <object class="GtkEventBox" id="greeter_clock-format_label_holder">
962 <property name="visible">True</property>
963 <property name="can_focus">False</property>
964 <child>
965 <object class="GtkLabel" id="greeter_clock-format_label">
966 <property name="visible">True</property>
967 <property name="can_focus">False</property>
968 <property name="label" translatable="yes" context="option|greeter|clock-format">Clock format:</property>
969 </object>
970 </child>
915971 </object>
916972 <packing>
917973 <property name="expand">False</property>
936992 <property name="left_attach">0</property>
937993 <property name="top_attach">1</property>
938994 <property name="width">2</property>
995 </packing>
996 </child>
997 <child>
998 <object class="GtkEventBox" id="greeter_indicators_label_holder">
999 <property name="visible">True</property>
1000 <property name="can_focus">False</property>
1001 <child>
1002 <object class="GtkLabel" id="greeter_indicators_label">
1003 <property name="visible">True</property>
1004 <property name="can_focus">False</property>
1005 <property name="halign">start</property>
1006 <property name="hexpand">True</property>
1007 <property name="label" translatable="yes" context="option|greeter|indicators">Redefine indicators</property>
1008 <attributes>
1009 <attribute name="weight" value="semibold"/>
1010 </attributes>
1011 </object>
1012 </child>
1013 </object>
1014 <packing>
1015 <property name="left_attach">0</property>
1016 <property name="top_attach">4</property>
9391017 </packing>
9401018 </child>
9411019 <child>
9541032 <object class="GtkLabel" id="label2">
9551033 <property name="visible">True</property>
9561034 <property name="can_focus">False</property>
957 <property name="label" translatable="yes">Panel</property>
1035 <property name="label" translatable="yes" context="tabs">Panel</property>
9581036 </object>
9591037 <packing>
9601038 <property name="position">1</property>
1039 <property name="tab_expand">True</property>
9611040 <property name="tab_fill">False</property>
9621041 </packing>
9631042 </child>
9741053 <property name="row_spacing">8</property>
9751054 <property name="column_spacing">8</property>
9761055 <child>
977 <object class="GtkLabel" id="label6">
1056 <object class="GtkAspectFrame" id="greeter_position_screen_frame">
1057 <property name="visible">True</property>
1058 <property name="can_focus">False</property>
1059 <property name="hexpand">True</property>
1060 <property name="vexpand">True</property>
1061 <property name="label_xalign">0</property>
1062 <property name="shadow_type">in</property>
1063 <property name="obey_child">False</property>
1064 <child>
1065 <object class="GtkOverlay" id="greeter_position_screen_overlay">
1066 <property name="visible">True</property>
1067 <property name="can_focus">False</property>
1068 <property name="hexpand">True</property>
1069 <property name="vexpand">True</property>
1070 <child>
1071 <object class="GtkBox" id="box3">
1072 <property name="visible">True</property>
1073 <property name="can_focus">False</property>
1074 <property name="hexpand">True</property>
1075 <property name="vexpand">True</property>
1076 <property name="orientation">vertical</property>
1077 <child>
1078 <placeholder/>
1079 </child>
1080 </object>
1081 </child>
1082 <child type="overlay">
1083 <object class="GtkEventBox" id="greeter_position_window_box">
1084 <property name="visible">True</property>
1085 <property name="can_focus">False</property>
1086 <property name="events">GDK_BUTTON1_MOTION_MASK | GDK_BUTTON_PRESS_MASK | GDK_STRUCTURE_MASK</property>
1087 <property name="halign">start</property>
1088 <property name="valign">start</property>
1089 <child>
1090 <object class="GtkFrame" id="greeter_position_window_frame">
1091 <property name="width_request">100</property>
1092 <property name="height_request">80</property>
1093 <property name="visible">True</property>
1094 <property name="can_focus">False</property>
1095 <property name="border_width">2</property>
1096 <property name="label_xalign">0</property>
1097 <property name="shadow_type">in</property>
1098 <child>
1099 <object class="GtkGrid" id="greeter_position_window_grid">
1100 <property name="visible">True</property>
1101 <property name="can_focus">False</property>
1102 <property name="column_spacing">30</property>
1103 <property name="row_homogeneous">True</property>
1104 <property name="column_homogeneous">True</property>
1105 <child>
1106 <placeholder/>
1107 </child>
1108 <child>
1109 <placeholder/>
1110 </child>
1111 <child>
1112 <placeholder/>
1113 </child>
1114 <child>
1115 <placeholder/>
1116 </child>
1117 <child>
1118 <placeholder/>
1119 </child>
1120 <child>
1121 <placeholder/>
1122 </child>
1123 <child>
1124 <placeholder/>
1125 </child>
1126 <child>
1127 <placeholder/>
1128 </child>
1129 <child>
1130 <placeholder/>
1131 </child>
1132 </object>
1133 </child>
1134 <child type="label_item">
1135 <placeholder/>
1136 </child>
1137 </object>
1138 </child>
1139 </object>
1140 </child>
1141 </object>
1142 </child>
1143 </object>
1144 <packing>
1145 <property name="left_attach">0</property>
1146 <property name="top_attach">1</property>
1147 <property name="width">3</property>
1148 </packing>
1149 </child>
1150 <child>
1151 <object class="GtkSeparator" id="separator1">
1152 <property name="visible">True</property>
1153 <property name="can_focus">False</property>
1154 <property name="orientation">vertical</property>
1155 </object>
1156 <packing>
1157 <property name="left_attach">1</property>
1158 <property name="top_attach">2</property>
1159 <property name="height">3</property>
1160 </packing>
1161 </child>
1162 <child>
1163 <object class="GtkLabel" id="label9">
9781164 <property name="visible">True</property>
9791165 <property name="can_focus">False</property>
9801166 <property name="halign">start</property>
981 <property name="valign">center</property>
982 <property name="hexpand">True</property>
983 <property name="label" translatable="yes" context="option|position">Horizontal </property>
984 <attributes>
985 <attribute name="weight" value="semibold"/>
986 </attributes>
987 </object>
988 <packing>
989 <property name="left_attach">0</property>
990 <property name="top_attach">3</property>
991 </packing>
992 </child>
993 <child>
994 <object class="GtkBox" id="box8">
1167 <property name="label" translatable="yes" context="option|greeter|position">Horizontal</property>
1168 </object>
1169 <packing>
1170 <property name="left_attach">0</property>
1171 <property name="top_attach">2</property>
1172 </packing>
1173 </child>
1174 <child>
1175 <object class="GtkLabel" id="label10">
1176 <property name="visible">True</property>
1177 <property name="can_focus">False</property>
1178 <property name="halign">start</property>
1179 <property name="label" translatable="yes" context="option|greeter|position">Vertical</property>
1180 </object>
1181 <packing>
1182 <property name="left_attach">2</property>
1183 <property name="top_attach">2</property>
1184 </packing>
1185 </child>
1186 <child>
1187 <object class="GtkBox" id="box6">
9951188 <property name="visible">True</property>
9961189 <property name="can_focus">False</property>
9971190 <property name="spacing">8</property>
9981191 <child>
999 <object class="GtkSpinButton" id="greeter_position_x_value">
1192 <object class="GtkSpinButton" id="greeter_position_x_entry">
10001193 <property name="visible">True</property>
10011194 <property name="can_focus">True</property>
10021195 <property name="halign">start</property>
1003 <property name="margin_left">24</property>
10041196 <property name="invisible_char">●</property>
10051197 <property name="width_chars">6</property>
1198 <property name="text" translatable="yes">0</property>
10061199 <property name="xalign">1</property>
10071200 <property name="adjustment">greeter_position_x_adjustment</property>
10081201 <property name="snap_to_ticks">True</property>
10161209 </child>
10171210 <child>
10181211 <object class="GtkCheckButton" id="greeter_position_x_percents">
1019 <property name="label" translatable="yes" context="option|position">in %</property>
1212 <property name="label" translatable="yes" context="option|greeter|position">in %</property>
10201213 <property name="visible">True</property>
10211214 <property name="can_focus">True</property>
10221215 <property name="receives_default">False</property>
10321225 </object>
10331226 <packing>
10341227 <property name="left_attach">0</property>
1035 <property name="top_attach">4</property>
1036 </packing>
1037 </child>
1038 <child>
1039 <object class="GtkBox" id="box9">
1228 <property name="top_attach">3</property>
1229 </packing>
1230 </child>
1231 <child>
1232 <object class="GtkBox" id="box7">
10401233 <property name="visible">True</property>
10411234 <property name="can_focus">False</property>
10421235 <property name="spacing">8</property>
10431236 <child>
1044 <object class="GtkSpinButton" id="greeter_position_y_value">
1237 <object class="GtkSpinButton" id="greeter_position_y_entry">
10451238 <property name="visible">True</property>
10461239 <property name="can_focus">True</property>
10471240 <property name="halign">start</property>
1048 <property name="margin_left">24</property>
10491241 <property name="invisible_char">●</property>
10501242 <property name="width_chars">6</property>
1243 <property name="text" translatable="yes">0</property>
10511244 <property name="xalign">1</property>
10521245 <property name="adjustment">greeter_position_y_adjustment</property>
10531246 <property name="snap_to_ticks">True</property>
10611254 </child>
10621255 <child>
10631256 <object class="GtkCheckButton" id="greeter_position_y_percents">
1064 <property name="label" translatable="yes" context="option|position">in %</property>
1257 <property name="label" translatable="yes" context="option|greeter|position">in %</property>
10651258 <property name="visible">True</property>
10661259 <property name="can_focus">True</property>
10671260 <property name="receives_default">False</property>
10771270 </object>
10781271 <packing>
10791272 <property name="left_attach">2</property>
1273 <property name="top_attach">3</property>
1274 </packing>
1275 </child>
1276 <child>
1277 <object class="GtkCheckButton" id="greeter_position_x_mirror">
1278 <property name="label" translatable="yes" context="option|greeter|position">from right</property>
1279 <property name="visible">True</property>
1280 <property name="can_focus">True</property>
1281 <property name="receives_default">False</property>
1282 <property name="xalign">0</property>
1283 <property name="draw_indicator">True</property>
1284 </object>
1285 <packing>
1286 <property name="left_attach">0</property>
10801287 <property name="top_attach">4</property>
10811288 </packing>
10821289 </child>
10831290 <child>
1084 <object class="GtkLabel" id="label11">
1085 <property name="visible">True</property>
1086 <property name="can_focus">False</property>
1087 <property name="halign">start</property>
1088 <property name="valign">center</property>
1089 <property name="hexpand">True</property>
1090 <property name="label" translatable="yes" context="option|position">Vertical</property>
1091 <attributes>
1092 <attribute name="weight" value="semibold"/>
1093 </attributes>
1291 <object class="GtkCheckButton" id="greeter_position_y_mirror">
1292 <property name="label" translatable="yes" context="option|greeter|position">from bottom</property>
1293 <property name="visible">True</property>
1294 <property name="can_focus">True</property>
1295 <property name="receives_default">False</property>
1296 <property name="xalign">0</property>
1297 <property name="draw_indicator">True</property>
10941298 </object>
10951299 <packing>
10961300 <property name="left_attach">2</property>
1097 <property name="top_attach">3</property>
1098 </packing>
1099 </child>
1100 <child>
1101 <object class="GtkSeparator" id="separator2">
1102 <property name="visible">True</property>
1103 <property name="can_focus">False</property>
1104 <property name="orientation">vertical</property>
1105 </object>
1106 <packing>
1107 <property name="left_attach">1</property>
1108 <property name="top_attach">3</property>
1109 <property name="height">3</property>
1110 </packing>
1111 </child>
1112 <child>
1113 <object class="GtkLabel" id="greeter_position_label">
1114 <property name="visible">True</property>
1115 <property name="can_focus">False</property>
1116 <property name="halign">start</property>
1117 <property name="label" translatable="yes" context="option|position">Select base point and its position</property>
1118 <attributes>
1119 <attribute name="style" value="oblique"/>
1120 </attributes>
1301 <property name="top_attach">4</property>
1302 </packing>
1303 </child>
1304 <child>
1305 <object class="GtkEventBox" id="greeter_position_label_holder">
1306 <property name="visible">True</property>
1307 <property name="can_focus">False</property>
1308 <child>
1309 <object class="GtkLabel" id="greeter_position_label">
1310 <property name="visible">True</property>
1311 <property name="can_focus">False</property>
1312 <property name="halign">start</property>
1313 <property name="label" translatable="yes" context="option|greeter|position">Select base point and its position.</property>
1314 <attributes>
1315 <attribute name="style" value="oblique"/>
1316 </attributes>
1317 </object>
1318 </child>
11211319 </object>
11221320 <packing>
11231321 <property name="left_attach">0</property>
11241322 <property name="top_attach">0</property>
11251323 <property name="width">3</property>
1126 </packing>
1127 </child>
1128 <child>
1129 <object class="GtkCheckButton" id="greeter_position_x_mirror">
1130 <property name="label" translatable="yes" context="option|position">from right</property>
1131 <property name="visible">True</property>
1132 <property name="can_focus">True</property>
1133 <property name="receives_default">False</property>
1134 <property name="margin_left">24</property>
1135 <property name="xalign">0</property>
1136 <property name="draw_indicator">True</property>
1137 </object>
1138 <packing>
1139 <property name="left_attach">0</property>
1140 <property name="top_attach">5</property>
1141 </packing>
1142 </child>
1143 <child>
1144 <object class="GtkCheckButton" id="greeter_position_y_mirror">
1145 <property name="label" translatable="yes" context="option|position">from bottom</property>
1146 <property name="visible">True</property>
1147 <property name="can_focus">True</property>
1148 <property name="receives_default">False</property>
1149 <property name="margin_left">24</property>
1150 <property name="xalign">0</property>
1151 <property name="draw_indicator">True</property>
1152 </object>
1153 <packing>
1154 <property name="left_attach">2</property>
1155 <property name="top_attach">5</property>
1156 </packing>
1157 </child>
1158 <child>
1159 <object class="GtkFixed" id="greeter_position_screen">
1160 <property name="visible">True</property>
1161 <property name="app_paintable">True</property>
1162 <property name="can_focus">False</property>
1163 <property name="hexpand">True</property>
1164 <property name="vexpand">True</property>
1165 <property name="resize_mode">immediate</property>
1166 <child>
1167 <object class="GtkFrame" id="greeter_position_window">
1168 <property name="width_request">100</property>
1169 <property name="height_request">80</property>
1170 <property name="visible">True</property>
1171 <property name="can_focus">False</property>
1172 <property name="halign">start</property>
1173 <property name="valign">start</property>
1174 <property name="border_width">2</property>
1175 <property name="resize_mode">immediate</property>
1176 <property name="label_xalign">0</property>
1177 <property name="shadow_type">in</property>
1178 <child>
1179 <object class="GtkGrid" id="greeter_position_window_grid">
1180 <property name="visible">True</property>
1181 <property name="can_focus">False</property>
1182 <property name="hexpand">True</property>
1183 <property name="vexpand">True</property>
1184 <property name="column_spacing">30</property>
1185 <property name="row_homogeneous">True</property>
1186 <property name="column_homogeneous">True</property>
1187 <child>
1188 <object class="GtkRadioButton" id="greeter_position_base_start_start">
1189 <property name="visible">True</property>
1190 <property name="can_focus">True</property>
1191 <property name="receives_default">False</property>
1192 <property name="halign">start</property>
1193 <property name="valign">start</property>
1194 <property name="xalign">0</property>
1195 <property name="active">True</property>
1196 <property name="draw_indicator">True</property>
1197 </object>
1198 <packing>
1199 <property name="left_attach">0</property>
1200 <property name="top_attach">0</property>
1201 </packing>
1202 </child>
1203 <child>
1204 <object class="GtkRadioButton" id="greeter_position_base_center_start">
1205 <property name="visible">True</property>
1206 <property name="can_focus">True</property>
1207 <property name="receives_default">False</property>
1208 <property name="halign">center</property>
1209 <property name="valign">start</property>
1210 <property name="xalign">0</property>
1211 <property name="draw_indicator">True</property>
1212 <property name="group">greeter_position_base_start_start</property>
1213 </object>
1214 <packing>
1215 <property name="left_attach">1</property>
1216 <property name="top_attach">0</property>
1217 </packing>
1218 </child>
1219 <child>
1220 <object class="GtkRadioButton" id="greeter_position_base_end_start">
1221 <property name="visible">True</property>
1222 <property name="can_focus">True</property>
1223 <property name="receives_default">False</property>
1224 <property name="halign">end</property>
1225 <property name="valign">start</property>
1226 <property name="xalign">0</property>
1227 <property name="draw_indicator">True</property>
1228 <property name="group">greeter_position_base_start_start</property>
1229 </object>
1230 <packing>
1231 <property name="left_attach">2</property>
1232 <property name="top_attach">0</property>
1233 </packing>
1234 </child>
1235 <child>
1236 <object class="GtkRadioButton" id="greeter_position_base_start_center">
1237 <property name="visible">True</property>
1238 <property name="can_focus">True</property>
1239 <property name="receives_default">False</property>
1240 <property name="halign">start</property>
1241 <property name="valign">center</property>
1242 <property name="xalign">0</property>
1243 <property name="draw_indicator">True</property>
1244 <property name="group">greeter_position_base_start_start</property>
1245 </object>
1246 <packing>
1247 <property name="left_attach">0</property>
1248 <property name="top_attach">1</property>
1249 </packing>
1250 </child>
1251 <child>
1252 <object class="GtkRadioButton" id="greeter_position_base_center_center">
1253 <property name="visible">True</property>
1254 <property name="can_focus">True</property>
1255 <property name="receives_default">False</property>
1256 <property name="halign">center</property>
1257 <property name="valign">center</property>
1258 <property name="xalign">0</property>
1259 <property name="draw_indicator">True</property>
1260 <property name="group">greeter_position_base_start_start</property>
1261 </object>
1262 <packing>
1263 <property name="left_attach">1</property>
1264 <property name="top_attach">1</property>
1265 </packing>
1266 </child>
1267 <child>
1268 <object class="GtkRadioButton" id="greeter_position_base_end_center">
1269 <property name="visible">True</property>
1270 <property name="can_focus">True</property>
1271 <property name="receives_default">False</property>
1272 <property name="halign">end</property>
1273 <property name="valign">center</property>
1274 <property name="xalign">0</property>
1275 <property name="draw_indicator">True</property>
1276 <property name="group">greeter_position_base_start_start</property>
1277 </object>
1278 <packing>
1279 <property name="left_attach">2</property>
1280 <property name="top_attach">1</property>
1281 </packing>
1282 </child>
1283 <child>
1284 <object class="GtkRadioButton" id="greeter_position_base_start_end">
1285 <property name="visible">True</property>
1286 <property name="can_focus">True</property>
1287 <property name="receives_default">False</property>
1288 <property name="halign">start</property>
1289 <property name="valign">end</property>
1290 <property name="xalign">0</property>
1291 <property name="draw_indicator">True</property>
1292 <property name="group">greeter_position_base_start_start</property>
1293 </object>
1294 <packing>
1295 <property name="left_attach">0</property>
1296 <property name="top_attach">2</property>
1297 </packing>
1298 </child>
1299 <child>
1300 <object class="GtkRadioButton" id="greeter_position_base_center_end">
1301 <property name="visible">True</property>
1302 <property name="can_focus">True</property>
1303 <property name="receives_default">False</property>
1304 <property name="halign">center</property>
1305 <property name="valign">end</property>
1306 <property name="xalign">0</property>
1307 <property name="draw_indicator">True</property>
1308 <property name="group">greeter_position_base_start_start</property>
1309 </object>
1310 <packing>
1311 <property name="left_attach">1</property>
1312 <property name="top_attach">2</property>
1313 </packing>
1314 </child>
1315 <child>
1316 <object class="GtkRadioButton" id="greeter_position_base_end_end">
1317 <property name="visible">True</property>
1318 <property name="can_focus">True</property>
1319 <property name="receives_default">False</property>
1320 <property name="halign">end</property>
1321 <property name="valign">end</property>
1322 <property name="xalign">0</property>
1323 <property name="draw_indicator">True</property>
1324 <property name="group">greeter_position_base_start_start</property>
1325 </object>
1326 <packing>
1327 <property name="left_attach">2</property>
1328 <property name="top_attach">2</property>
1329 </packing>
1330 </child>
1331 </object>
1332 </child>
1333 <child type="label_item">
1334 <placeholder/>
1335 </child>
1336 </object>
1337 </child>
1338 </object>
1339 <packing>
1340 <property name="left_attach">0</property>
1341 <property name="top_attach">1</property>
1342 <property name="width">3</property>
1343 <property name="height">2</property>
13441324 </packing>
13451325 </child>
13461326 </object>
13501330 </packing>
13511331 </child>
13521332 <child type="tab">
1353 <object class="GtkLabel" id="label3">
1333 <object class="GtkLabel" id="label5">
13541334 <property name="visible">True</property>
13551335 <property name="can_focus">False</property>
1356 <property name="label" translatable="yes">Window position</property>
1336 <property name="label" translatable="yes" context="tabs">Window position</property>
13571337 </object>
13581338 <packing>
13591339 <property name="position">2</property>
1340 <property name="tab_expand">True</property>
13601341 <property name="tab_fill">False</property>
13611342 </packing>
13621343 </child>
13731354 <property name="row_spacing">8</property>
13741355 <property name="column_spacing">8</property>
13751356 <child>
1376 <object class="GtkLabel" id="greeter_screensaver-timeout_label">
1377 <property name="visible">True</property>
1378 <property name="can_focus">False</property>
1379 <property name="halign">start</property>
1380 <property name="hexpand">True</property>
1381 <property name="label" translatable="yes" context="option|timeout">Timeout until the screen blanks </property>
1382 <attributes>
1383 <attribute name="weight" value="semibold"/>
1384 </attributes>
1385 </object>
1386 <packing>
1387 <property name="left_attach">0</property>
1388 <property name="top_attach">2</property>
1389 <property name="width">2</property>
1390 </packing>
1391 </child>
1392 <child>
1393 <object class="GtkLabel" id="greeter_keyboard_label">
1394 <property name="visible">True</property>
1395 <property name="can_focus">False</property>
1396 <property name="halign">start</property>
1397 <property name="hexpand">True</property>
1398 <property name="label" translatable="yes" context="option|keyboard">Onscreen keyboard</property>
1399 <attributes>
1400 <attribute name="weight" value="semibold"/>
1401 </attributes>
1402 </object>
1403 <packing>
1404 <property name="left_attach">0</property>
1405 <property name="top_attach">0</property>
1406 </packing>
1407 </child>
1408 <child>
1409 <object class="GtkComboBoxText" id="greeter_keyboard_values">
1410 <property name="visible">True</property>
1411 <property name="can_focus">False</property>
1412 <property name="margin_left">24</property>
1413 <property name="has_entry">True</property>
1414 <items>
1415 <item>onboard</item>
1416 </items>
1417 <child internal-child="entry">
1418 <object class="GtkEntry" id="greeter_keyboard_value">
1419 <property name="can_focus">True</property>
1420 </object>
1421 </child>
1422 </object>
1423 <packing>
1424 <property name="left_attach">0</property>
1425 <property name="top_attach">1</property>
1426 <property name="width">2</property>
1427 </packing>
1428 </child>
1429 <child>
1430 <object class="GtkSwitch" id="greeter_keyboard_use">
1431 <property name="visible">True</property>
1432 <property name="can_focus">False</property>
1433 <property name="halign">end</property>
1434 </object>
1435 <packing>
1436 <property name="left_attach">1</property>
1437 <property name="top_attach">0</property>
1438 </packing>
1439 </child>
1440 <child>
14411357 <object class="GtkBox" id="greeter_screensaver-timeout_box">
14421358 <property name="visible">True</property>
14431359 <property name="can_focus">False</property>
14481364 <property name="visible">True</property>
14491365 <property name="can_focus">False</property>
14501366 <property name="valign">start</property>
1451 <property name="label" translatable="yes" context="option|timeout">Never</property>
1367 <property name="label" translatable="yes" context="option|greeter|screensaver-timeout">Never</property>
14521368 </object>
14531369 <packing>
14541370 <property name="expand">False</property>
14891405 <packing>
14901406 <property name="left_attach">0</property>
14911407 <property name="top_attach">3</property>
1408 <property name="width">2</property>
1409 </packing>
1410 </child>
1411 <child>
1412 <object class="GtkLabel" id="label4">
1413 <property name="visible">True</property>
1414 <property name="can_focus">False</property>
1415 <property name="halign">start</property>
1416 <property name="label" translatable="yes">Accessibility</property>
1417 <attributes>
1418 <attribute name="weight" value="semibold"/>
1419 </attributes>
1420 </object>
1421 <packing>
1422 <property name="left_attach">0</property>
1423 <property name="top_attach">0</property>
1424 <property name="width">2</property>
1425 </packing>
1426 </child>
1427 <child>
1428 <object class="GtkGrid" id="grid1">
1429 <property name="visible">True</property>
1430 <property name="can_focus">False</property>
1431 <property name="margin_left">24</property>
1432 <property name="row_spacing">8</property>
1433 <property name="column_spacing">8</property>
1434 <child>
1435 <object class="GtkComboBoxText" id="greeter_reader_combo">
1436 <property name="visible">True</property>
1437 <property name="can_focus">False</property>
1438 <property name="hexpand">True</property>
1439 <property name="has_entry">True</property>
1440 <items>
1441 <item id="select-path" translatable="yes" context="option|greeter|reader">Select path to reader...</item>
1442 <item id="separator">-</item>
1443 <item id="value">orca</item>
1444 </items>
1445 <child internal-child="entry">
1446 <object class="GtkEntry" id="greeter_reader_entry">
1447 <property name="can_focus">True</property>
1448 <property name="placeholder_text" translatable="yes" context="option|greeter|reader">Command to launch screen reader</property>
1449 </object>
1450 </child>
1451 </object>
1452 <packing>
1453 <property name="left_attach">1</property>
1454 <property name="top_attach">2</property>
1455 </packing>
1456 </child>
1457 <child>
1458 <object class="GtkComboBoxText" id="greeter_keyboard_combo">
1459 <property name="visible">True</property>
1460 <property name="can_focus">False</property>
1461 <property name="hexpand">True</property>
1462 <property name="has_entry">True</property>
1463 <items>
1464 <item id="select-path" translatable="yes" context="option|greeter|keyboard">Select path to keyboard...</item>
1465 <item id="separator">-</item>
1466 <item id="value">onboard</item>
1467 </items>
1468 <child internal-child="entry">
1469 <object class="GtkEntry" id="greeter_keyboard_entry">
1470 <property name="can_focus">True</property>
1471 <property name="placeholder_text" translatable="yes" context="option|greeter|keyboard">Command to launch on-screen keyboard</property>
1472 </object>
1473 </child>
1474 </object>
1475 <packing>
1476 <property name="left_attach">1</property>
1477 <property name="top_attach">0</property>
1478 </packing>
1479 </child>
1480 <child>
1481 <object class="GtkComboBoxText" id="greeter_a11y-states_keyboard">
1482 <property name="visible">True</property>
1483 <property name="can_focus">False</property>
1484 <property name="halign">start</property>
1485 <items>
1486 <item id="-" translatable="yes" context="option|greeter|a11y-states">Disabled at start</item>
1487 <item id="+" translatable="yes" context="option|greeter|a11y-states">Enabled at start</item>
1488 <item id="~" translatable="yes" context="option|greeter|a11y-states">Save state between launches</item>
1489 </items>
1490 </object>
1491 <packing>
1492 <property name="left_attach">1</property>
1493 <property name="top_attach">1</property>
1494 </packing>
1495 </child>
1496 <child>
1497 <object class="GtkComboBoxText" id="greeter_a11y-states_reader">
1498 <property name="visible">True</property>
1499 <property name="can_focus">False</property>
1500 <property name="halign">start</property>
1501 <items>
1502 <item id="-" translatable="yes" context="option|greeter|a11y-states">Disabled at start</item>
1503 <item id="+" translatable="yes" context="option|greeter|a11y-states">Enabled at start</item>
1504 <item id="~" translatable="yes" context="option|greeter|a11y-states">Save state between launches</item>
1505 </items>
1506 </object>
1507 <packing>
1508 <property name="left_attach">1</property>
1509 <property name="top_attach">3</property>
1510 </packing>
1511 </child>
1512 <child>
1513 <object class="GtkComboBoxText" id="greeter_a11y-states_contrast">
1514 <property name="visible">True</property>
1515 <property name="can_focus">False</property>
1516 <property name="halign">start</property>
1517 <items>
1518 <item id="-" translatable="yes" context="option|greeter|a11y-states">Disabled at start</item>
1519 <item id="+" translatable="yes" context="option|greeter|a11y-states">Enabled at start</item>
1520 <item id="~" translatable="yes" context="option|greeter|a11y-states">Save state between launches</item>
1521 </items>
1522 </object>
1523 <packing>
1524 <property name="left_attach">1</property>
1525 <property name="top_attach">4</property>
1526 </packing>
1527 </child>
1528 <child>
1529 <object class="GtkComboBoxText" id="greeter_a11y-states_font">
1530 <property name="visible">True</property>
1531 <property name="can_focus">False</property>
1532 <property name="halign">start</property>
1533 <items>
1534 <item id="-" translatable="yes" context="option|greeter|a11y-states">Disabled at start</item>
1535 <item id="+" translatable="yes" context="option|greeter|a11y-states">Enabled at start</item>
1536 <item id="~" translatable="yes" context="option|greeter|a11y-states">Save state between launches</item>
1537 </items>
1538 </object>
1539 <packing>
1540 <property name="left_attach">1</property>
1541 <property name="top_attach">5</property>
1542 </packing>
1543 </child>
1544 <child>
1545 <object class="GtkEventBox" id="greeter_a11y-theme_label_holder">
1546 <property name="visible">True</property>
1547 <property name="can_focus">False</property>
1548 <child>
1549 <object class="GtkLabel" id="greeter_a11y-theme_label">
1550 <property name="visible">True</property>
1551 <property name="can_focus">False</property>
1552 <property name="halign">start</property>
1553 <property name="label" translatable="yes" context="option|greeter|a11y-theme">Contrast theme</property>
1554 </object>
1555 </child>
1556 </object>
1557 <packing>
1558 <property name="left_attach">0</property>
1559 <property name="top_attach">4</property>
1560 </packing>
1561 </child>
1562 <child>
1563 <object class="GtkEventBox" id="greeter_a11y-font_label_holder">
1564 <property name="visible">True</property>
1565 <property name="can_focus">False</property>
1566 <child>
1567 <object class="GtkLabel" id="greeter_a11y-font_label">
1568 <property name="visible">True</property>
1569 <property name="can_focus">False</property>
1570 <property name="halign">start</property>
1571 <property name="label" translatable="yes" context="option|greeter|a11y-font">Large font</property>
1572 </object>
1573 </child>
1574 </object>
1575 <packing>
1576 <property name="left_attach">0</property>
1577 <property name="top_attach">5</property>
1578 </packing>
1579 </child>
1580 <child>
1581 <object class="GtkEventBox" id="greeter_reader_label_holder">
1582 <property name="visible">True</property>
1583 <property name="can_focus">False</property>
1584 <child>
1585 <object class="GtkCheckButton" id="greeter_reader_use">
1586 <property name="visible">True</property>
1587 <property name="can_focus">True</property>
1588 <property name="receives_default">False</property>
1589 <property name="xalign">0</property>
1590 <property name="draw_indicator">True</property>
1591 <child>
1592 <object class="GtkBox" id="box15">
1593 <property name="visible">True</property>
1594 <property name="can_focus">False</property>
1595 <child>
1596 <object class="GtkLabel" id="greeter_reader_label">
1597 <property name="visible">True</property>
1598 <property name="can_focus">False</property>
1599 <property name="label" translatable="yes" context="greeter|option|reader">Reader</property>
1600 </object>
1601 <packing>
1602 <property name="expand">False</property>
1603 <property name="fill">True</property>
1604 <property name="position">0</property>
1605 </packing>
1606 </child>
1607 <child>
1608 <object class="GtkImage" id="greeter_reader_error">
1609 <property name="can_focus">False</property>
1610 <property name="yalign">0</property>
1611 <property name="pixel_size">12</property>
1612 <property name="icon_name">dialog-warning</property>
1613 <property name="icon_size">1</property>
1614 </object>
1615 <packing>
1616 <property name="expand">False</property>
1617 <property name="fill">True</property>
1618 <property name="position">1</property>
1619 </packing>
1620 </child>
1621 </object>
1622 </child>
1623 </object>
1624 </child>
1625 </object>
1626 <packing>
1627 <property name="left_attach">0</property>
1628 <property name="top_attach">2</property>
1629 </packing>
1630 </child>
1631 <child>
1632 <object class="GtkEventBox" id="greeter_keyboard_label_holder">
1633 <property name="visible">True</property>
1634 <property name="can_focus">False</property>
1635 <child>
1636 <object class="GtkCheckButton" id="greeter_keyboard_use">
1637 <property name="visible">True</property>
1638 <property name="can_focus">True</property>
1639 <property name="receives_default">False</property>
1640 <property name="xalign">0</property>
1641 <property name="draw_indicator">True</property>
1642 <child>
1643 <object class="GtkBox" id="box14">
1644 <property name="visible">True</property>
1645 <property name="can_focus">False</property>
1646 <child>
1647 <object class="GtkLabel" id="greeter_keyboard_label">
1648 <property name="visible">True</property>
1649 <property name="can_focus">False</property>
1650 <property name="label" translatable="yes" context="greeter|option|keyboard">Keyboard</property>
1651 </object>
1652 <packing>
1653 <property name="expand">False</property>
1654 <property name="fill">True</property>
1655 <property name="position">0</property>
1656 </packing>
1657 </child>
1658 <child>
1659 <object class="GtkImage" id="greeter_keyboard_error">
1660 <property name="can_focus">False</property>
1661 <property name="yalign">0</property>
1662 <property name="pixel_size">12</property>
1663 <property name="icon_name">dialog-warning</property>
1664 <property name="icon_size">1</property>
1665 </object>
1666 <packing>
1667 <property name="expand">False</property>
1668 <property name="fill">True</property>
1669 <property name="position">1</property>
1670 </packing>
1671 </child>
1672 </object>
1673 </child>
1674 </object>
1675 </child>
1676 </object>
1677 <packing>
1678 <property name="left_attach">0</property>
1679 <property name="top_attach">0</property>
1680 </packing>
1681 </child>
1682 <child>
1683 <placeholder/>
1684 </child>
1685 <child>
1686 <placeholder/>
1687 </child>
1688 </object>
1689 <packing>
1690 <property name="left_attach">0</property>
1691 <property name="top_attach">1</property>
1692 <property name="width">2</property>
1693 </packing>
1694 </child>
1695 <child>
1696 <object class="GtkEventBox" id="greeter_screensaver-timeout_label_holder">
1697 <property name="visible">True</property>
1698 <property name="can_focus">False</property>
1699 <child>
1700 <object class="GtkLabel" id="greeter_screensaver-timeout_label">
1701 <property name="visible">True</property>
1702 <property name="can_focus">False</property>
1703 <property name="halign">start</property>
1704 <property name="hexpand">True</property>
1705 <property name="label" translatable="yes" context="option|greeter|screensaver-timeout">Timeout until the screen blanks </property>
1706 <attributes>
1707 <attribute name="weight" value="semibold"/>
1708 </attributes>
1709 </object>
1710 </child>
1711 </object>
1712 <packing>
1713 <property name="left_attach">0</property>
1714 <property name="top_attach">2</property>
1715 <property name="width">2</property>
1716 </packing>
1717 </child>
1718 <child>
1719 <object class="GtkEventBox" id="greeter_allow-debugging_label_holder">
1720 <property name="visible">True</property>
1721 <property name="can_focus">False</property>
1722 <child>
1723 <object class="GtkBox" id="box12">
1724 <property name="visible">True</property>
1725 <property name="can_focus">False</property>
1726 <child>
1727 <object class="GtkCheckButton" id="greeter_allow-debugging_value">
1728 <property name="label" translatable="yes" context="greeter|option|allow-debugging">Debugging mode</property>
1729 <property name="visible">True</property>
1730 <property name="can_focus">True</property>
1731 <property name="receives_default">False</property>
1732 <property name="tooltip_text" translatable="yes" context="greeter|option|allow-debugging">Enable keys to launch GtkInspector
1733 More informative log</property>
1734 <property name="xalign">0</property>
1735 <property name="draw_indicator">True</property>
1736 </object>
1737 <packing>
1738 <property name="expand">False</property>
1739 <property name="fill">True</property>
1740 <property name="position">0</property>
1741 </packing>
1742 </child>
1743 <child>
1744 <object class="GtkImage" id="greeter_allow-debugging_error">
1745 <property name="can_focus">False</property>
1746 <property name="yalign">0</property>
1747 <property name="pixel_size">12</property>
1748 <property name="icon_name">dialog-warning</property>
1749 <property name="icon_size">1</property>
1750 </object>
1751 <packing>
1752 <property name="expand">False</property>
1753 <property name="fill">True</property>
1754 <property name="position">1</property>
1755 </packing>
1756 </child>
1757 </object>
1758 </child>
1759 </object>
1760 <packing>
1761 <property name="left_attach">0</property>
1762 <property name="top_attach">4</property>
14921763 <property name="width">2</property>
14931764 </packing>
14941765 </child>
14991770 </packing>
15001771 </child>
15011772 <child type="tab">
1502 <object class="GtkLabel" id="label4">
1773 <object class="GtkLabel" id="label3">
15031774 <property name="visible">True</property>
15041775 <property name="can_focus">False</property>
1505 <property name="label" translatable="yes">Misc.</property>
1776 <property name="label" translatable="yes" context="tabs">Misc.</property>
15061777 </object>
15071778 <packing>
15081779 <property name="position">3</property>
1780 <property name="tab_expand">True</property>
15091781 <property name="tab_fill">False</property>
15101782 </packing>
15111783 </child>
15171789 </packing>
15181790 </child>
15191791 <child>
1520 <object class="GtkInfoBar" id="no_access_infobar">
1792 <object class="GtkInfoBar" id="infobar">
15211793 <property name="visible">True</property>
15221794 <property name="app_paintable">True</property>
15231795 <property name="can_focus">False</property>
16351907 </object>
16361908 </child>
16371909 </object>
1638 <object class="GtkFileChooserDialog" id="greeter_default-user-image_path_dialog">
1639 <property name="can_focus">False</property>
1640 <property name="border_width">5</property>
1641 <property name="title" translatable="yes">Select image</property>
1642 <property name="role">GtkFileChooserDialog</property>
1643 <property name="window_position">center</property>
1644 <property name="default_width">600</property>
1645 <property name="default_height">450</property>
1646 <property name="type_hint">dialog</property>
1647 <property name="transient_for">settings_window</property>
1648 <property name="create_folders">False</property>
1649 <property name="filter">greeter_default-user-image_path_dialog_filter</property>
1650 <property name="preview_widget">greeter_default-user-image_path_dialog_preview</property>
1651 <child internal-child="vbox">
1652 <object class="GtkBox" id="filechooserdialog-vbox1">
1653 <property name="can_focus">False</property>
1654 <property name="orientation">vertical</property>
1655 <property name="spacing">2</property>
1656 <child internal-child="action_area">
1657 <object class="GtkButtonBox" id="filechooserdialog-action_area1">
1658 <property name="can_focus">False</property>
1659 <property name="layout_style">end</property>
1660 <child>
1661 <object class="GtkButton" id="button2">
1662 <property name="label" context="button">_Cancel</property>
1663 <property name="visible">True</property>
1664 <property name="can_focus">False</property>
1665 <property name="receives_default">True</property>
1666 <property name="image">icon_cancel</property>
1667 <property name="use_underline">True</property>
1668 </object>
1669 <packing>
1670 <property name="expand">False</property>
1671 <property name="fill">True</property>
1672 <property name="position">0</property>
1673 </packing>
1674 </child>
1675 <child>
1676 <object class="GtkButton" id="button1">
1677 <property name="label" context="button">_OK</property>
1678 <property name="visible">True</property>
1679 <property name="can_focus">False</property>
1680 <property name="can_default">True</property>
1681 <property name="has_default">True</property>
1682 <property name="receives_default">True</property>
1683 <property name="image">icon_ok</property>
1684 <property name="use_underline">True</property>
1685 </object>
1686 <packing>
1687 <property name="expand">False</property>
1688 <property name="fill">True</property>
1689 <property name="position">1</property>
1690 </packing>
1691 </child>
1692 </object>
1693 <packing>
1694 <property name="expand">False</property>
1695 <property name="fill">True</property>
1696 <property name="pack_type">end</property>
1697 <property name="position">0</property>
1698 </packing>
1699 </child>
1700 </object>
1701 </child>
1702 <action-widgets>
1703 <action-widget response="-6">button2</action-widget>
1704 <action-widget response="-5">button1</action-widget>
1705 </action-widgets>
1706 </object>
17071910 </interface>
00 <?xml version="1.0" encoding="UTF-8"?>
1 <!-- Generated with glade 3.18.3 -->
12 <interface>
2 <!-- interface-requires gtk+ 3.0 -->
3 <!-- interface-requires gtk_greeter_settings 1.0 -->
3 <requires lib="gtk+" version="3.8"/>
4 <requires lib="gtk_greeter_settings" version="1.0"/>
45 <object class="GtkListStore" id="contexts_model">
56 <columns>
67 <!-- column-name value -->
2728 <object class="GtkTreeModelFilter" id="icons_filter">
2829 <property name="child_model">icons_model</property>
2930 </object>
31 <object class="GtkTreeModelSort" id="icons_sorted">
32 <property name="model">icons_filter</property>
33 </object>
34 <object class="GtkEntryCompletion" id="name_completion">
35 <property name="model">icons_model</property>
36 <property name="text_column">0</property>
37 <property name="inline_completion">True</property>
38 <property name="popup_completion">False</property>
39 </object>
3040 <object class="GtkImage" id="image2">
3141 <property name="visible">True</property>
3242 <property name="can_focus">False</property>
3848 <property name="can_focus">False</property>
3949 <property name="xpad">2</property>
4050 <property name="icon_name">dialog-ok</property>
41 </object>
42 <object class="GtkTreeModelSort" id="icons_sorted">
43 <property name="model">icons_filter</property>
4451 </object>
4552 <object class="IconChooserDialog" id="icon_chooser_dialog">
4653 <property name="width_request">400</property>
147154 </packing>
148155 </child>
149156 <child>
150 <object class="GtkEntry" id="name">
157 <object class="GtkEntry" id="name_entry">
151158 <property name="visible">True</property>
152159 <property name="can_focus">True</property>
153160 <property name="invisible_char">●</property>
154 <property name="invisible_char_set">True</property>
155161 <property name="completion">name_completion</property>
156162 <signal name="changed" handler="on_name_changed" swapped="no"/>
157163 </object>
166172 <property name="left_attach">0</property>
167173 <property name="top_attach">0</property>
168174 <property name="width">2</property>
169 <property name="height">1</property>
170175 </packing>
171176 </child>
172177 <child>
180185 <packing>
181186 <property name="left_attach">0</property>
182187 <property name="top_attach">1</property>
183 <property name="width">1</property>
184 <property name="height">1</property>
185188 </packing>
186189 </child>
187190 <child>
195198 <packing>
196199 <property name="left_attach">1</property>
197200 <property name="top_attach">1</property>
198 <property name="width">1</property>
199 <property name="height">1</property>
200 </packing>
201 </child>
202 <child>
203 <object class="GtkImage" id="preview">
204 <property name="visible">True</property>
205 <property name="can_focus">False</property>
206 <property name="halign">center</property>
207 <property name="valign">start</property>
208 <property name="stock">gtk-missing-image</property>
209 <property name="pixel_size">32</property>
210 <property name="icon-size">6</property>
211 </object>
212 <packing>
213 <property name="left_attach">2</property>
214 <property name="top_attach">0</property>
215 <property name="width">1</property>
216 <property name="height">2</property>
217201 </packing>
218202 </child>
219203 <child>
232216 <property name="left_attach">0</property>
233217 <property name="top_attach">3</property>
234218 <property name="width">3</property>
235 <property name="height">1</property>
236219 </packing>
237220 </child>
238221 <child>
288271 <property name="left_attach">1</property>
289272 <property name="top_attach">2</property>
290273 <property name="width">2</property>
291 <property name="height">1</property>
292274 </packing>
293275 </child>
294276 <child>
327309 <packing>
328310 <property name="left_attach">0</property>
329311 <property name="top_attach">2</property>
330 <property name="width">1</property>
331 <property name="height">1</property>
312 </packing>
313 </child>
314 <child>
315 <object class="GtkImage" id="preview_image">
316 <property name="width_request">32</property>
317 <property name="height_request">32</property>
318 <property name="visible">True</property>
319 <property name="can_focus">False</property>
320 <property name="halign">center</property>
321 <property name="valign">start</property>
322 <property name="pixel_size">32</property>
323 <property name="icon_size">6</property>
324 </object>
325 <packing>
326 <property name="left_attach">2</property>
327 <property name="top_attach">0</property>
328 <property name="height">2</property>
332329 </packing>
333330 </child>
334331 </object>
345342 <action-widget response="-5">ok_button</action-widget>
346343 </action-widgets>
347344 </object>
348 <object class="GtkEntryCompletion" id="name_completion">
349 <property name="model">icons_model</property>
350 <property name="text_column">0</property>
351 <property name="inline_completion">True</property>
352 <property name="popup_completion">False</property>
353 </object>
354345 </interface>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!-- Generated with glade 3.18.3 -->
2 <interface>
3 <requires lib="gtk+" version="3.8"/>
4 <object class="GtkImage" id="cancel_image">
5 <property name="visible">True</property>
6 <property name="can_focus">False</property>
7 <property name="icon_name">dialog-cancel</property>
8 </object>
9 <object class="GtkFileFilter" id="filefilter1">
10 <mime-types>
11 <mime-type>image/*</mime-type>
12 </mime-types>
13 </object>
14 <object class="GtkImage" id="ok_image">
15 <property name="visible">True</property>
16 <property name="can_focus">False</property>
17 <property name="icon_name">dialog-ok</property>
18 </object>
19 <object class="GtkImage" id="preview_image">
20 <property name="visible">True</property>
21 <property name="can_focus">False</property>
22 <property name="valign">start</property>
23 <property name="margin_right">8</property>
24 <property name="icon_name">unknown</property>
25 </object>
26 <object class="GtkFileChooserDialog" id="dialog">
27 <property name="can_focus">False</property>
28 <property name="type_hint">dialog</property>
29 <property name="filter">filefilter1</property>
30 <property name="preview_widget">preview_image</property>
31 <child internal-child="vbox">
32 <object class="GtkBox" id="filechooserdialog-vbox1">
33 <property name="can_focus">False</property>
34 <property name="orientation">vertical</property>
35 <property name="spacing">2</property>
36 <child internal-child="action_area">
37 <object class="GtkButtonBox" id="filechooserdialog-action_area1">
38 <property name="can_focus">False</property>
39 <property name="layout_style">end</property>
40 <child>
41 <object class="GtkButton" id="cancel_button">
42 <property name="label" translatable="yes">_Cancel</property>
43 <property name="visible">True</property>
44 <property name="can_focus">True</property>
45 <property name="receives_default">True</property>
46 <property name="image">cancel_image</property>
47 <property name="use_underline">True</property>
48 </object>
49 <packing>
50 <property name="expand">True</property>
51 <property name="fill">True</property>
52 <property name="position">0</property>
53 </packing>
54 </child>
55 <child>
56 <object class="GtkButton" id="ok_button">
57 <property name="label" translatable="yes">_OK</property>
58 <property name="visible">True</property>
59 <property name="can_focus">True</property>
60 <property name="can_default">True</property>
61 <property name="receives_default">True</property>
62 <property name="image">ok_image</property>
63 <property name="use_underline">True</property>
64 </object>
65 <packing>
66 <property name="expand">True</property>
67 <property name="fill">True</property>
68 <property name="position">1</property>
69 </packing>
70 </child>
71 </object>
72 <packing>
73 <property name="expand">False</property>
74 <property name="fill">False</property>
75 <property name="position">0</property>
76 </packing>
77 </child>
78 <child>
79 <placeholder/>
80 </child>
81 </object>
82 </child>
83 <action-widgets>
84 <action-widget response="-6">cancel_button</action-widget>
85 <action-widget response="-5">ok_button</action-widget>
86 </action-widgets>
87 </object>
88 </interface>
+0
-456
data/IndicatorChooserDialog.ui less more
0 <?xml version="1.0" encoding="UTF-8"?>
1 <interface>
2 <!-- interface-requires gtk+ 3.0 -->
3 <!-- interface-requires gtk_greeter_settings 1.0 -->
4 <object class="GtkImage" id="image1">
5 <property name="visible">True</property>
6 <property name="can_focus">False</property>
7 <property name="xpad">2</property>
8 <property name="icon_name">list-add</property>
9 </object>
10 <object class="GtkImage" id="image2">
11 <property name="visible">True</property>
12 <property name="can_focus">False</property>
13 <property name="xpad">2</property>
14 <property name="icon_name">window-close</property>
15 </object>
16 <object class="GtkImage" id="image3">
17 <property name="visible">True</property>
18 <property name="can_focus">False</property>
19 <property name="xpad">2</property>
20 <property name="icon_name">dialog-ok</property>
21 </object>
22 <object class="IndicatorChooserDialog" id="indicator_chooser_dialog">
23 <property name="width_request">400</property>
24 <property name="can_focus">False</property>
25 <property name="title" translatable="yes" context="indicators-dialog">Select indicator</property>
26 <property name="modal">True</property>
27 <property name="window_position">center</property>
28 <property name="destroy_with_parent">True</property>
29 <property name="icon_name">application-x-executable</property>
30 <property name="type_hint">dialog</property>
31 <child internal-child="vbox">
32 <object class="GtkBox" id="dialog-vbox1">
33 <property name="can_focus">False</property>
34 <property name="margin_left">8</property>
35 <property name="margin_right">8</property>
36 <property name="margin_top">8</property>
37 <property name="margin_bottom">8</property>
38 <property name="orientation">vertical</property>
39 <property name="spacing">8</property>
40 <child internal-child="action_area">
41 <object class="GtkButtonBox" id="dialog-action_area1">
42 <property name="can_focus">False</property>
43 <property name="layout_style">end</property>
44 <child>
45 <object class="GtkButton" id="cancel_button">
46 <property name="label" translatable="yes" context="button">_Close</property>
47 <property name="visible">True</property>
48 <property name="can_focus">True</property>
49 <property name="receives_default">True</property>
50 <property name="image">image2</property>
51 <property name="use_underline">True</property>
52 </object>
53 <packing>
54 <property name="expand">False</property>
55 <property name="fill">True</property>
56 <property name="position">0</property>
57 </packing>
58 </child>
59 <child>
60 <object class="GtkButton" id="ok_button">
61 <property name="label" translatable="yes" context="button">_OK</property>
62 <property name="visible">True</property>
63 <property name="can_focus">True</property>
64 <property name="can_default">True</property>
65 <property name="has_default">True</property>
66 <property name="receives_default">True</property>
67 <property name="tooltip_text" translatable="yes">Add selected indicator to the list and close this window</property>
68 <property name="image">image3</property>
69 <property name="use_underline">True</property>
70 </object>
71 <packing>
72 <property name="expand">False</property>
73 <property name="fill">True</property>
74 <property name="position">1</property>
75 </packing>
76 </child>
77 <child>
78 <object class="GtkBox" id="box1">
79 <property name="visible">True</property>
80 <property name="can_focus">False</property>
81 <property name="orientation">vertical</property>
82 <child>
83 <object class="GtkButton" id="add_button">
84 <property name="label" translatable="yes" context="button">_Add</property>
85 <property name="visible">True</property>
86 <property name="can_focus">True</property>
87 <property name="receives_default">True</property>
88 <property name="has_tooltip">True</property>
89 <property name="tooltip_text" translatable="yes">Add selected indicator to the list without closing this window</property>
90 <property name="image">image1</property>
91 <property name="use_underline">True</property>
92 <signal name="clicked" handler="on_add_clicked" swapped="no"/>
93 </object>
94 <packing>
95 <property name="expand">False</property>
96 <property name="fill">True</property>
97 <property name="position">0</property>
98 </packing>
99 </child>
100 </object>
101 <packing>
102 <property name="expand">False</property>
103 <property name="fill">True</property>
104 <property name="position">2</property>
105 <property name="secondary">True</property>
106 <property name="non_homogeneous">True</property>
107 </packing>
108 </child>
109 </object>
110 <packing>
111 <property name="expand">False</property>
112 <property name="fill">True</property>
113 <property name="pack_type">end</property>
114 <property name="position">0</property>
115 </packing>
116 </child>
117 <child>
118 <object class="GtkBox" id="box7">
119 <property name="visible">True</property>
120 <property name="can_focus">False</property>
121 <property name="valign">start</property>
122 <property name="hexpand">True</property>
123 <property name="orientation">vertical</property>
124 <property name="spacing">8</property>
125 <child>
126 <object class="GtkRadioButton" id="short_choice">
127 <property name="visible">True</property>
128 <property name="can_focus">True</property>
129 <property name="receives_default">False</property>
130 <property name="xalign">0</property>
131 <property name="active">True</property>
132 <property name="draw_indicator">True</property>
133 <signal name="toggled" handler="on_short_choice_toggled" swapped="no"/>
134 <child>
135 <object class="GtkLabel" id="label5">
136 <property name="visible">True</property>
137 <property name="can_focus">False</property>
138 <property name="halign">start</property>
139 <property name="hexpand">True</property>
140 <property name="label" translatable="yes" context="indicators-dialog">Short name</property>
141 <attributes>
142 <attribute name="weight" value="semibold"/>
143 </attributes>
144 </object>
145 </child>
146 </object>
147 <packing>
148 <property name="expand">False</property>
149 <property name="fill">True</property>
150 <property name="position">0</property>
151 </packing>
152 </child>
153 <child>
154 <object class="GtkComboBox" id="combobox1">
155 <property name="visible">True</property>
156 <property name="can_focus">False</property>
157 <property name="margin_left">24</property>
158 <property name="model">short_model</property>
159 <property name="has_entry">True</property>
160 <property name="entry_text_column">0</property>
161 <child internal-child="entry">
162 <object class="GtkEntry" id="short_value">
163 <property name="can_focus">True</property>
164 <property name="is_focus">True</property>
165 <signal name="changed" handler="on_short_value_changed" swapped="no"/>
166 <signal name="activate" handler="on_short_value_activate" swapped="no"/>
167 </object>
168 </child>
169 </object>
170 <packing>
171 <property name="expand">False</property>
172 <property name="fill">True</property>
173 <property name="position">1</property>
174 </packing>
175 </child>
176 <child>
177 <object class="GtkLabel" id="label17">
178 <property name="visible">True</property>
179 <property name="can_focus">False</property>
180 <property name="halign">start</property>
181 <property name="margin_left">24</property>
182 <property name="label" translatable="yes" context="indicators-dialog">Indicators that greeter can find without using absolute pathes</property>
183 <attributes>
184 <attribute name="style" value="oblique"/>
185 </attributes>
186 </object>
187 <packing>
188 <property name="expand">False</property>
189 <property name="fill">True</property>
190 <property name="position">2</property>
191 </packing>
192 </child>
193 <child>
194 <object class="GtkRadioButton" id="path_choice">
195 <property name="visible">True</property>
196 <property name="can_focus">True</property>
197 <property name="receives_default">False</property>
198 <property name="xalign">0</property>
199 <property name="draw_indicator">True</property>
200 <property name="group">short_choice</property>
201 <child>
202 <object class="GtkLabel" id="label4">
203 <property name="visible">True</property>
204 <property name="can_focus">False</property>
205 <property name="halign">start</property>
206 <property name="hexpand">True</property>
207 <property name="label" translatable="yes" context="indicators-dialog">Path</property>
208 <attributes>
209 <attribute name="weight" value="semibold"/>
210 </attributes>
211 </object>
212 </child>
213 </object>
214 <packing>
215 <property name="expand">False</property>
216 <property name="fill">True</property>
217 <property name="position">3</property>
218 </packing>
219 </child>
220 <child>
221 <object class="GtkFileChooserButton" id="path_value">
222 <property name="visible">True</property>
223 <property name="can_focus">False</property>
224 <property name="margin_left">24</property>
225 <property name="filter">library_file_filter</property>
226 <signal name="file-set" handler="on_path_value_changed" swapped="no"/>
227 </object>
228 <packing>
229 <property name="expand">False</property>
230 <property name="fill">True</property>
231 <property name="position">4</property>
232 </packing>
233 </child>
234 <child>
235 <object class="GtkLabel" id="label16">
236 <property name="visible">True</property>
237 <property name="can_focus">False</property>
238 <property name="halign">start</property>
239 <property name="margin_left">24</property>
240 <property name="label" translatable="yes" context="indicators-dialog">Absolute path to indicator library file (*.so)</property>
241 <attributes>
242 <attribute name="style" value="oblique"/>
243 </attributes>
244 </object>
245 <packing>
246 <property name="expand">False</property>
247 <property name="fill">True</property>
248 <property name="position">5</property>
249 </packing>
250 </child>
251 <child>
252 <object class="GtkSeparator" id="separator2">
253 <property name="visible">True</property>
254 <property name="can_focus">False</property>
255 </object>
256 <packing>
257 <property name="expand">False</property>
258 <property name="fill">True</property>
259 <property name="position">6</property>
260 </packing>
261 </child>
262 <child>
263 <object class="GtkGrid" id="grid1">
264 <property name="visible">True</property>
265 <property name="can_focus">False</property>
266 <property name="halign">start</property>
267 <property name="row_spacing">4</property>
268 <property name="column_spacing">8</property>
269 <child>
270 <object class="GtkLabel" id="label2">
271 <property name="visible">True</property>
272 <property name="can_focus">False</property>
273 <property name="halign">start</property>
274 <property name="label" translatable="yes" context="indicators-dialog">Fills the maximum available space</property>
275 <attributes>
276 <attribute name="style" value="oblique"/>
277 </attributes>
278 </object>
279 <packing>
280 <property name="left_attach">1</property>
281 <property name="top_attach">0</property>
282 <property name="width">1</property>
283 <property name="height">1</property>
284 </packing>
285 </child>
286 <child>
287 <object class="GtkRadioButton" id="spacer_choice">
288 <property name="visible">True</property>
289 <property name="can_focus">True</property>
290 <property name="receives_default">False</property>
291 <property name="xalign">0</property>
292 <property name="draw_indicator">True</property>
293 <property name="group">short_choice</property>
294 <child>
295 <object class="GtkLabel" id="label1">
296 <property name="visible">True</property>
297 <property name="can_focus">False</property>
298 <property name="halign">start</property>
299 <property name="hexpand">True</property>
300 <property name="label" translatable="yes" context="indicators-dialog">Spacer</property>
301 <attributes>
302 <attribute name="weight" value="semibold"/>
303 </attributes>
304 </object>
305 </child>
306 </object>
307 <packing>
308 <property name="left_attach">0</property>
309 <property name="top_attach">0</property>
310 <property name="width">1</property>
311 <property name="height">1</property>
312 </packing>
313 </child>
314 <child>
315 <object class="GtkRadioButton" id="separator_choice">
316 <property name="visible">True</property>
317 <property name="can_focus">True</property>
318 <property name="receives_default">False</property>
319 <property name="xalign">0</property>
320 <property name="draw_indicator">True</property>
321 <property name="group">short_choice</property>
322 <child>
323 <object class="GtkLabel" id="label3">
324 <property name="visible">True</property>
325 <property name="can_focus">False</property>
326 <property name="halign">start</property>
327 <property name="hexpand">True</property>
328 <property name="label" translatable="yes" context="indicators-dialog">Separator</property>
329 <attributes>
330 <attribute name="weight" value="semibold"/>
331 </attributes>
332 </object>
333 </child>
334 </object>
335 <packing>
336 <property name="left_attach">0</property>
337 <property name="top_attach">1</property>
338 <property name="width">1</property>
339 <property name="height">1</property>
340 </packing>
341 </child>
342 <child>
343 <object class="GtkLabel" id="label6">
344 <property name="visible">True</property>
345 <property name="can_focus">False</property>
346 <property name="halign">start</property>
347 <property name="label" translatable="yes" context="indicators-dialog">Draw a separator</property>
348 <attributes>
349 <attribute name="style" value="oblique"/>
350 </attributes>
351 </object>
352 <packing>
353 <property name="left_attach">1</property>
354 <property name="top_attach">1</property>
355 <property name="width">1</property>
356 <property name="height">1</property>
357 </packing>
358 </child>
359 </object>
360 <packing>
361 <property name="expand">False</property>
362 <property name="fill">True</property>
363 <property name="position">7</property>
364 </packing>
365 </child>
366 <child>
367 <object class="GtkInfoBar" id="infobar">
368 <property name="visible">True</property>
369 <property name="app_paintable">True</property>
370 <property name="can_focus">False</property>
371 <property name="message_type">warning</property>
372 <child internal-child="content_area">
373 <object class="GtkBox" id="infobar-content_area1">
374 <property name="can_focus">False</property>
375 <property name="border_width">8</property>
376 <property name="spacing">16</property>
377 <child>
378 <object class="GtkLabel" id="message">
379 <property name="visible">True</property>
380 <property name="can_focus">False</property>
381 <property name="label">[message]</property>
382 </object>
383 <packing>
384 <property name="expand">True</property>
385 <property name="fill">True</property>
386 <property name="position">0</property>
387 </packing>
388 </child>
389 </object>
390 <packing>
391 <property name="expand">True</property>
392 <property name="fill">True</property>
393 <property name="position">0</property>
394 </packing>
395 </child>
396 <child internal-child="action_area">
397 <object class="GtkButtonBox" id="infobar-action_area1">
398 <property name="can_focus">False</property>
399 <property name="border_width">5</property>
400 <property name="orientation">vertical</property>
401 <property name="layout_style">start</property>
402 <child>
403 <placeholder/>
404 </child>
405 </object>
406 <packing>
407 <property name="expand">False</property>
408 <property name="fill">True</property>
409 <property name="position">1</property>
410 </packing>
411 </child>
412 </object>
413 <packing>
414 <property name="expand">False</property>
415 <property name="fill">True</property>
416 <property name="position">8</property>
417 </packing>
418 </child>
419 </object>
420 <packing>
421 <property name="expand">True</property>
422 <property name="fill">True</property>
423 <property name="position">1</property>
424 </packing>
425 </child>
426 <child>
427 <object class="GtkSeparator" id="separator1">
428 <property name="visible">True</property>
429 <property name="can_focus">False</property>
430 </object>
431 <packing>
432 <property name="expand">False</property>
433 <property name="fill">True</property>
434 <property name="position">2</property>
435 </packing>
436 </child>
437 </object>
438 </child>
439 <action-widgets>
440 <action-widget response="-7">cancel_button</action-widget>
441 <action-widget response="-5">ok_button</action-widget>
442 </action-widgets>
443 </object>
444 <object class="GtkFileFilter" id="library_file_filter">
445 <mime-types>
446 <mime-type>application/x-sharedlib</mime-type>
447 </mime-types>
448 </object>
449 <object class="GtkListStore" id="short_model">
450 <columns>
451 <!-- column-name name -->
452 <column type="gchararray"/>
453 </columns>
454 </object>
455 </interface>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!-- Generated with glade 3.18.3 -->
2 <interface>
3 <requires lib="gtk+" version="3.8"/>
4 <requires lib="gtk_greeter_settings" version="1.0"/>
5 <object class="GtkImage" id="image1">
6 <property name="visible">True</property>
7 <property name="can_focus">False</property>
8 <property name="xpad">2</property>
9 <property name="icon_name">list-add</property>
10 </object>
11 <object class="GtkImage" id="image2">
12 <property name="visible">True</property>
13 <property name="can_focus">False</property>
14 <property name="xpad">2</property>
15 <property name="icon_name">window-close</property>
16 </object>
17 <object class="GtkImage" id="image3">
18 <property name="visible">True</property>
19 <property name="can_focus">False</property>
20 <property name="xpad">2</property>
21 <property name="icon_name">dialog-ok</property>
22 </object>
23 <object class="GtkFileFilter" id="library_file_filter">
24 <mime-types>
25 <mime-type>application/x-sharedlib</mime-type>
26 </mime-types>
27 </object>
28 <object class="GtkListStore" id="option_path_model">
29 <columns>
30 <!-- column-name title -->
31 <column type="gchararray"/>
32 <!-- column-name type -->
33 <column type="gchararray"/>
34 <!-- column-name icon -->
35 <column type="gchararray"/>
36 </columns>
37 <data>
38 <row>
39 <col id="0" translatable="yes" context="option-entry|indicators">Select file...</col>
40 <col id="1">select-path</col>
41 <col id="2">system-search</col>
42 </row>
43 <row>
44 <col id="0">-</col>
45 <col id="1">separator</col>
46 <col id="2">-</col>
47 </row>
48 </data>
49 </object>
50 <object class="IndicatorPropertiesDialog" id="indicator_properties_dialog">
51 <property name="width_request">400</property>
52 <property name="can_focus">False</property>
53 <property name="title" translatable="yes" context="option-entry|indicators">Indicator properties</property>
54 <property name="resizable">False</property>
55 <property name="modal">True</property>
56 <property name="window_position">center</property>
57 <property name="destroy_with_parent">True</property>
58 <property name="icon_name">application-x-executable</property>
59 <property name="type_hint">dialog</property>
60 <child internal-child="vbox">
61 <object class="GtkBox" id="dialog-vbox1">
62 <property name="can_focus">False</property>
63 <property name="margin_left">8</property>
64 <property name="margin_right">8</property>
65 <property name="margin_top">8</property>
66 <property name="margin_bottom">8</property>
67 <property name="orientation">vertical</property>
68 <property name="spacing">8</property>
69 <child internal-child="action_area">
70 <object class="GtkButtonBox" id="dialog-action_area1">
71 <property name="can_focus">False</property>
72 <property name="homogeneous">True</property>
73 <property name="layout_style">end</property>
74 <child>
75 <object class="GtkButton" id="cancel_button">
76 <property name="label" translatable="yes" context="button">_Close</property>
77 <property name="visible">True</property>
78 <property name="can_focus">True</property>
79 <property name="receives_default">True</property>
80 <property name="image">image2</property>
81 <property name="use_underline">True</property>
82 </object>
83 <packing>
84 <property name="expand">False</property>
85 <property name="fill">True</property>
86 <property name="position">0</property>
87 </packing>
88 </child>
89 <child>
90 <object class="GtkButton" id="ok_button">
91 <property name="label" translatable="yes" context="button">_OK</property>
92 <property name="visible">True</property>
93 <property name="can_focus">True</property>
94 <property name="can_default">True</property>
95 <property name="has_default">True</property>
96 <property name="receives_default">True</property>
97 <property name="image">image3</property>
98 <property name="use_underline">True</property>
99 </object>
100 <packing>
101 <property name="expand">False</property>
102 <property name="fill">True</property>
103 <property name="position">1</property>
104 </packing>
105 </child>
106 <child>
107 <object class="GtkBox" id="box1">
108 <property name="visible">True</property>
109 <property name="can_focus">False</property>
110 <property name="orientation">vertical</property>
111 <property name="homogeneous">True</property>
112 <child>
113 <object class="GtkButton" id="add_button">
114 <property name="label" translatable="yes" context="button">_Add</property>
115 <property name="visible">True</property>
116 <property name="can_focus">True</property>
117 <property name="receives_default">True</property>
118 <property name="image">image1</property>
119 <property name="use_underline">True</property>
120 <signal name="clicked" handler="on_add_clicked" swapped="no"/>
121 </object>
122 <packing>
123 <property name="expand">False</property>
124 <property name="fill">True</property>
125 <property name="position">0</property>
126 </packing>
127 </child>
128 </object>
129 <packing>
130 <property name="expand">False</property>
131 <property name="fill">True</property>
132 <property name="position">2</property>
133 <property name="secondary">True</property>
134 <property name="non_homogeneous">True</property>
135 </packing>
136 </child>
137 </object>
138 <packing>
139 <property name="expand">False</property>
140 <property name="fill">True</property>
141 <property name="pack_type">end</property>
142 <property name="position">0</property>
143 </packing>
144 </child>
145 <child>
146 <object class="GtkBox" id="box2">
147 <property name="visible">True</property>
148 <property name="can_focus">False</property>
149 <property name="spacing">6</property>
150 <child>
151 <object class="GtkRadioButton" id="option_type_indicator_choice">
152 <property name="label" translatable="yes" context="option-entry|indicators">Indicator</property>
153 <property name="visible">True</property>
154 <property name="can_focus">True</property>
155 <property name="receives_default">False</property>
156 <property name="xalign">0</property>
157 <property name="active">True</property>
158 <property name="draw_indicator">True</property>
159 </object>
160 <packing>
161 <property name="expand">False</property>
162 <property name="fill">True</property>
163 <property name="position">0</property>
164 </packing>
165 </child>
166 <child>
167 <object class="GtkComboBoxText" id="option_type_types">
168 <property name="visible">True</property>
169 <property name="can_focus">False</property>
170 <signal name="changed" handler="on_option_type_types_changed" swapped="no"/>
171 </object>
172 <packing>
173 <property name="expand">False</property>
174 <property name="fill">True</property>
175 <property name="position">1</property>
176 </packing>
177 </child>
178 </object>
179 <packing>
180 <property name="expand">False</property>
181 <property name="fill">True</property>
182 <property name="position">0</property>
183 </packing>
184 </child>
185 <child>
186 <object class="GtkBox" id="option_type_indicator_box">
187 <property name="visible">True</property>
188 <property name="can_focus">False</property>
189 <property name="margin_left">24</property>
190 <property name="orientation">vertical</property>
191 <property name="spacing">4</property>
192 <child>
193 <object class="GtkGrid" id="common_options_box">
194 <property name="visible">True</property>
195 <property name="can_focus">False</property>
196 <property name="row_spacing">8</property>
197 <property name="column_spacing">6</property>
198 <child>
199 <object class="GtkCheckButton" id="option_text_use">
200 <property name="label" translatable="yes" context="option-entry|indicators">Display label</property>
201 <property name="visible">True</property>
202 <property name="can_focus">True</property>
203 <property name="receives_default">False</property>
204 <property name="xalign">0</property>
205 <property name="draw_indicator">True</property>
206 </object>
207 <packing>
208 <property name="left_attach">0</property>
209 <property name="top_attach">0</property>
210 </packing>
211 </child>
212 <child>
213 <object class="GtkEntry" id="option_text_value">
214 <property name="visible">True</property>
215 <property name="can_focus">True</property>
216 <property name="hexpand">True</property>
217 <property name="placeholder_text" translatable="yes" context="option-entry|indicators">Leave empty to use default value</property>
218 </object>
219 <packing>
220 <property name="left_attach">1</property>
221 <property name="top_attach">0</property>
222 </packing>
223 </child>
224 <child>
225 <object class="GtkCheckButton" id="option_image_use">
226 <property name="label" translatable="yes" context="option-entry|indicators">Display image</property>
227 <property name="visible">True</property>
228 <property name="can_focus">True</property>
229 <property name="receives_default">False</property>
230 <property name="xalign">0</property>
231 <property name="draw_indicator">True</property>
232 </object>
233 <packing>
234 <property name="left_attach">0</property>
235 <property name="top_attach">1</property>
236 </packing>
237 </child>
238 <child>
239 <object class="GtkMenuButton" id="option_image_button">
240 <property name="visible">True</property>
241 <property name="can_focus">True</property>
242 <property name="receives_default">True</property>
243 <property name="halign">start</property>
244 <child>
245 <object class="GtkBox" id="box3">
246 <property name="visible">True</property>
247 <property name="can_focus">False</property>
248 <property name="spacing">4</property>
249 <child>
250 <object class="GtkImage" id="option_image_image">
251 <property name="width_request">24</property>
252 <property name="height_request">24</property>
253 <property name="visible">True</property>
254 <property name="can_focus">False</property>
255 <property name="pixel_size">24</property>
256 <property name="icon_name">avatar-default</property>
257 <property name="icon_size">1</property>
258 </object>
259 <packing>
260 <property name="expand">False</property>
261 <property name="fill">True</property>
262 <property name="position">0</property>
263 </packing>
264 </child>
265 <child>
266 <object class="GtkLabel" id="option_image_label">
267 <property name="height_request">24</property>
268 <property name="visible">True</property>
269 <property name="can_focus">False</property>
270 <property name="label">[icon]</property>
271 </object>
272 <packing>
273 <property name="expand">False</property>
274 <property name="fill">True</property>
275 <property name="position">1</property>
276 </packing>
277 </child>
278 </object>
279 </child>
280 </object>
281 <packing>
282 <property name="left_attach">1</property>
283 <property name="top_attach">1</property>
284 </packing>
285 </child>
286 </object>
287 <packing>
288 <property name="expand">False</property>
289 <property name="fill">True</property>
290 <property name="position">0</property>
291 </packing>
292 </child>
293 <child>
294 <object class="GtkNotebook" id="custom_options_box">
295 <property name="visible">True</property>
296 <property name="can_focus">False</property>
297 <property name="valign">start</property>
298 <property name="show_tabs">False</property>
299 <property name="show_border">False</property>
300 <child>
301 <object class="GtkBox" id="custom_options_external">
302 <property name="can_focus">False</property>
303 <property name="orientation">vertical</property>
304 <property name="spacing">4</property>
305 <child>
306 <object class="GtkLabel" id="label2">
307 <property name="visible">True</property>
308 <property name="can_focus">False</property>
309 <property name="halign">start</property>
310 <property name="label" translatable="yes" context="option-entry|indicators">Indicator library/service:</property>
311 </object>
312 <packing>
313 <property name="expand">False</property>
314 <property name="fill">True</property>
315 <property name="position">0</property>
316 </packing>
317 </child>
318 <child>
319 <object class="GtkComboBox" id="option_path_combo">
320 <property name="visible">True</property>
321 <property name="can_focus">False</property>
322 <property name="model">option_path_model</property>
323 <property name="has_entry">True</property>
324 <property name="entry_text_column">0</property>
325 <property name="id_column">1</property>
326 <child>
327 <object class="GtkCellRendererPixbuf" id="cellrenderertext1"/>
328 <attributes>
329 <attribute name="icon-name">2</attribute>
330 </attributes>
331 </child>
332 <child>
333 <object class="GtkCellRendererText" id="cellrenderertext2"/>
334 <attributes>
335 <attribute name="text">0</attribute>
336 </attributes>
337 </child>
338 <child internal-child="entry">
339 <object class="GtkEntry" id="option_path_entry">
340 <property name="can_focus">True</property>
341 </object>
342 </child>
343 </object>
344 <packing>
345 <property name="expand">False</property>
346 <property name="fill">True</property>
347 <property name="position">1</property>
348 </packing>
349 </child>
350 </object>
351 </child>
352 <child type="tab">
353 <object class="GtkLabel" id="label3">
354 <property name="visible">True</property>
355 <property name="can_focus">False</property>
356 <property name="label" translatable="yes">page 1</property>
357 </object>
358 <packing>
359 <property name="tab_fill">False</property>
360 </packing>
361 </child>
362 <child>
363 <object class="GtkBox" id="custom_options_power">
364 <property name="can_focus">False</property>
365 <property name="orientation">vertical</property>
366 <child>
367 <object class="GtkCheckButton" id="option_hide_disabled_value">
368 <property name="label" translatable="yes" context="option-entry|indicators">Hide disabled power actions</property>
369 <property name="visible">True</property>
370 <property name="can_focus">True</property>
371 <property name="receives_default">False</property>
372 <property name="xalign">0</property>
373 <property name="draw_indicator">True</property>
374 </object>
375 <packing>
376 <property name="expand">False</property>
377 <property name="fill">True</property>
378 <property name="position">0</property>
379 </packing>
380 </child>
381 </object>
382 <packing>
383 <property name="position">1</property>
384 </packing>
385 </child>
386 <child type="tab">
387 <object class="GtkLabel" id="label1">
388 <property name="visible">True</property>
389 <property name="can_focus">False</property>
390 <property name="label" translatable="yes">page 2</property>
391 </object>
392 <packing>
393 <property name="position">1</property>
394 <property name="tab_fill">False</property>
395 </packing>
396 </child>
397 <child>
398 <object class="GtkBox" id="custom_options_text">
399 <property name="visible">True</property>
400 <property name="can_focus">False</property>
401 <property name="orientation">vertical</property>
402 <property name="spacing">4</property>
403 <child>
404 <object class="GtkLabel" id="label5">
405 <property name="visible">True</property>
406 <property name="can_focus">False</property>
407 <property name="halign">start</property>
408 <property name="label" translatable="yes" context="option-entry|indicators">Text to display:</property>
409 </object>
410 <packing>
411 <property name="expand">False</property>
412 <property name="fill">True</property>
413 <property name="position">0</property>
414 </packing>
415 </child>
416 <child>
417 <object class="GtkEntry" id="option_text_fallback_value">
418 <property name="visible">True</property>
419 <property name="can_focus">True</property>
420 </object>
421 <packing>
422 <property name="expand">False</property>
423 <property name="fill">True</property>
424 <property name="position">1</property>
425 </packing>
426 </child>
427 </object>
428 <packing>
429 <property name="position">2</property>
430 </packing>
431 </child>
432 <child type="tab">
433 <object class="GtkLabel" id="label4">
434 <property name="visible">True</property>
435 <property name="can_focus">False</property>
436 <property name="label" translatable="yes">page 3</property>
437 </object>
438 <packing>
439 <property name="position">2</property>
440 <property name="tab_fill">False</property>
441 </packing>
442 </child>
443 </object>
444 <packing>
445 <property name="expand">False</property>
446 <property name="fill">True</property>
447 <property name="position">1</property>
448 </packing>
449 </child>
450 </object>
451 <packing>
452 <property name="expand">False</property>
453 <property name="fill">True</property>
454 <property name="position">2</property>
455 </packing>
456 </child>
457 <child>
458 <object class="GtkRadioButton" id="option_type_spacer_choice">
459 <property name="label" translatable="yes" context="option-entry|indicators">Spacer - fills the maximum available space</property>
460 <property name="visible">True</property>
461 <property name="can_focus">True</property>
462 <property name="receives_default">False</property>
463 <property name="xalign">0</property>
464 <property name="draw_indicator">True</property>
465 <property name="group">option_type_indicator_choice</property>
466 </object>
467 <packing>
468 <property name="expand">False</property>
469 <property name="fill">True</property>
470 <property name="position">3</property>
471 </packing>
472 </child>
473 <child>
474 <object class="GtkRadioButton" id="option_type_separator_choice">
475 <property name="label" translatable="yes" context="option-entry|indicators">Separator - draw a separator</property>
476 <property name="visible">True</property>
477 <property name="can_focus">True</property>
478 <property name="receives_default">False</property>
479 <property name="xalign">0</property>
480 <property name="draw_indicator">True</property>
481 <property name="group">option_type_indicator_choice</property>
482 </object>
483 <packing>
484 <property name="expand">False</property>
485 <property name="fill">True</property>
486 <property name="position">4</property>
487 </packing>
488 </child>
489 <child>
490 <object class="GtkInfoBar" id="infobar">
491 <property name="app_paintable">True</property>
492 <property name="can_focus">False</property>
493 <property name="message_type">warning</property>
494 <child internal-child="action_area">
495 <object class="GtkButtonBox" id="infobar-action_area">
496 <property name="can_focus">False</property>
497 <property name="orientation">vertical</property>
498 <property name="layout_style">start</property>
499 <child>
500 <placeholder/>
501 </child>
502 </object>
503 <packing>
504 <property name="expand">False</property>
505 <property name="fill">True</property>
506 <property name="position">1</property>
507 </packing>
508 </child>
509 <child internal-child="content_area">
510 <object class="GtkBox" id="infobar-content_area">
511 <property name="can_focus">False</property>
512 <property name="spacing">16</property>
513 <child>
514 <object class="GtkLabel" id="message">
515 <property name="visible">True</property>
516 <property name="can_focus">False</property>
517 <property name="label">[message]</property>
518 </object>
519 <packing>
520 <property name="expand">True</property>
521 <property name="fill">True</property>
522 <property name="position">0</property>
523 </packing>
524 </child>
525 </object>
526 <packing>
527 <property name="expand">True</property>
528 <property name="fill">True</property>
529 <property name="position">0</property>
530 </packing>
531 </child>
532 </object>
533 <packing>
534 <property name="expand">False</property>
535 <property name="fill">True</property>
536 <property name="position">5</property>
537 </packing>
538 </child>
539 <child>
540 <object class="GtkSeparator" id="separator1">
541 <property name="visible">True</property>
542 <property name="can_focus">False</property>
543 </object>
544 <packing>
545 <property name="expand">False</property>
546 <property name="fill">True</property>
547 <property name="position">6</property>
548 </packing>
549 </child>
550 </object>
551 </child>
552 <action-widgets>
553 <action-widget response="-7">cancel_button</action-widget>
554 <action-widget response="-5">ok_button</action-widget>
555 </action-widgets>
556 </object>
557 </interface>
00 <?xml version="1.0" encoding="UTF-8"?>
11 <!-- Generated with glade 3.18.3 -->
22 <interface>
3 <requires lib="gtk+" version="3.6"/>
3 <requires lib="gtk+" version="3.8"/>
44 <requires lib="gtk_greeter_settings" version="1.0"/>
55 <object class="GtkListStore" id="background_model">
66 <columns>
1616 </row>
1717 <row>
1818 <col id="0" translatable="yes" context="option|multihead">Select color</col>
19 <col id="1">icon</col>
19 <col id="1">color</col>
2020 </row>
2121 <row>
2222 <col id="0" translatable="yes" context="option|multihead">Use default value</col>
5959 <column type="GdkPixbuf"/>
6060 <!-- column-name background-is-color -->
6161 <column type="gboolean"/>
62 <!-- column-name error-visible -->
63 <column type="gboolean"/>
64 <!-- column-name error-text -->
65 <column type="gchararray"/>
6266 </columns>
6367 </object>
6468 <object class="MultiheadSetupDialog" id="multihead_setup_dialog">
6569 <property name="width_request">500</property>
6670 <property name="can_focus">False</property>
67 <property name="title" translatable="yes" context="option|monitors">Multihead setup</property>
71 <property name="title" translatable="yes" context="option|multihead">Multihead setup</property>
6872 <property name="modal">True</property>
6973 <property name="window_position">center</property>
7074 <property name="destroy_with_parent">True</property>
152156 <property name="headers_clickable">False</property>
153157 <property name="search_column">0</property>
154158 <child internal-child="selection">
155 <object class="GtkTreeSelection" id="treeview-selection">
159 <object class="GtkTreeSelection" id="monitors_selection">
156160 <signal name="changed" handler="on_selection_changed" swapped="no"/>
157161 </object>
158162 </child>
167171 </object>
168172 <attributes>
169173 <attribute name="text">0</attribute>
174 </attributes>
175 </child>
176 <child>
177 <object class="GtkCellRendererPixbuf" id="error_renderer">
178 <property name="icon_name">dialog-warning</property>
179 </object>
180 <attributes>
181 <attribute name="visible">8</attribute>
170182 </attributes>
171183 </child>
172184 </object>
205217 <child>
206218 <object class="GtkTreeViewColumn" id="background_column">
207219 <property name="resizable">True</property>
220 <property name="sizing">autosize</property>
208221 <property name="title" translatable="yes" context="option|multihead">Background</property>
222 <property name="expand">True</property>
209223 <child>
210224 <object class="GtkCellRendererPixbuf" id="color_renderer"/>
211225 <attributes>
245259 <object class="GtkToolButton" id="add_button">
246260 <property name="visible">True</property>
247261 <property name="can_focus">False</property>
248 <property name="tooltip_text" translatable="yes" context="option|monitors">Add monior to the list</property>
249 <property name="label" translatable="yes" context="option|monitors">Add</property>
262 <property name="tooltip_text" translatable="yes" context="option|multihead">Add monior to the list</property>
263 <property name="label" translatable="yes" context="option|multihead">Add</property>
250264 <property name="use_underline">True</property>
251265 <property name="icon_name">list-add-symbolic</property>
252266 <signal name="clicked" handler="on_monitors_add_clicked" swapped="no"/>
260274 <object class="GtkToolButton" id="remove_button">
261275 <property name="visible">True</property>
262276 <property name="can_focus">False</property>
263 <property name="tooltip_text" translatable="yes" context="option|monitors">Remove monitor from the list</property>
264 <property name="label" translatable="yes" context="option|monitors">Remove</property>
277 <property name="tooltip_text" translatable="yes" context="option|multihead">Remove monitor from the list</property>
278 <property name="label" translatable="yes" context="option|multihead">Remove</property>
265279 <property name="use_underline">True</property>
266280 <property name="icon_name">list-remove-symbolic</property>
267281 <signal name="clicked" handler="on_monitors_remove_clicked" swapped="no"/>
33 <glade-widget-class title="Settings Window" name="GtkGreeterSettingsWindow"
44 generic-name="GtkGreeterSettingsWindow" parent="GtkWindow"
55 icon-name="widget-gtk-window"/>
6 <glade-widget-class title="Indicator Chooser Dialog" name="IndicatorChooserDialog"
7 generic-name="IndicatorChooserDialog" parent="GtkDialog"
6 <glade-widget-class title="Indicator Properties Dialog" name="IndicatorPropertiesDialog"
7 generic-name="IndicatorPropertiesDialog" parent="GtkDialog"
88 icon-name="widget-gtk-dialog"/>
99 <glade-widget-class title="Icon Chooser Dialog" name="IconChooserDialog"
1010 generic-name="IconChooserDialog" parent="GtkDialog"
1414 # You should have received a copy of the GNU General Public License along
1515 # with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17 from collections import namedtuple
17
18 import collections
1819 import configparser
20 import os
21 import shlex
22 import sys
1923 from glob import iglob
2024 from itertools import chain
2125 from locale import gettext as _
22 import os
23 import sys
24
25 from gi.repository import Gtk
26 from lightdm_gtk_greeter_settings import OptionEntry
27 from lightdm_gtk_greeter_settings import helpers
28 from lightdm_gtk_greeter_settings.helpers import C_, WidgetsWrapper
29
30 from lightdm_gtk_greeter_settings.MultiheadSetupDialog import MonitorsGroup
26
27 from gi.repository import (
28 Gdk,
29 Gtk)
30 from gi.repository import Pango
31 from gi.repository.GObject import markup_escape_text as escape_markup
32
33 from lightdm_gtk_greeter_settings import (
34 helpers,
35 IconEntry,
36 IndicatorsEntry,
37 OptionEntry,
38 PositionEntry)
39 from lightdm_gtk_greeter_settings.helpers import (
40 C_,
41 string2bool,
42 WidgetsEnum)
43 from lightdm_gtk_greeter_settings.MonitorsGroup import MonitorsGroup
3144 from lightdm_gtk_greeter_settings.OptionGroup import SimpleGroup
3245
3346
3447 __all__ = ['GtkGreeterSettingsWindow']
3548
3649
37 InitialValue = namedtuple('InitialValue', ('value', 'enabled'))
50 InitialValue = collections.namedtuple('InitialValue', ('value', 'enabled'))
3851
3952
4053 class GtkGreeterSettingsWindow(Gtk.Window):
4154
4255 __gtype_name__ = 'GtkGreeterSettingsWindow'
4356
44 BUILDER_WIDGETS = ('apply_button', 'no_access_infobar',
45 'gtk_theme_values', 'icons_theme_values')
57 class Widgets(WidgetsEnum):
58 apply = 'apply_button'
59 infobar = 'infobar'
4660
4761 def __new__(cls):
4862 builder = Gtk.Builder()
4963 builder.add_from_file(helpers.get_data_path('%s.ui' % cls.__name__))
5064 window = builder.get_object('settings_window')
51 window._builder = builder
52 window._widgets = WidgetsWrapper(builder)
53 window.__dict__.update(('_' + w, builder.get_object(w))
54 for w in cls.BUILDER_WIDGETS)
65 window.builder = builder
5566 builder.connect_signals(window)
56 window._init_window()
67 window.init_window()
5768 return window
5869
59 def _init_window(self):
60
61 self._entries_setup = \
62 {
63 ('greeter', 'screensaver-timeout'): self.on_entry_setup_greeter_screensaver_timeout,
64 ('greeter', 'theme-name'): self.on_entry_setup_greeter_theme_name,
65 ('greeter', 'icon-theme-name'): self.on_entry_setup_greeter_icon_theme_name,
66 }
70 builder = None
71
72 entries_setup = {
73 ('greeter', 'allow-debugging'): ('changed',),
74 ('greeter', 'background'): ('changed',),
75 ('greeter', 'default-user-image'): ('changed',),
76 ('greeter', 'screensaver-timeout'): ('setup', 'get', 'set'),
77 ('greeter', 'theme-name'): ('setup', 'changed'),
78 ('greeter', 'icon-theme-name'): ('setup', 'changed'),
79 ('greeter', 'keyboard'): ('changed',),
80 ('greeter', 'reader'): ('changed',)}
81
82 def init_window(self):
83 self._widgets = self.Widgets(builder=self.builder)
6784
6885 self._multihead_dialog = None
86 self._entry_menu = None
6987 self._initial_values = {}
7088 self._changed_entries = None
7189 self._entries = None
72 self._groups = \
73 (
74 SimpleGroup('greeter', self._builder,
75 {
90 self._groups = (
91 SimpleGroup('greeter', self.builder, {
7692 # Appearance
77 'theme-name': (OptionEntry.StringEntry, None),
78 'icon-theme-name': (OptionEntry.StringEntry, None),
93 'theme-name': (OptionEntry.StringEntry, ''),
94 'icon-theme-name': (OptionEntry.StringEntry, ''),
7995 'font-name': (OptionEntry.FontEntry, 'Sans 10'),
8096 'xft-antialias': (OptionEntry.BooleanEntry, 'false'),
8197 'xft-dpi': (OptionEntry.StringEntry, None),
8399 'xft-hintstyle': (OptionEntry.ChoiceEntry, None),
84100 'background': (OptionEntry.BackgroundEntry, '#000000'),
85101 'user-background': (OptionEntry.BooleanEntry, 'true'),
86 'default-user-image': (OptionEntry.IconEntry, '#avatar-default'),
102 'hide-user-image': (OptionEntry.InvertedBooleanEntry, 'false'),
103 'default-user-image': (IconEntry.IconEntry, '#avatar-default'),
87104 # Panel
88105 'clock-format': (OptionEntry.ClockFormatEntry, '%a, %H:%M'),
89 'indicators': (OptionEntry.IndicatorsEntry,
106 'indicators': (IndicatorsEntry.IndicatorsEntry,
90107 '~host;~spacer;~clock;~spacer;~language;~session;~a11y;~power'),
91108 # Position
92 'position': (OptionEntry.PositionEntry, '50%,center'),
109 'position': (PositionEntry.PositionEntry, '50%,center'),
93110 # Misc
94 'screensaver-timeout': (OptionEntry.AdjustmentEntry, 60),
95 'keyboard': (OptionEntry.StringEntry, None)
96 }),
97 MonitorsGroup(self._widgets)
98 )
111 'screensaver-timeout': (OptionEntry.AdjustmentEntry, '60'),
112 'keyboard': (OptionEntry.StringPathEntry, ''),
113 'reader': (OptionEntry.StringPathEntry, ''),
114 'a11y-states': (OptionEntry.AccessibilityStatesEntry, ''),
115 'allow-debugging': (OptionEntry.BooleanEntry, 'false'), }),
116 MonitorsGroup(self.builder))
99117
100118 for group in self._groups:
101119 group.entry_added.connect(self.on_entry_added)
102120 group.entry_removed.connect(self.on_entry_removed)
103121
104 self._timeout_adjustment = self._widgets['greeter', 'screensaver-timeout', 'adjustment']
105
106122 self._config_path = helpers.get_config_path()
107123 self._allow_edit = self._has_access_to_write(self._config_path)
108 self._no_access_infobar.props.visible = not self._allow_edit
109 self._apply_button.props.visible = self._allow_edit
124 self._widgets.infobar.props.visible = not self._allow_edit
125 self._widgets.apply.props.visible = self._allow_edit
126
110127 if not self._allow_edit:
111128 helpers.show_message(
112129 text=_('No permissions to save configuration'),
142159 group.read(self._config)
143160
144161 self._initial_values = {entry: InitialValue(entry.value, entry.enabled)
145 for entry in self._initial_values.keys()}
162 for entry in self._initial_values.keys()}
146163 self._changed_entries = set()
147 self._apply_button.props.sensitive = False
164 self._widgets.apply.props.sensitive = False
148165
149166 def _write(self):
150167 for group in self._groups:
154171 self._initial_values[entry] = InitialValue(entry.value, entry.enabled)
155172
156173 self._changed_entries.clear()
157 self._apply_button.props.sensitive = False
174 self._widgets.apply.props.sensitive = False
158175
159176 try:
160177 with open(self._config_path, 'w') as file:
163180 helpers.show_message(e, Gtk.MessageType.ERROR)
164181
165182 def on_entry_added(self, group, entry, key):
166 if isinstance(group, SimpleGroup):
167 setup = self._entries_setup.get((group.name, key))
168 if setup:
169 setup(entry)
183 if isinstance(group, SimpleGroup) and (group.name, key) in self.entries_setup:
184 for action in self.entries_setup[(group.name, key)]:
185 fname = 'on_entry_%s_%s_%s' % (action, group.name, key)
186 f = getattr(self, fname.replace('-', '_'))
187 if action == 'setup':
188 f(entry)
189 else:
190 entry.connect(action, f)
191
192 label_holder = entry.widgets['label_holder']
193 if label_holder and isinstance(group, SimpleGroup):
194 label_holder.connect('button-press-event', self.on_entry_label_clicked,
195 entry, group, key)
196
170197 entry.changed.connect(self.on_entry_changed)
171198 self._initial_values[entry] = InitialValue(entry.value, entry.enabled)
172199 self.on_entry_changed(entry, force=True)
173200
174201 def on_entry_removed(self, group, entry, key):
175202 self._initial_values.pop(entry)
203
176204 if self._changed_entries is None:
177205 return
178206
179207 self._changed_entries.discard(entry)
180 self._apply_button.props.sensitive = self._allow_edit and self._changed_entries
208 self._widgets.apply.props.sensitive = self._allow_edit and self._changed_entries
181209
182210 def on_entry_changed(self, entry, force=False):
183211 if self._changed_entries is None:
184212 return
185213
186 if force or entry.enabled != self._initial_values[entry].enabled or \
187 (entry.enabled and entry.value != self._initial_values[entry].value):
214 initial = self._initial_values[entry]
215 if force or entry.enabled != initial.enabled or \
216 (entry.enabled and entry.value != initial.value):
188217 self._changed_entries.add(entry)
189218 else:
190219 self._changed_entries.discard(entry)
191 self._apply_button.props.sensitive = self._allow_edit and self._changed_entries
192
220
221 self._widgets.apply.props.sensitive = self._allow_edit and self._changed_entries
222
223 def on_entry_reset_clicked(self, item):
224 entry, value, enabled = item._reset_entry_data
225 if enabled is None:
226 entry.value = value
227 else:
228 entry.enabled = enabled
229
230 def on_entry_label_clicked(self, widget, event, entry, group, key):
231 if event.button != 3:
232 return
233
234 if not self._entry_menu:
235 def new_item(activate=None):
236 item = Gtk.MenuItem('')
237 item.get_child().props.use_markup = True
238 item.get_child().props.ellipsize = Pango.EllipsizeMode.END
239 item.get_child().props.max_width_chars = 90
240 if activate:
241 item.connect('activate', activate)
242 else:
243 item.props.sensitive = False
244 return item
245
246 self._entry_menu = Gtk.Menu()
247 self._entry_menu_label_item = new_item()
248 self._entry_menu_separator_item = Gtk.SeparatorMenuItem()
249 self._entry_menu_initial_item = new_item(self.on_entry_reset_clicked)
250 self._entry_menu_default_item = new_item(self.on_entry_reset_clicked)
251
252 self._entry_menu.append(self._entry_menu_label_item)
253 self._entry_menu.append(self._entry_menu_separator_item)
254 self._entry_menu.append(self._entry_menu_initial_item)
255 self._entry_menu.append(self._entry_menu_default_item)
256 self._entry_menu.show_all()
257
258 def format_value(value=None, enabled=True):
259 if not enabled:
260 return _('<i>disabled</i>')
261 if value == '':
262 return _('<i>empty string</i>')
263 elif value is None:
264 return _('<i>None</i>')
265 else:
266 return escape_markup(str(value))
267
268 self._entry_menu_label_item.props.label = '{key} = {value}'.format(
269 group=group.name,
270 key=key,
271 value=format_value(value=entry.value, enabled=entry.enabled))
272
273 if entry in self._changed_entries:
274 initial = self._initial_values[entry]
275
276 if entry.enabled != initial.enabled and not initial.enabled:
277 self._entry_menu_initial_item._reset_entry_data = entry, None, initial.enabled
278 else:
279 self._entry_menu_initial_item._reset_entry_data = entry, initial.value, None
280
281 value = format_value(value=initial.value, enabled=initial.enabled)
282 self._entry_menu_initial_item.set_tooltip_markup(value)
283 self._entry_menu_initial_item.props.visible = True
284 self._entry_menu_initial_item.props.label = \
285 _('Reset to initial value: <b>{value}</b>').format(value=value)
286 else:
287 self._entry_menu_initial_item.props.visible = False
288
289 default = group.defaults[key]
290 if default is not None and entry.value != default:
291 value = format_value(value=default)
292 self._entry_menu_default_item._reset_entry_data = entry, default, None
293 self._entry_menu_default_item.set_tooltip_markup(value)
294 self._entry_menu_default_item.props.visible = True
295 self._entry_menu_default_item.props.label = \
296 _('Reset to default value: <b>{value}</b>').format(value=value)
297 else:
298 self._entry_menu_default_item.props.visible = False
299
300 self._entry_menu_separator_item.props.visible = \
301 (self._entry_menu_initial_item.props.visible or
302 self._entry_menu_default_item.props.visible)
303 self._entry_menu.popup(None, None, None, None, 0, Gtk.get_current_event_time())
304
305 # [greeter] screensaver-timeout
193306 def on_entry_setup_greeter_screensaver_timeout(self, entry):
194 timeout_view = entry.widgets['view']
195 timeout_adjustment = entry.widgets['adjustment']
196 timeout_end_label = entry.widgets['end-label']
197 for mark in chain(list(range(10, 61, 10)),
198 list(range(69,
199 int(timeout_adjustment.props.upper),
200 10))):
201 timeout_view.add_mark(mark, Gtk.PositionType.BOTTOM, None)
202 total = int(timeout_adjustment.props.upper - 60) + 1
203 timeout_end_label.props.label = C_('option|timeout', '{count} min').format(count=total)
204
205 timeout_view.connect('format-value', self.on_entry_format_scale_greeter_screensaver_timeout, timeout_adjustment)
206 entry.get.connect(self.on_entry_get_greeter_screensaver_timeout)
207 entry.set.connect(self.on_entry_set_greeter_screensaver_timeout)
208
307 view = entry.widgets['view']
308 adjustment = entry.widgets['adjustment']
309 end_label = entry.widgets['end-label']
310 for mark in chain((range(10, 61, 10)),
311 (range(69, int(adjustment.props.upper), 10))):
312 view.add_mark(mark, Gtk.PositionType.BOTTOM, None)
313 total = int(adjustment.props.upper - 60) + 1
314 end_label.props.label = C_('option|greeter|screensaver-timeout',
315 '{count} min').format(count=total)
316
317 view.connect('format-value',
318 self.on_entry_format_scale_greeter_screensaver_timeout,
319 adjustment)
320
321 def on_entry_get_greeter_screensaver_timeout(self, entry=None, value=None):
322 try:
323 value = int(float(value))
324 except ValueError:
325 value = 60
326
327 if value > 60:
328 return (value - 59) * 60
329 return value
330
331 def on_entry_set_greeter_screensaver_timeout(self, entry=None, value=None):
332 try:
333 value = int(float(value))
334 except ValueError:
335 value = 60
336
337 if value > 60:
338 return value // 60 + 59
339 return value
340
341 def on_entry_format_scale_greeter_screensaver_timeout(self, scale, value, adjustment):
342 if value != adjustment.props.lower and value != adjustment.props.upper:
343 value = self.on_entry_get_greeter_screensaver_timeout(value=value)
344 return '%02d:%02d' % (value // 60, value % 60)
345 return ''
346
347 # [greeter] theme-name
209348 def on_entry_setup_greeter_theme_name(self, entry):
210349 values = entry.widgets['values']
211350 for theme in sorted(iglob(os.path.join(sys.prefix, 'share', 'themes', '*', 'gtk-3.0'))):
212351 values.append_text(theme.split(os.path.sep)[-2])
213352
353 def on_entry_changed_greeter_theme_name(self, entry):
354 if not entry.value or \
355 entry.value in (row[0] for row in entry.widgets['values'].props.model):
356 entry.error = None
357 else:
358 entry.error = C_('option|greeter|theme-name', 'Selected theme is not available')
359
360 # [greeter] icon-theme-name
214361 def on_entry_setup_greeter_icon_theme_name(self, entry):
215362 values = entry.widgets['values']
216363 for theme in sorted(iglob(os.path.join(sys.prefix, 'share', 'icons', '*', 'index.theme'))):
217364 values.append_text(theme.split(os.path.sep)[-2])
218365
219 def on_entry_get_greeter_screensaver_timeout(self, entry=None, value=None):
220 value = int(float(value))
221 if value > 60:
222 return (value - 59) * 60
223 return value
224
225 def on_entry_set_greeter_screensaver_timeout(self, entry=None, value=None):
226 value = int(float(value))
227 if value > 60:
228 return value // 60 + 59
229 return value
230
231 def on_entry_format_scale_greeter_screensaver_timeout(self, scale, value, adjustment):
232 if value != adjustment.props.lower and value != adjustment.props.upper:
233 value = self.on_entry_get_greeter_screensaver_timeout(value=value)
234 return '%02d:%02d' % (value // 60, value % 60)
235 else:
236 return ''
366 def on_entry_changed_greeter_icon_theme_name(self, entry):
367 if not entry.value or \
368 entry.value in (row[0] for row in entry.widgets['values'].props.model):
369 entry.error = None
370 else:
371 entry.error = C_('option|greeter|icon-theme-name', 'Selected theme is not available')
372
373 # [greeter] allow-debugging
374 def on_entry_changed_greeter_allow_debugging(self, entry):
375 if (Gtk.MAJOR_VERSION, Gtk.MINOR_VERSION, Gtk.MICRO_VERSION) < (3, 14, 0) and \
376 string2bool(entry.value):
377 entry.error = C_('option|greeter|allow-debugging',
378 'GtkInspector is not available on your system')
379 else:
380 entry.error = None
381
382 # [greeter] default-user-image
383 def on_entry_changed_greeter_default_user_image(self, entry):
384 value = entry.value
385 if value.startswith('#'):
386 entry.error = None
387 else:
388 entry.error = helpers.check_path_accessibility(value)
389
390 # [greeter] background
391 def on_entry_changed_greeter_background(self, entry):
392 value = entry.value
393 if not value or Gdk.RGBA().parse(value):
394 entry.error = None
395 else:
396 entry.error = helpers.check_path_accessibility(value)
397
398 # [greeter] keyboard
399 def on_entry_changed_greeter_keyboard(self, entry):
400 error = None
401 if entry.enabled:
402 value = entry.value
403 if os.path.isabs(value):
404 argv = shlex.split(value)
405 error = helpers.check_path_accessibility(argv[0], executable=True)
406 elif not value:
407 error = _('Do not leave this field empty')
408 entry.error = error
409
410 # [greeter] reader
411 on_entry_changed_greeter_reader = on_entry_changed_greeter_keyboard
237412
238413 def on_destroy(self, *unused):
239414 Gtk.main_quit()
1414 # You should have received a copy of the GNU General Public License along
1515 # with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17 from collections import namedtuple
18 from gi.repository import Gtk, GObject
19 from lightdm_gtk_greeter_settings.helpers import ModelRowEnum
20 from lightdm_gtk_greeter_settings.helpers import get_data_path
21 from lightdm_gtk_greeter_settings.helpers import NC_, C_
17
18 from gi.repository import (
19 GObject,
20 Gtk)
21
22 from lightdm_gtk_greeter_settings.helpers import (
23 get_data_path,
24 NC_,
25 SimpleEnum,
26 WidgetsEnum)
2227
2328
2429 __all__ = ['IconChooserDialog']
2530
26 CONTEXT_ROW = ModelRowEnum('NAME', 'STANDARD', 'TITLE')
27 ICON_ROW = ModelRowEnum('NAME', 'STANDARD', 'CONTEXT')
31
32 class ContextRow(SimpleEnum):
33 Name = ()
34 Standard = ()
35 Title = ()
36
37
38 class IconRow(SimpleEnum):
39 Name = ()
40 Standard = ()
41 Context = ()
2842
2943
3044 class IconChooserDialog(Gtk.Dialog):
3145
3246 __gtype_name__ = 'IconChooserDialog'
33
34 IconsFilterArgs = namedtuple('IconsFilterArgs', ('standard', 'context'))
35
36 BUILDER_WIDGETS = ('name', 'preview', 'standard_toggle', 'spinner',
37 'contexts_view', 'contexts_selection', 'contexts_model',
38 'contexts_filter', 'icons_view', 'icons_selection',
39 'icons_model', 'icons_sorted', 'icons_filter')
4047
4148 def __new__(cls):
4249 builder = Gtk.Builder()
4350 builder.add_from_file(get_data_path('%s.ui' % cls.__name__))
4451 window = builder.get_object('icon_chooser_dialog')
45 window._builder = builder
46 window.__dict__.update(('_' + w, builder.get_object(w))
47 for w in cls.BUILDER_WIDGETS)
48
52 window.builder = builder
4953 builder.connect_signals(window)
50 window._init_window()
54 window.init_window()
5155 return window
5256
53 def _init_window(self):
57 class Widgets(WidgetsEnum):
58 name = 'name_entry'
59 preview = 'preview_image'
60 standard = 'standard_toggle'
61 ok = 'ok_button'
62 cancel = 'cancel_button'
63 contexts_view = 'contexts_view'
64 contexts_selection = 'contexts_selection'
65 contexts_model = 'contexts_model'
66 contexts_filter = 'contexts_filter'
67 icons_view = 'icons_view'
68 icons_selection = 'icons_selection'
69 icons_model = 'icons_model'
70 icons_sorted = 'icons_sorted'
71 icons_filter = 'icons_filter'
72
73 builder = None
74
75 def init_window(self):
76 self._widgets = self.Widgets(builder=self.builder)
77 self._widgets_to_disable = (self._widgets.name, self._widgets.standard,
78 self._widgets.contexts_view, self._widgets.icons_view,
79 self._widgets.ok, self._widgets.cancel)
5480
5581 self._icons_loaded = False
5682 self._icon_to_select = None
57 self._icons_filter_args = None
58
59 self._contexts_view.set_row_separator_func(
60 self._contexts_row_separator_callback, None)
61 self._contexts_filter.set_visible_func(
62 self._contexts_filter_visible_callback)
63
64 self._icons_filter.set_visible_func(
65 self._icons_filter_visible_callback)
66 self._icons_sorted.set_sort_column_id(0, Gtk.SortType.ASCENDING)
83 self._icon_filter_standard = True
84 self._icon_filter_context = None
85
86 self._widgets.contexts_view.set_row_separator_func(self._contexts_separator_callback, None)
87 self._widgets.contexts_filter.set_visible_func(self._contexts_visible_callback)
88
89 self._widgets.icons_filter.set_visible_func(self._icons_filter_visible_callback)
90 self._widgets.icons_sorted.set_sort_column_id(0, Gtk.SortType.ASCENDING)
6791
6892 self._reload()
93
94 def _reload(self):
95 for w in self._widgets_to_disable:
96 w.props.sensitive = False
97 GObject.idle_add(self._read_icons)
6998
7099 def _read_icons(self):
71100 theme = Gtk.IconTheme.get_default()
72 standard_contexts = set(name for name, title in STANDARD_CONTEXTS)
73
74 self._contexts_model.clear()
75 for name, title in STANDARD_CONTEXTS:
76 row = CONTEXT_ROW(NAME=name, STANDARD=True,
77 TITLE=title and C_('icon-dialog', title))
78 self._contexts_model.append(row)
101 standard_contexts = set(name for name, title in StandardContexts)
102
103 self._widgets.contexts_model.clear()
104 for name, title in StandardContexts:
105 row = ContextRow._make(Name=name, Standard=True, Title=title)
106 self._widgets.contexts_model.append(row)
79107
80108 for name in theme.list_contexts():
81109 if name not in standard_contexts:
82 row = CONTEXT_ROW(NAME=name, STANDARD=False, TITLE=name)
83 self._contexts_model.append(row)
84
85 self._icons_model.clear()
110 row = ContextRow._make(Name=name, Standard=False, Title=name)
111 self._widgets.contexts_model.append(row)
112
113 self._widgets.icons_model.clear()
86114 for context in theme.list_contexts():
87115 for icon in theme.list_icons(context):
88 row = ICON_ROW(NAME=icon, CONTEXT=context,
89 STANDARD=icon in STANDARD_ICON_NAMES)
90 self._icons_model.append(row)
116 row = IconRow._make(Name=icon, Standard=icon in StandardIconNames, Context=context)
117 self._widgets.icons_model.append(row)
91118
92119 self._icons_loaded = True
93120 if self._icon_to_select:
94121 self.select_icon(self._icon_to_select)
95122 self._icon_to_select = None
123
124 for w in self._widgets_to_disable:
125 w.props.sensitive = True
126
96127 return False
97128
98 def _reload(self):
99 GObject.idle_add(self._read_icons)
100
101129 def _update_contexts_filter(self):
102 selected_iter = self._contexts_selection.get_selected()[1]
103 selected_path = self._contexts_filter.get_path(
104 selected_iter) if selected_iter else None
105 self._contexts_filter.refilter()
106 if selected_path and \
107 self._contexts_selection.path_is_selected(selected_path):
108 self._update_icons_filter()
130 self._widgets.contexts_filter.refilter()
131 self._update_icons_filter()
109132
110133 def _update_icons_filter(self):
111 model, rowiter = self._contexts_selection.get_selected()
134 self._widgets.icons_view.props.model = None
135 model, rowiter = self._widgets.contexts_selection.get_selected()
112136 if rowiter:
113 self._icons_filter_args = self.IconsFilterArgs(
114 self._standard_toggle.props.active,
115 model[rowiter][CONTEXT_ROW.NAME])
116 else:
117 self._icons_filter_args = None
118 self._icons_view.props.model = None
119 self._icons_filter.refilter()
120 self._icons_view.props.model = self._icons_sorted
121
122 def _contexts_filter_visible_callback(self, model, rowiter, data):
123 if not self._standard_toggle.props.active:
137 self._icon_filter_standard = self._widgets.standard.props.active
138 self._icon_filter_context = model[rowiter][ContextRow.Name]
139 self._widgets.icons_filter.refilter()
140 self._widgets.icons_view.props.model = self._widgets.icons_sorted
141
142 def _contexts_visible_callback(self, model, rowiter, data):
143 if not self._widgets.standard.props.active:
124144 return True
125 return model[rowiter][CONTEXT_ROW.STANDARD]
126
127 def _contexts_row_separator_callback(self, model, rowiter, data):
128 return not model[rowiter][CONTEXT_ROW.NAME] and \
129 not model[rowiter][CONTEXT_ROW.TITLE]
145 return model[rowiter][ContextRow.Standard]
146
147 def _contexts_separator_callback(self, model, rowiter, data):
148 return not model[rowiter][ContextRow.Name] and not model[rowiter][ContextRow.Title]
130149
131150 def _icons_filter_visible_callback(self, model, rowiter, data):
132 if not self._icons_filter_args:
151 if self._icon_filter_standard and not model[rowiter][IconRow.Standard]:
133152 return False
134 if self._icons_filter_args.standard and \
135 not model[rowiter][ICON_ROW.STANDARD]:
136 return False
137 if not self._icons_filter_args.context:
153 if not self._icon_filter_context:
138154 return True
139 return model[rowiter][ICON_ROW.CONTEXT] == \
140 self._icons_filter_args.context
141
142 def run(self):
143 return super().run()
144
145 def get_iconname(self):
146 return self._name.props.text
155 return model[rowiter][IconRow.Context] == self._icon_filter_context
156
157 def get_selected_icon(self):
158 return self._widgets.name.props.text
147159
148160 def select_icon(self, name):
149161 if not self._icons_loaded:
150162 self._icon_to_select = name
151163 return
152164
153 if not self._icons_filter_args or \
154 self._icons_filter_args.context is not None:
155 if name not in STANDARD_ICON_NAMES:
156 self._standard_toggle.props.active = False
157 self._contexts_selection.select_path(0)
158 for row in self._icons_sorted:
159 if row[ICON_ROW.NAME] == name:
160 self._icons_view.set_cursor(row.path)
161 self._icons_selection.select_path(row.path)
165 if name not in StandardIconNames:
166 self._widgets.standard.props.active = False
167 self._widgets.contexts_selection.select_path(0)
168
169 for row in self._widgets.icons_sorted:
170 if row[IconRow.Name] == name:
171 self._widgets.icons_view.set_cursor(row.path)
172 self._widgets.icons_selection.select_path(row.path)
162173 break
163174 else:
164 self._name.props.text = name
175 self._widgets.name.props.text = name
165176
166177 def on_icons_selection_changed(self, selection):
167 model, rowiter = self._icons_selection.get_selected()
178 model, rowiter = selection.get_selected()
168179 if rowiter:
169 name = model[rowiter][ICON_ROW.NAME]
170 self._name.props.text = name
180 self._widgets.name.props.text = model[rowiter][IconRow.Name]
171181
172182 def on_contexts_selection_changed(self, selection):
173 self._icons_selection.unselect_all()
183 self._widgets.icons_selection.unselect_all()
174184 self._update_icons_filter()
175185
176186 def on_standard_toggled(self, toggle):
180190 name = entry.props.text
181191 if not Gtk.IconTheme.get_default().has_icon(name):
182192 name = ''
183 self._preview.props.icon_name = name
184
185
186 #http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
187
188 STANDARD_CONTEXTS =\
189 (
190 (None, NC_('icon-dialog', 'All contexts')),
191 (None, ''), # separator
192 ('Actions', NC_('icon-dialog', 'Actions')),
193 ('Applications', NC_('icon-dialog', 'Applications')),
194 ('Categories', NC_('icon-dialog', 'Categories')),
195 ('Devices', NC_('icon-dialog', 'Devices')),
196 ('Emblems', NC_('icon-dialog', 'Emblems')),
197 ('Emotes', NC_('icon-dialog', 'Emoticons')),
198 ('International', NC_('icon-dialog', 'International')),
199 ('MimeTypes', NC_('icon-dialog', 'MIME Types')),
200 ('Places', NC_('icon-dialog', 'Places')),
201 ('Status', NC_('icon-dialog', 'Status'))
202 )
203
204 STANDARD_ICON_NAMES = \
205 {
206 # Actions
207 'address-book-new', 'application-exit', 'appointment-new',
208 'call-start', 'call-stop', 'contact-new', 'document-new',
209 'document-open', 'document-open-recent', 'document-page-setup',
210 'document-print', 'document-print-preview', 'document-properties',
211 'document-revert', 'document-save', 'document-save-as',
212 'document-send', 'edit-clear', 'edit-copy', 'edit-cut', 'edit-delete',
213 'edit-find', 'edit-find-replace', 'edit-paste', 'edit-redo',
214 'edit-select-all', 'edit-undo', 'folder-new', 'format-indent-less',
215 'format-indent-more', 'format-justify-center', 'format-justify-fill',
216 'format-justify-left', 'format-justify-right',
217 'format-text-direction-ltr', 'format-text-direction-rtl',
218 'format-text-bold', 'format-text-italic', 'format-text-underline',
219 'format-text-strikethrough', 'go-bottom', 'go-down', 'go-first',
220 'go-home', 'go-jump', 'go-last', 'go-next', 'go-previous', 'go-top',
221 'go-up', 'help-about', 'help-contents', 'help-faq', 'insert-image',
222 'insert-link', 'insert-object', 'insert-text', 'list-add',
223 'list-remove', 'mail-forward', 'mail-mark-important', 'mail-mark-junk',
224 'mail-mark-notjunk', 'mail-mark-read', 'mail-mark-unread',
225 'mail-message-new', 'mail-reply-all', 'mail-reply-sender', 'mail-send',
226 'mail-send-receive', 'media-eject', 'media-playback-pause',
227 'media-playback-start', 'media-playback-stop', 'media-record',
228 'media-seek-backward', 'media-seek-forward', 'media-skip-backward',
229 'media-skip-forward', 'object-flip-horizontal', 'object-flip-vertical',
230 'object-rotate-left', 'object-rotate-right', 'process-stop',
231 'system-lock-screen', 'system-log-out', 'system-run', 'system-search',
232 'system-reboot', 'system-shutdown', 'tools-check-spelling',
233 'view-fullscreen', 'view-refresh', 'view-restore',
234 'view-sort-ascending', 'view-sort-descending', 'window-close',
235 'window-new', 'zoom-fit-best', 'zoom-in', 'zoom-original', 'zoom-out',
236 # StandardApplicationIcons
237 'accessories-calculator', 'accessories-character-map',
238 'accessories-dictionary', 'accessories-text-editor', 'help-browser',
239 'multimedia-volume-control', 'preferences-desktop-accessibility',
240 'preferences-desktop-font', 'preferences-desktop-keyboard',
241 'preferences-desktop-locale', 'preferences-desktop-multimedia',
242 'preferences-desktop-screensaver', 'preferences-desktop-theme',
243 'preferences-desktop-wallpaper', 'system-file-manager',
244 'system-software-install', 'system-software-update',
245 'utilities-system-monitor', 'utilities-terminal',
246 # StandardCategoryIcons
247 'applications-accessories', 'applications-development',
248 'applications-engineering', 'applications-games',
249 'applications-graphics', 'applications-internet',
250 'applications-multimedia', 'applications-office', 'applications-other',
251 'applications-science', 'applications-system',
252 'applications-utilities', 'preferences-desktop',
253 'preferences-desktop-peripherals', 'preferences-desktop-personal',
254 'preferences-other', 'preferences-system',
255 'preferences-system-network', 'system-help',
256 # StandardDeviceIcons
257 'audio-card', 'audio-input-microphone', 'battery', 'camera-photo',
258 'camera-video', 'camera-web', 'computer', 'drive-harddisk',
259 'drive-optical', 'drive-removable-media', 'input-gaming',
260 'input-keyboard', 'input-mouse', 'input-tablet', 'media-flash',
261 'media-floppy', 'media-optical', 'media-tape', 'modem',
262 'multimedia-player', 'network-wired', 'network-wireless', 'pda',
263 'phone', 'printer', 'scanner', 'video-display',
264 # StandardEmblemIcons
265 'emblem-default', 'emblem-documents', 'emblem-downloads',
266 'emblem-favorite', 'emblem-important', 'emblem-mail', 'emblem-photos',
267 'emblem-readonly', 'emblem-shared', 'emblem-symbolic-link',
268 'emblem-synchronized', 'emblem-system', 'emblem-unreadable',
269 # StandardEmotionIcons
270 'face-angel', 'face-angry', 'face-cool', 'face-crying',
271 'face-devilish', 'face-embarrassed', 'face-kiss', 'face-laugh',
272 'face-monkey', 'face-plain', 'face-raspberry', 'face-sad', 'face-sick',
273 'face-smile', 'face-smile-big', 'face-smirk', 'face-surprise',
274 'face-tired', 'face-uncertain', 'face-wink', 'face-worried',
275 # StandardInternationalIcons
276 'flag-aa',
277 # StandardMIMETypeIcons
278 'application-x-executable', 'audio-x-generic', 'font-x-generic',
279 'image-x-generic', 'package-x-generic', 'text-html', 'text-x-generic',
280 'text-x-generic-template', 'text-x-script', 'video-x-generic',
281 'x-office-address-book', 'x-office-calendar', 'x-office-document',
282 'x-office-presentation', 'x-office-spreadsheet',
283 # StandardPlaceIcons
284 'folder', 'folder-remote', 'network-server', 'network-workgroup',
285 'start-here', 'user-bookmarks', 'user-desktop', 'user-home',
286 'user-trash',
287 # StandardStatusIcons
288 'appointment-missed', 'appointment-soon', 'audio-volume-high',
289 'audio-volume-low', 'audio-volume-medium', 'audio-volume-muted',
290 'battery-caution', 'battery-low', 'dialog-error', 'dialog-information',
291 'dialog-password', 'dialog-question', 'dialog-warning',
292 'folder-drag-accept', 'folder-open', 'folder-visiting',
293 'image-loading', 'image-missing', 'mail-attachment', 'mail-unread',
294 'mail-read', 'mail-replied', 'mail-signed', 'mail-signed-verified',
295 'media-playlist-repeat', 'media-playlist-shuffle', 'network-error',
296 'network-idle', 'network-offline', 'network-receive',
297 'network-transmit', 'network-transmit-receive', 'printer-error',
298 'printer-printing', 'security-high', 'security-medium', 'security-low',
299 'software-update-available', 'software-update-urgent', 'sync-error',
300 'sync-synchronizing', 'task-due', 'task-past-due', 'user-available',
301 'user-away', 'user-idle', 'user-offline', 'user-trash-full',
302 'weather-clear', 'weather-clear-night', 'weather-few-clouds',
303 'weather-few-clouds-night', 'weather-fog', 'weather-overcast',
304 'weather-severe-alert', 'weather-showers', 'weather-showers-scattered',
305 'weather-snow', 'weather-storm'
306 }
193 self._widgets.preview.props.icon_name = name
194
195
196 # http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
197
198 StandardContexts = (
199 (None, NC_('icon-dialog', 'All contexts')),
200 (None, ''), # separator
201 ('Actions', NC_('icon-dialog', 'Actions')),
202 ('Applications', NC_('icon-dialog', 'Applications')),
203 ('Categories', NC_('icon-dialog', 'Categories')),
204 ('Devices', NC_('icon-dialog', 'Devices')),
205 ('Emblems', NC_('icon-dialog', 'Emblems')),
206 ('Emotes', NC_('icon-dialog', 'Emoticons')),
207 ('International', NC_('icon-dialog', 'International')),
208 ('MimeTypes', NC_('icon-dialog', 'MIME Types')),
209 ('Places', NC_('icon-dialog', 'Places')),
210 ('Status', NC_('icon-dialog', 'Status')))
211
212 StandardIconNames = {
213 # Actions
214 'address-book-new', 'application-exit', 'appointment-new',
215 'call-start', 'call-stop', 'contact-new', 'document-new',
216 'document-open', 'document-open-recent', 'document-page-setup',
217 'document-print', 'document-print-preview', 'document-properties',
218 'document-revert', 'document-save', 'document-save-as',
219 'document-send', 'edit-clear', 'edit-copy', 'edit-cut', 'edit-delete',
220 'edit-find', 'edit-find-replace', 'edit-paste', 'edit-redo',
221 'edit-select-all', 'edit-undo', 'folder-new', 'format-indent-less',
222 'format-indent-more', 'format-justify-center', 'format-justify-fill',
223 'format-justify-left', 'format-justify-right',
224 'format-text-direction-ltr', 'format-text-direction-rtl',
225 'format-text-bold', 'format-text-italic', 'format-text-underline',
226 'format-text-strikethrough', 'go-bottom', 'go-down', 'go-first',
227 'go-home', 'go-jump', 'go-last', 'go-next', 'go-previous', 'go-top',
228 'go-up', 'help-about', 'help-contents', 'help-faq', 'insert-image',
229 'insert-link', 'insert-object', 'insert-text', 'list-add',
230 'list-remove', 'mail-forward', 'mail-mark-important', 'mail-mark-junk',
231 'mail-mark-notjunk', 'mail-mark-read', 'mail-mark-unread',
232 'mail-message-new', 'mail-reply-all', 'mail-reply-sender', 'mail-send',
233 'mail-send-receive', 'media-eject', 'media-playback-pause',
234 'media-playback-start', 'media-playback-stop', 'media-record',
235 'media-seek-backward', 'media-seek-forward', 'media-skip-backward',
236 'media-skip-forward', 'object-flip-horizontal', 'object-flip-vertical',
237 'object-rotate-left', 'object-rotate-right', 'process-stop',
238 'system-lock-screen', 'system-log-out', 'system-run', 'system-search',
239 'system-reboot', 'system-shutdown', 'tools-check-spelling',
240 'view-fullscreen', 'view-refresh', 'view-restore',
241 'view-sort-ascending', 'view-sort-descending', 'window-close',
242 'window-new', 'zoom-fit-best', 'zoom-in', 'zoom-original', 'zoom-out',
243 # StandardApplicationIcons
244 'accessories-calculator', 'accessories-character-map',
245 'accessories-dictionary', 'accessories-text-editor', 'help-browser',
246 'multimedia-volume-control', 'preferences-desktop-accessibility',
247 'preferences-desktop-font', 'preferences-desktop-keyboard',
248 'preferences-desktop-locale', 'preferences-desktop-multimedia',
249 'preferences-desktop-screensaver', 'preferences-desktop-theme',
250 'preferences-desktop-wallpaper', 'system-file-manager',
251 'system-software-install', 'system-software-update',
252 'utilities-system-monitor', 'utilities-terminal',
253 # StandardCategoryIcons
254 'applications-accessories', 'applications-development',
255 'applications-engineering', 'applications-games',
256 'applications-graphics', 'applications-internet',
257 'applications-multimedia', 'applications-office', 'applications-other',
258 'applications-science', 'applications-system',
259 'applications-utilities', 'preferences-desktop',
260 'preferences-desktop-peripherals', 'preferences-desktop-personal',
261 'preferences-other', 'preferences-system',
262 'preferences-system-network', 'system-help',
263 # StandardDeviceIcons
264 'audio-card', 'audio-input-microphone', 'battery', 'camera-photo',
265 'camera-video', 'camera-web', 'computer', 'drive-harddisk',
266 'drive-optical', 'drive-removable-media', 'input-gaming',
267 'input-keyboard', 'input-mouse', 'input-tablet', 'media-flash',
268 'media-floppy', 'media-optical', 'media-tape', 'modem',
269 'multimedia-player', 'network-wired', 'network-wireless', 'pda',
270 'phone', 'printer', 'scanner', 'video-display',
271 # StandardEmblemIcons
272 'emblem-default', 'emblem-documents', 'emblem-downloads',
273 'emblem-favorite', 'emblem-important', 'emblem-mail', 'emblem-photos',
274 'emblem-readonly', 'emblem-shared', 'emblem-symbolic-link',
275 'emblem-synchronized', 'emblem-system', 'emblem-unreadable',
276 # StandardEmotionIcons
277 'face-angel', 'face-angry', 'face-cool', 'face-crying',
278 'face-devilish', 'face-embarrassed', 'face-kiss', 'face-laugh',
279 'face-monkey', 'face-plain', 'face-raspberry', 'face-sad', 'face-sick',
280 'face-smile', 'face-smile-big', 'face-smirk', 'face-surprise',
281 'face-tired', 'face-uncertain', 'face-wink', 'face-worried',
282 # StandardInternationalIcons
283 'flag-aa',
284 # StandardMIMETypeIcons
285 'application-x-executable', 'audio-x-generic', 'font-x-generic',
286 'image-x-generic', 'package-x-generic', 'text-html', 'text-x-generic',
287 'text-x-generic-template', 'text-x-script', 'video-x-generic',
288 'x-office-address-book', 'x-office-calendar', 'x-office-document',
289 'x-office-presentation', 'x-office-spreadsheet',
290 # StandardPlaceIcons
291 'folder', 'folder-remote', 'network-server', 'network-workgroup',
292 'start-here', 'user-bookmarks', 'user-desktop', 'user-home',
293 'user-trash',
294 # StandardStatusIcons
295 'appointment-missed', 'appointment-soon', 'audio-volume-high',
296 'audio-volume-low', 'audio-volume-medium', 'audio-volume-muted',
297 'battery-caution', 'battery-low', 'dialog-error', 'dialog-information',
298 'dialog-password', 'dialog-question', 'dialog-warning',
299 'folder-drag-accept', 'folder-open', 'folder-visiting',
300 'image-loading', 'image-missing', 'mail-attachment', 'mail-unread',
301 'mail-read', 'mail-replied', 'mail-signed', 'mail-signed-verified',
302 'media-playlist-repeat', 'media-playlist-shuffle', 'network-error',
303 'network-idle', 'network-offline', 'network-receive',
304 'network-transmit', 'network-transmit-receive', 'printer-error',
305 'printer-printing', 'security-high', 'security-medium', 'security-low',
306 'software-update-available', 'software-update-urgent', 'sync-error',
307 'sync-synchronizing', 'task-due', 'task-past-due', 'user-available',
308 'user-away', 'user-idle', 'user-offline', 'user-trash-full',
309 'weather-clear', 'weather-clear-night', 'weather-few-clouds',
310 'weather-few-clouds-night', 'weather-fog', 'weather-overcast',
311 'weather-severe-alert', 'weather-showers', 'weather-showers-scattered',
312 'weather-snow', 'weather-storm'}
0 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1 # LightDM GTK Greeter Settings
2 # Copyright (C) 2015 Andrew P. <pan.pav.7c5@gmail.com>
3 #
4 # This program is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU General Public License version 3, as published
6 # by the Free Software Foundation.
7 #
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranties of
10 # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 # PURPOSE. See the GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License along
14 # with this program. If not, see <http://www.gnu.org/licenses/>.
15
16
17 import os
18
19 from gi.repository import Gtk
20
21 from lightdm_gtk_greeter_settings.IconChooserDialog import IconChooserDialog
22 from lightdm_gtk_greeter_settings.OptionEntry import BaseEntry
23 from lightdm_gtk_greeter_settings.helpers import (
24 C_,
25 get_data_path,
26 set_image_from_path,
27 SimpleEnum)
28
29
30 __all__ = ['IconEntry']
31
32
33 class IconEntry(BaseEntry):
34
35 class Item(SimpleEnum):
36 priority = 0
37 # (value, just_label) => (label, tooltip)
38 update = None
39 # (old_value) => str or None
40 ask = None
41 # Associated menu item
42 menuitem = None
43
44 def __init__(self, widgets):
45 super().__init__(widgets)
46 self._value = None
47 self._image = widgets['image']
48 self._button = widgets['button']
49 self._button.props.popup = Gtk.Menu()
50 self._widgets_to_disable.append(self._button)
51 self._icon_dialog = None
52 self._path_dialog = None
53 self._current_item = None
54
55 self._items = []
56 for priority, (update, ask) in self._get_items():
57 item = self.Item(priority=priority, update=update, ask=ask)
58 item.menuitem = Gtk.MenuItem()
59 item.menuitem.props.visible = True
60 item.menuitem.props.label = item.update(None, True)[0]
61 item.menuitem.connect('activate', self._on_item_clicked, item)
62 self._button.props.popup.append(item.menuitem)
63 self._items.append(item)
64
65 self._items.sort(key=lambda i: i.priority)
66
67 def _get_value(self):
68 return self._value
69
70 def _set_value(self, value):
71 applied_item = None
72 tooltip = None
73 for item in self._items:
74 if applied_item:
75 label, __ = item.update(None, True)
76 else:
77 label, tooltip = item.update(value, False)
78 if tooltip:
79 applied_item = item
80 item.menuitem.get_child().set_markup(label)
81
82 if not applied_item:
83 tooltip = C_('option-entry|icon', 'Unrecognized value: {value}').format(value=value)
84 self._button.set_tooltip_markup(tooltip)
85
86 self._value = value
87 self._current_item = applied_item
88
89 self._emit_changed()
90
91 def _get_items(self):
92 return ((0, (self._update_icon, self._ask_icon)),
93 (100, (self._update_image, self._ask_image)))
94
95 def _on_item_clicked(self, menuitem, item):
96 value = item.ask(self._value if item == self._current_item else None)
97 if value is not None:
98 self._set_value(value)
99
100 def _update_icon(self, value, just_label=False):
101 if just_label or value is None or not value.startswith('#'):
102 return C_('option-entry|icon', 'Select icon name...'), None
103 name = value[1:]
104 label = C_('option-entry|icon', '<b>Icon: {icon}</b>').format(icon=name)
105 tooltip = label
106 self._image.set_from_icon_name(name, Gtk.IconSize.DIALOG)
107 return label, tooltip
108
109 def _ask_icon(self, oldvalue):
110 if not self._icon_dialog:
111 self._icon_dialog = IconChooserDialog()
112 self._icon_dialog.props.transient_for = self._image.get_toplevel()
113 if oldvalue:
114 self._icon_dialog.select_icon(oldvalue[1:])
115
116 value = None
117 if self._icon_dialog.run() == Gtk.ResponseType.OK:
118 value = '#' + self._icon_dialog.get_selected_icon()
119 self._icon_dialog.hide()
120 return value
121
122 def _update_image(self, value, just_label=False):
123 if just_label or value is None:
124 return C_('option-entry|icon', 'Select file...'), None
125
126 if set_image_from_path(self._image, value):
127 label = C_('option-entry|icon', '<b>File: {path}</b>')
128 else:
129 label = C_('option-entry|icon', '<b>File: {path}</b> (failed to load)')
130
131 return (label.format(path=os.path.basename(value)),
132 label.format(path=value))
133
134 def _ask_image(self, oldvalue):
135 if not self._path_dialog:
136 builder = Gtk.Builder()
137 builder.add_from_file(get_data_path('ImageChooserDialog.ui'))
138
139 self._path_dialog = builder.get_object('dialog')
140 self._path_dialog.props.transient_for = self._image.get_toplevel()
141 self._path_dialog.connect('update-preview', self._on_update_path_preview)
142
143 preview_size = self._image.props.pixel_size
144 preview = self._path_dialog.props.preview_widget
145 preview.props.pixel_size = preview_size
146 preview.set_size_request(preview_size, preview_size)
147
148 if oldvalue is not None:
149 self._path_dialog.select_filename(self._value)
150
151 value = None
152 if self._path_dialog.run() == Gtk.ResponseType.OK:
153 value = self._path_dialog.get_filename()
154 self._path_dialog.hide()
155 return value
156
157 def _on_update_path_preview(self, chooser):
158 set_image_from_path(chooser.props.preview_widget, chooser.get_filename())
+0
-130
lightdm_gtk_greeter_settings/IndicatorChooserDialog.py less more
0 #!/usr/bin/env python3
1 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2 # LightDM GTK Greeter Settings
3 # Copyright (C) 2014 Andrew P. <pan.pav.7c5@gmail.com>
4 #
5 # This program is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License version 3, as published
7 # by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranties of
11 # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12 # PURPOSE. See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with this program. If not, see <http://www.gnu.org/licenses/>.
16
17 from glob import iglob
18 import os
19 import sys
20
21 from gi.repository import Gtk
22 from lightdm_gtk_greeter_settings import helpers
23
24
25 __all__ = ['IndicatorChooserDialog']
26
27
28 class IndicatorChooserDialog(Gtk.Dialog):
29
30 __gtype_name__ = 'IndicatorChooserDialog'
31
32 BUILDER_WIDGETS = ('short_choice', 'short_value', 'short_model',
33 'path_choice', 'path_value',
34 'spacer_choice', 'separator_choice',
35 'add_button', 'ok_button', 'infobar', 'message')
36
37 def __new__(cls, check_callback=None, add_callback=None):
38 builder = Gtk.Builder()
39 builder.add_from_file(helpers.get_data_path('%s.ui' % cls.__name__))
40 window = builder.get_object('indicator_chooser_dialog')
41 window._builder = builder
42 window.__dict__.update(('_' + w, builder.get_object(w))
43 for w in cls.BUILDER_WIDGETS)
44
45 builder.connect_signals(window)
46 window._init_window(check_callback, add_callback)
47 return window
48
49 def _init_window(self, check_callback, add_callback):
50 self._check_callback = check_callback
51 self._add_callback = add_callback
52 self._add_button.props.visible = add_callback is not None
53
54 for path in sorted(iglob(os.path.join(sys.prefix, 'share', 'unity',
55 'indicators', '*'))):
56 name = os.path.basename(path)
57 parts = name.rsplit('.', maxsplit=1)
58 if len(parts) == 2 and parts[0] == 'com.canonical.indicator':
59 name = parts[1]
60 self._short_model.append((name,))
61
62 for path in sorted(iglob(os.path.join(sys.prefix, 'lib', 'indicators3',
63 '7', '*.so'))):
64 self._short_model.append((os.path.basename(path),))
65
66 def _get_current_value(self):
67 if self._short_choice.props.active:
68 return self._short_value.props.text
69 elif self._path_choice.props.active:
70 return self._path_value.get_filename()
71 elif self._spacer_choice.props.active:
72 return '~spacer';
73 else:
74 return '~separator';
75
76 def _update_state(self, force_state=None):
77 message = None
78 if force_state is None:
79 valid = False
80 if self._check_callback is not None:
81 check = self._check_callback(self._get_current_value())
82 if isinstance(check, str):
83 message = check
84 else:
85 valid = bool(check)
86 else:
87 valid = True
88 else:
89 valid = force_state
90
91 self._infobar.props.visible = message is not None
92 if message is not None:
93 self._message.props.label = message
94
95 self._ok_button.props.sensitive = valid
96 self._add_button.props.sensitive = valid
97
98 def on_short_value_changed(self, widget):
99 if not self._short_choice.props.active:
100 self._short_choice.props.active = True
101 else:
102 self._update_state()
103
104 def on_path_value_changed(self, widget):
105 self._path_choice.props.active = True
106 self._update_state()
107
108 def on_short_choice_toggled(self, widget):
109 self._update_state()
110
111 def on_add_clicked(self, widget):
112 value = self._get_current_value()
113 if value:
114 self._add_callback(value)
115 self._update_state(False)
116
117 def on_short_value_activate(self, entry):
118 if self._short_choice.props.active and self._ok_button.props.sensitive:
119 self._ok_button.clicked()
120
121 def get_indicator(self):
122 self._short_choice.props.active = True
123 self._update_state()
124 self._short_value.grab_focus()
125 response = self.run()
126 self.hide()
127 if response == Gtk.ResponseType.OK:
128 return self._get_current_value()
129 return None
0 #!/usr/bin/env python3
1 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2 # LightDM GTK Greeter Settings
3 # Copyright (C) 2014 Andrew P. <pan.pav.7c5@gmail.com>
4 #
5 # This program is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License version 3, as published
7 # by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranties of
11 # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12 # PURPOSE. See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18 import os
19 import sys
20 from copy import deepcopy
21 from glob import iglob
22
23 from gi.repository import Gtk
24
25 from lightdm_gtk_greeter_settings import (
26 IconEntry,
27 OptionEntry)
28 from lightdm_gtk_greeter_settings.helpers import (
29 C_,
30 bool2string,
31 string2bool,
32 get_data_path,
33 get_greeter_version,
34 SimpleEnum,
35 WidgetsEnum,
36 WidgetsWrapper)
37 from lightdm_gtk_greeter_settings.IndicatorsEntry import (
38 EmptyIndicators,
39 Indicators,
40 LayoutSet,
41 Option)
42
43
44 __all__ = ['IndicatorPropertiesDialog']
45
46
47 class IndicatorPath(OptionEntry.StringPathEntry):
48
49 class Row(SimpleEnum):
50 Title = ()
51 Type = ()
52 Icon = ()
53
54
55 class IndicatorIconEntry(IconEntry.IconEntry):
56
57 DefaultValue = ()
58
59 def __init__(self, widgets):
60 self._label = widgets['label']
61 super().__init__(widgets)
62
63 def _set_value(self, value):
64 super()._set_value(self.DefaultValue if value is None else value)
65 self._label.set_markup(self._current_item.menuitem.get_label())
66 self._image.props.visible = value not in (None, self.DefaultValue)
67
68 def _get_value(self):
69 return super()._get_value() or None
70
71 def _get_items(self):
72 for item in super()._get_items():
73 yield item
74 yield -1, (self._update_default, self._ask_default)
75
76 def _update_default(self, value, just_label):
77 if just_label or value is not self.DefaultValue:
78 return C_('option-entry|indicators', 'Use default value...'), None
79 self._image.props.icon_name = ''
80 label = C_('option-entry|indicators', '<b>Using default value</b>')
81 return label, label
82
83 def _ask_default(self, oldvalue):
84 return self.DefaultValue
85
86
87 class IndicatorTypeEntry(OptionEntry.BaseEntry):
88
89 def __init__(self, widgets):
90 super().__init__(widgets)
91
92 self._types = widgets['types']
93 self._indicator_choice = widgets['indicator_choice']
94 self._spacer_choice = widgets['spacer_choice']
95 self._separator_choice = widgets['separator_choice']
96
97 self._types.connect('changed', self._emit_changed)
98 self._indicator_choice.connect('toggled', self._on_choice_changed, None,
99 (self._types, widgets['indicator_box']))
100 self._spacer_choice.connect('toggled', self._on_choice_changed, Indicators.Spacer)
101 self._separator_choice.connect('toggled', self._on_choice_changed, Indicators.Separator)
102
103 self._value = None
104
105 def add_type(self, name, title):
106 if name not in EmptyIndicators:
107 self._types.append(name, title or name)
108
109 def _get_value(self):
110 if self._indicator_choice.props.active:
111 return self._types.props.active_id
112 else:
113 return self._value
114
115 def _set_value(self, value):
116 if value == Indicators.Spacer:
117 button = self._spacer_choice
118 elif value == Indicators.Separator:
119 button = self._separator_choice
120 else:
121 button = self._indicator_choice
122
123 self._value = value
124 self._types.set_active_id(value)
125
126 if button.props.active:
127 button.toggled()
128 else:
129 button.props.active = True
130
131 def _on_choice_changed(self, button, value, widgets=[]):
132 for w in widgets:
133 w.props.sensitive = button.props.active
134
135 if button.props.active:
136 self._value = value if value else self._types.props.active_id
137 self._emit_changed()
138
139
140 class IndicatorPropertiesDialog(Gtk.Dialog):
141 __gtype_name__ = 'IndicatorPropertiesDialog'
142
143 class Widgets(WidgetsEnum):
144 add = 'add_button'
145 ok = 'ok_button'
146 infobar = 'infobar'
147 message = 'message'
148 common_options = 'common_options_box'
149 custom_options = 'custom_options_box'
150 path = 'option_path_combo'
151 path_model = 'option_path_model'
152 hide_disabled = 'option_power_hide_disabled'
153
154 def __new__(cls, *args, **kwargs):
155 builder = Gtk.Builder()
156 builder.add_from_file(get_data_path('%s.ui' % cls.__name__))
157 window = builder.get_object('indicator_properties_dialog')
158 window.builder = builder
159 builder.connect_signals(window)
160 window.init_window(*args, **kwargs)
161 return window
162
163 def init_window(self, is_duplicate=None, get_defaults=None, get_name=str):
164 self._widgets = self.Widgets(builder=self.builder)
165 self._get_defaults = get_defaults
166 self._add_indicator = None
167 self._is_duplicate = is_duplicate
168 self._get_name = get_name
169 self._indicator_loaded = False
170 self._name = None
171 self._reversed = False
172
173 self._name2page = {}
174 for i in range(0, self._widgets.custom_options.get_n_pages()):
175 page = self._widgets.custom_options.get_nth_page(i)
176 name = Gtk.Buildable.get_name(page)
177 self._name2page['~' + name.rsplit('_')[-1]] = i
178
179 if get_greeter_version() < 0x020100:
180 self._widgets.common_options.props.visible = False
181
182 self._name2page = {
183 Indicators.External: self._name2page[Indicators.External],
184 Indicators.Text: self._name2page[Indicators.Text]}
185 text_prefix = 'option_text_fallback'
186 else:
187 self._name2page[Indicators.Text] = -1
188 text_prefix = 'option_text'
189
190 self._option_type = IndicatorTypeEntry(WidgetsWrapper(self.builder, 'option_type'))
191 self._option_text = OptionEntry.StringEntry(WidgetsWrapper(self.builder, text_prefix))
192 self._option_image = IndicatorIconEntry(WidgetsWrapper(self.builder, 'option_image'))
193 self._option_path = IndicatorPath(WidgetsWrapper(self.builder, 'option_path'))
194 self._option_hide_disabled = \
195 OptionEntry.BooleanEntry(WidgetsWrapper(self.builder, 'option_hide_disabled'))
196
197 for entry in (self._option_type, self._option_path):
198 entry.changed.connect(self._on_option_changed)
199
200 for name in Indicators:
201 self._option_type.add_type(name, self._get_name(name))
202
203 # Hiding first column created by Gtk.ComboBoxText
204 self._widgets.path.get_cells()[0].props.visible = False
205
206 for path in sorted(iglob(os.path.join(sys.prefix, 'share', 'unity', 'indicators', '*'))):
207 name = os.path.basename(path)
208 parts = name.rsplit('.', maxsplit=1)
209 if len(parts) == 2 and parts[0] == 'com.canonical.indicator':
210 name = parts[1]
211 row = IndicatorPath.Row._make(Type=IndicatorPath.ItemType.Value,
212 Title=name,
213 Icon='application-x-executable')
214 self._widgets.path_model.append(row)
215
216 for path in sorted(iglob(os.path.join(sys.prefix, 'lib', 'indicators3', '7', '*.so'))):
217 row = IndicatorPath.Row._make(Type=IndicatorPath.ItemType.Value,
218 Title=os.path.basename(path),
219 Icon='application-x-executable')
220 self._widgets.path_model.append(row)
221
222 def _on_option_changed(self, entry=None):
223 if not self._indicator_loaded:
224 return
225
226 name = self._option_type.value
227 error = None
228 warning = None
229
230 if name == Indicators.External:
231 if not str(self._option_path.value).strip():
232 error = C_('option-entry|indicators', 'Path/Service field is not filled')
233 elif name != self._name:
234 if self._is_duplicate and self._is_duplicate(name):
235 warning = C_('option-entry|indicators',
236 'Indicator "{name}" is already in the list.\n'
237 'It will be overwritten.').format(name=self._get_name(name, name))
238
239 self._widgets.ok.props.sensitive = error is None
240 self._widgets.add.props.sensitive = error is None
241 self._widgets.infobar.props.visible = error or warning
242 self._widgets.message.props.label = error or warning
243
244 if error:
245 self._widgets.infobar.props.message_type = Gtk.MessageType.WARNING
246 elif warning:
247 self._widgets.infobar.props.message_type = Gtk.MessageType.INFO
248 else:
249 self._widgets.infobar.props.message_type = Gtk.MessageType.OTHER
250
251 def on_option_type_types_changed(self, combo):
252 current = self._widgets.custom_options.props.page
253 if current != -1:
254 self._widgets.custom_options.get_nth_page(current).props.visible = False
255 current = self._name2page.get(combo.props.active_id, -1)
256 if current != -1:
257 self._widgets.custom_options.get_nth_page(current).props.visible = True
258 self._widgets.custom_options.props.page = current
259 if self._indicator_loaded:
260 defaults = self._get_defaults(combo.props.active_id)
261 self._option_text.enabled = Option.Text in defaults
262 self._option_image.enabled = Option.Image in defaults
263
264 def on_add_clicked(self, widget):
265 self._add_callback(self.get_indicator())
266 self._options = deepcopy(self._options)
267 self._on_option_changed()
268
269 @property
270 def add_callback(self):
271 return self._add_callback
272
273 @add_callback.setter
274 def add_callback(self, value):
275 self._add_callback = value
276 self._widgets.add.props.visible = value is not None
277
278 def set_indicator(self, options):
279 self._indicator_loaded = False
280 self._options = deepcopy(options)
281 self._name = options[Option.Name]
282
283 self._option_type.value = options[Option.Name]
284 self._option_path.value = options.get(Option.Path)
285
286 self._option_text.value = options.get(Option.Text, '')
287 self._option_text.enabled = Option.Text in options
288
289 self._option_image.value = options.get(Option.Image)
290 self._option_image.enabled = Option.Image in options
291
292 self._reversed = Option.Layout in options and LayoutSet.Reversed in options[Option.Layout]
293
294 hide_disabled = options.get(Option.HideDisabled, bool2string(False))
295 self._option_hide_disabled.value = hide_disabled or bool2string(True)
296
297 self._indicator_loaded = True
298 self._on_option_changed()
299
300 def get_indicator(self):
301 options = self._options
302
303 name = self._option_type.value
304 options[Option.Name] = name
305
306 options[Option.Layout] = set()
307 if name not in EmptyIndicators:
308 if self._option_text.enabled:
309 options[Option.Text] = self._option_text.value or None
310 options[Option.Layout].add(LayoutSet.Text)
311 if self._option_image.enabled:
312 options[Option.Image] = self._option_image.value or None
313 options[Option.Layout].add(LayoutSet.Image)
314 if self._option_text.enabled and self._option_image.enabled and self._reversed:
315 options[Option.Layout].add(LayoutSet.Reversed)
316
317 if LayoutSet.Text not in options[Option.Layout] and Option.Text in options:
318 del options[Option.Text]
319 if LayoutSet.Image not in options[Option.Layout] and Option.Image in options:
320 del options[Option.Image]
321
322 if name == Indicators.External:
323 options[Option.Path] = self._option_path.value
324 else:
325 options.pop(Option.Path, None)
326
327 if name == Indicators.Power and string2bool(self._option_hide_disabled.value):
328 options[Option.HideDisabled] = None
329 elif Option.HideDisabled in options:
330 options.pop(Option.HideDisabled, None)
331
332 return options
0 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1 # LightDM GTK Greeter Settings
2 # Copyright (C) 2014 Andrew P. <pan.pav.7c5@gmail.com>
3 #
4 # This program is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU General Public License version 3, as published
6 # by the Free Software Foundation.
7 #
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranties of
10 # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 # PURPOSE. See the GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License along
14 # with this program. If not, see <http://www.gnu.org/licenses/>.
15
16
17 import operator
18 import platform
19 import string
20 from copy import deepcopy
21
22 from gi.repository import (
23 Gtk,
24 Gdk)
25 from gi.repository.GObject import markup_escape_text as escape_markup
26
27 from lightdm_gtk_greeter_settings.helpers import (
28 C_,
29 get_greeter_version,
30 get_markup_error,
31 SimpleEnum,
32 TreeStoreDataWrapper)
33 from lightdm_gtk_greeter_settings.OptionEntry import BaseEntry
34
35
36 __all__ = ['BuiltInIndicators',
37 'EmptyIndicators',
38 'Indicators',
39 'IndicatorsEntry',
40 'Option',
41 'SingleIndicators']
42
43
44 class Indicators(SimpleEnum):
45 External = '~external'
46 Spacer = '~spacer'
47 Separator = '~separator'
48 Text = '~text'
49 Host = '~host'
50 Clock = '~clock'
51 Layout = '~layout'
52 Session = '~session'
53 Language = '~language'
54 A11y = '~a11y'
55 Power = '~power'
56
57
58 # Valid builtin indicators
59 BuiltInIndicators = set(Indicators) - {Indicators.External}
60
61 # Special indicators
62 EmptyIndicators = {Indicators.Spacer, Indicators.Separator}
63
64 # These indicators can have only one instance
65 SingleIndicators = set(Indicators) - {Indicators.External, Indicators.Text,
66 Indicators.Spacer, Indicators.Separator}
67
68 # Valid options names
69
70
71 class Option(SimpleEnum):
72 # Common
73 Name = 'name'
74 Layout = 'layout'
75 Text = 'text'
76 Image = 'image'
77 FallbackImage = 'fallback-image'
78 Tooltip = 'tooltip'
79 Markup = 'markup'
80 Expand = 'expand'
81 Align = 'align'
82 # External
83 Path = 'path'
84 # Power
85 HideDisabled = 'hide-disabled'
86
87
88 class Layout(SimpleEnum):
89 Empty = ''
90 Text = 'text'
91 Image = 'image'
92 ImageText = 'image-text'
93 TextImage = 'text-image'
94
95 @classmethod
96 def _to_set(cls, value):
97 return LayoutSet._str2set.get(value, set())
98
99
100 class LayoutSet(SimpleEnum):
101 Text = 'text'
102 Image = 'image'
103 Reversed = 'reversed'
104
105 _str2set = {
106 Layout.Empty: set(),
107 Layout.Text: {Text},
108 Layout.Image: {Image},
109 Layout.ImageText: {Text, Image},
110 Layout.TextImage: {Text, Image, Reversed}}
111
112 @classmethod
113 def _to_string(cls, value):
114 return next((k for k, v in cls._str2set.items() if v == value), '')
115
116
117 class Row(SimpleEnum):
118 Name = ()
119 Tooltip = ()
120 HasState = ()
121 State = ()
122 Options = ()
123 Icon = ()
124 Markup = ()
125
126
127 class IndicatorsEntry(BaseEntry):
128 # Readable names for indicators
129 Names = {
130 Indicators.External: C_('option-entry|indicators|name', 'External library/service'),
131 Indicators.Spacer: C_('option-entry|indicators|name', 'Spacer'),
132 Indicators.Separator: C_('option-entry|indicators|name', 'Separator'),
133 Indicators.Text: C_('option-entry|indicators|name', 'Text'),
134 Indicators.Clock: C_('option-entry|indicators|name', 'Clock'),
135 Indicators.Host: C_('option-entry|indicators|name', 'Host name'),
136 Indicators.Layout: C_('option-entry|indicators|name', 'Keyboard layout'),
137 Indicators.Session: C_('option-entry|indicators|name', 'Sessions menu'),
138 Indicators.Language: C_('option-entry|indicators|name', 'Languages menu'),
139 Indicators.A11y: C_('option-entry|indicators|name', 'Accessibility menu'),
140 Indicators.Power: C_('option-entry|indicators|name', 'Power menu')}
141 # Default icons for indicators to display in treeview
142 Icons = {
143 Indicators.A11y: 'preferences-desktop-accessibility',
144 Indicators.Session: 'document-properties',
145 Indicators.Power: 'system-shutdown'}
146 Tooltips = {
147 Indicators.Spacer: C_('option-entry|indicators|tooltip', 'Spacer'),
148 Indicators.Separator: C_('option-entry|indicators|tooltip', 'Separator'),
149 Indicators.Text: C_('option-entry|indicators|tooltip', 'Custom text or/and image'),
150 Indicators.Host: C_('option-entry|indicators|tooltip', 'Host name'),
151 Indicators.Clock: C_('option-entry|indicators|tooltip', 'Clock'),
152 Indicators.Layout: C_('option-entry|indicators|tooltip', 'Layout indicator'),
153 Indicators.Session: C_('option-entry|indicators|tooltip',
154 'Sessions menu (xfce, unity, gnome etc.)'),
155 Indicators.Language: C_('option-entry|indicators|tooltip', 'Languages menu'),
156 Indicators.A11y: C_('option-entry|indicators|tooltip', 'Accessibility menu'),
157 Indicators.Power: C_('option-entry|indicators|tooltip', 'Power menu')}
158 # Default options for indicators
159 DefaultOptions = {
160 Indicators.External: {Option.Text: None, Option.Image: None},
161 Indicators.Spacer: {Option.Layout: set()},
162 Indicators.Separator: {Option.Layout: set()},
163 Indicators.Text: {Option.Layout: {LayoutSet.Text}, Option.Text: None},
164 Indicators.Host: {Option.Layout: {LayoutSet.Text}, Option.Text: None},
165 Indicators.Clock: {Option.Layout: {LayoutSet.Text}, Option.Text: None},
166 Indicators.Layout: {Option.Layout: {LayoutSet.Text}, Option.Text: None},
167 Indicators.Session: {Option.Layout: {LayoutSet.Text, LayoutSet.Image},
168 Option.Text: None, Option.Image: None},
169 Indicators.Language: {Option.Layout: {LayoutSet.Text}, Option.Text: None},
170 Indicators.A11y: {Option.Layout: {LayoutSet.Image}, Option.Image: None},
171 Indicators.Power: {Option.Layout: {LayoutSet.Image}, Option.Image: None}}
172
173 def __init__(self, widgets):
174 super().__init__(widgets)
175
176 if get_greeter_version() < 0x020100:
177 self._get_value = self._get_value_19
178 self._on_button_release = self._on_button_release_19
179
180 for k, v in self.DefaultOptions.items():
181 v[Option.Name] = k
182
183 self._treeview = widgets['treeview']
184 self._selection = widgets['selection']
185 self._state_renderer = widgets['state_renderer']
186 self._state_column = widgets['state_column']
187 self._add = widgets['add']
188 self._remove = widgets['remove']
189 self._up = widgets['up']
190 self._down = widgets['down']
191 self._tools = widgets['tools']
192 self._model = widgets['model']
193 self._widgets_to_disable = [self._treeview, widgets['toolbar']]
194 self._properties_dialog = None
195 self._row_menu = None
196 self._tools_menu = None
197 self._show_unused = False
198
199 self._treeview.connect('key-press-event', self._on_key_press)
200 self._treeview.connect('row-activated', self._on_row_activated)
201 self._treeview.connect('button-release-event', self._on_button_release)
202 self._selection.connect('changed', self._on_selection_changed)
203 self._state_renderer.connect('toggled', self._on_state_toggled)
204
205 self._add.connect('clicked', self._on_add_clicked)
206 self._remove.connect('clicked', self._on_remove_clicked)
207 self._up.connect('clicked', self._on_up_clicked)
208 self._down.connect('clicked', self._on_down_clicked)
209 self._tools.connect('clicked', self._on_tools_clicked)
210
211 self._on_row_changed_id = self._model.connect('row-changed', self._on_model_changed)
212 self._on_row_deleted_id = self._model.connect('row-deleted', self._on_model_changed)
213 self._on_row_inserted_id = self._model.connect('row-inserted', self._on_model_changed)
214 self._on_rows_reordered_id = self._model.connect('rows-reordered', self._on_model_changed)
215
216 def _on_model_changed(self, *unused):
217 self._emit_changed()
218
219 def _get_value(self):
220 def fix_token(s):
221 s = s.replace('"', r'\"')
222 if any(c in s for c in string.whitespace):
223 s = '"' + s + '"'
224 return s
225
226 items = []
227 for row in self._model:
228 if row[Row.HasState] and not row[Row.State]:
229 continue
230
231 options = deepcopy(row[Row.Options].data)
232 name = options.pop(Option.Name)
233 defaults = deepcopy(self.DefaultOptions[name])
234
235 # text, image, layout=image-text -> text, image
236 if options.get(Option.Layout) == {LayoutSet.Text, LayoutSet.Image}:
237 del options[Option.Layout]
238
239 for k in defaults.keys() & options.keys():
240 if defaults[k] == options[k]:
241 del options[k]
242
243 if Option.Layout in options:
244 layout = options[Option.Layout]
245 options[Option.Layout] = LayoutSet._to_string(layout)
246 # text, layout=text -> layout=text
247 if LayoutSet.Text in layout and options.get(Option.Text, self) is None:
248 del options[Option.Text]
249 if LayoutSet.Image in layout and options.get(Option.Image, self) is None:
250 del options[Option.Image]
251
252 # name=~text, text=value -> ~~value
253 if name == Indicators.Text:
254 name = '~~' + (options.pop(Option.Text, None) or '')
255 elif name == Indicators.External:
256 name = options.pop(Option.Path, None) or ''
257
258 if not options:
259 items.append(fix_token(name))
260 else:
261 values = (fix_token(k) + '=' + fix_token(v) if v else fix_token(k)
262 for k, v in sorted(options.items(), key=operator.itemgetter(0)))
263 items.append(fix_token(name) + ': ' + ', '.join(values))
264 return '; '.join(items)
265
266 def _get_value_19(self):
267
268 items = []
269 for row in self._model:
270 if row[Row.HasState] and not row[Row.State]:
271 continue
272
273 options = deepcopy(row[Row.Options].data)
274 name = options.pop(Option.Name)
275
276 # name=~text, text=value -> ~~value
277 if name == Indicators.Text:
278 name = '~~' + (options.pop(Option.Text, None) or '')
279 elif name == Indicators.External:
280 name = options.pop(Option.Path, None) or ''
281
282 items.append(name)
283 return ';'.join(items)
284
285 def _set_value(self, value):
286 with self._model.handler_block(self._on_row_deleted_id):
287 self._model.clear()
288
289 for options in self._read_options_string(value):
290 name = options[Option.Name]
291
292 if name.startswith('~~'):
293 options.setdefault(Option.Text, name[2:])
294 options[Option.Name] = Indicators.Text
295 name = Indicators.Text
296 elif name not in BuiltInIndicators:
297 options.setdefault(Option.Path, name)
298 options[Option.Name] = Indicators.External
299 name = Indicators.External
300
301 defaults = deepcopy(self.DefaultOptions[name])
302
303 if Option.Markup in options:
304 markup = options[Option.Markup]
305 if markup is not None:
306 options[Option.Text] = markup
307 options[Option.Markup] = None
308
309 if Option.Layout in options:
310 options[Option.Layout] = Layout._to_set(options[Option.Layout])
311 else:
312 options[Option.Layout] = defaults.get(Option.Layout) or set()
313
314 if Option.Text in options:
315 options[Option.Layout].add(LayoutSet.Text)
316 elif LayoutSet.Text in options[Option.Layout]:
317 options.setdefault(Option.Text, None)
318 else:
319 defaults.pop(Option.Text, None)
320
321 if Option.Image in options:
322 options[Option.Layout].add(LayoutSet.Image)
323 elif LayoutSet.Image in options[Option.Layout]:
324 options.setdefault(Option.Image, None)
325 else:
326 defaults.pop(Option.Image, None)
327
328 options.update((k, defaults[k])
329 for k in defaults.keys() - options.keys())
330
331 with self._model.handler_block(self._on_row_changed_id), \
332 self._model.handler_block(self._on_row_inserted_id):
333 self._set_row(None, options, select=False)
334
335 if self._show_unused:
336 self._tools_show_unused_toggled()
337
338 self._selection.select_path(0)
339 self._on_model_changed()
340
341 def _read_options_string(self, s):
342
343 while s:
344 name, s = self._next_string_token(s, ':;')
345 if not name:
346 continue
347 options = {Option.Name: name}
348
349 if s.startswith(':'):
350 while s:
351 option, s = self._next_string_token(s[1:], '=,;')
352 if s.startswith('='):
353 value, s = self._next_string_token(s[1:], ',;')
354 else:
355 value = None
356 options[option] = value
357 if not s.startswith(','):
358 break
359
360 yield options
361 s = s[1:]
362
363 def _next_string_token(self, s, delimiters):
364 token = []
365 quoted = False
366
367 for last, c in enumerate(s):
368 if not c.isspace():
369 break
370
371 # Parsing quotes
372 for i, c in enumerate(s[last:], last):
373 if c == '"':
374 if i > last and s[i - 1] == '\\':
375 token.append(s[last:i - 1])
376 token.append('"')
377 else:
378 token.append(s[last:i])
379 quoted = not quoted
380 last = i + 1
381 elif not quoted and c in delimiters:
382 break
383
384 if quoted:
385 return '', ''
386
387 if last != i or last == 0:
388 token.append(s[last: i if c in delimiters else i + 1].rstrip())
389
390 return ''.join(token) if token else None, s[i:]
391
392 def _remove_selection(self):
393 model, rowiter = self._selection.get_selected()
394 if rowiter:
395 if self._show_unused and model[rowiter][Row.HasState]:
396 model[rowiter][Row.State] = False
397 else:
398 model.remove(rowiter)
399 self._on_selection_changed()
400
401 def _move_selection(self, move_up):
402 model, rowiter = self._selection.get_selected()
403 if rowiter:
404 next_iter = model.iter_previous(
405 rowiter) if move_up else model.iter_next(rowiter)
406 if self._show_unused and \
407 (model[rowiter][Row.HasState] and not model[rowiter][Row.State] or
408 model[next_iter][Row.HasState] and not model[next_iter][Row.State]):
409 with self._model.handler_block(self._on_rows_reordered_id):
410 model.swap(rowiter, next_iter)
411 else:
412 model.swap(rowiter, next_iter)
413 self._on_selection_changed()
414
415 def _create_row_tuple(self, options):
416 name = options[Option.Name]
417 error = None
418
419 text = options.get(Option.Text)
420 if Option.Text in options:
421 if text is not None:
422 if Option.Markup in options:
423 error = get_markup_error(text)
424 if error:
425 text = '<i>{text}</i>'.format(text=escape_markup(text))
426 else:
427 text = escape_markup(text)
428 text = '"' + text + '"'
429 elif name == Indicators.Host:
430 text = escape_markup(platform.node())
431
432 display_name = self.Names.get(name, name)
433 if name == Indicators.External:
434 if options.get(Option.Path):
435 title = '{name} ({value})'.format(name=escape_markup(display_name),
436 value=escape_markup(options[Option.Path]))
437 else:
438 title = escape_markup(display_name)
439 else:
440 title = escape_markup(display_name)
441
442 if text:
443 markup = '{name}: {text}'.format(name=title, text=text)
444 else:
445 markup = title
446
447 if Option.Image in options or get_greeter_version() < 0x020100:
448 icon = options.get(Option.Image)
449 if icon and icon.startswith('#'):
450 icon = icon[1:]
451 elif icon:
452 icon = 'image-x-generic'
453 else:
454 if name in self.Icons:
455 icon = self.Icons[name]
456 elif name in BuiltInIndicators:
457 icon = 'applications-system'
458 else:
459 icon = 'application-x-executable'
460 else:
461 icon = ''
462
463 has_state = name in SingleIndicators
464
465 return Row._make(Name=name,
466 Tooltip=self.Tooltips.get(name),
467 Icon=icon,
468 Markup=markup,
469 HasState=has_state, State=has_state,
470 Options=TreeStoreDataWrapper(options))
471
472 def _set_row(self, rowiter, options, select=True):
473 old_name = self._model[rowiter][Row.Name] if rowiter else None
474 new_name = options.get(
475 Option.Name, '') if options is not None else None
476 old_is_single = old_name in SingleIndicators
477 new_is_single = new_name in SingleIndicators
478
479 if new_name == old_name:
480 # The same row - just update
481 pass
482 elif old_is_single and new_is_single:
483 old_row = next(
484 (row for row in self._model if row[Row.Name] == new_name), None)
485 if old_row:
486 if self._show_unused:
487 # Swap current row with new_row
488 with self._model.handler_block(self._on_rows_reordered_id):
489 self._model.move_before(old_row.iter, rowiter)
490 with self._model.handler_block(self._on_row_changed_id):
491 self._model[rowiter][Row.State] = False
492 rowiter = old_row.iter
493 else:
494 # Replace current row with replace_row
495 with self._model.handler_block(self._on_row_deleted_id):
496 self._model.remove(old_row.iter)
497 elif old_is_single:
498 if self._show_unused:
499 # Uncheck old row and use new instead of it
500 with self._model.handler_block(self._on_row_changed_id):
501 self._model[rowiter][Row.State] = False
502 with self._model.handler_block(self._on_row_inserted_id):
503 new_iter = self._model.insert_after(rowiter)
504 rowiter = new_iter
505 elif new_is_single:
506 old_row = next(
507 (row for row in self._model if row[Row.Name] == new_name), None)
508 if old_row:
509 with self._model.handler_block(self._on_row_deleted_id):
510 self._model.remove(old_row.iter)
511
512 if rowiter and options:
513 with self._model.handler_block(self._on_row_changed_id):
514 self._model[rowiter] = self._create_row_tuple(options)
515 self._model.row_changed(self._model.get_path(rowiter), rowiter)
516 elif options:
517 rowiter = self._model.append(self._create_row_tuple(options))
518
519 if select and rowiter:
520 self._selection.select_iter(rowiter)
521
522 return rowiter
523
524 def _edit_indicator(self, options, add_callback=None):
525 if not self._properties_dialog:
526 from lightdm_gtk_greeter_settings.IndicatorPropertiesDialog \
527 import IndicatorPropertiesDialog as Dialog
528 self._properties_dialog = Dialog(is_duplicate=self._is_duplicate,
529 get_defaults=self.DefaultOptions.get,
530 get_name=self.Names.get)
531 self._properties_dialog.props.transient_for = self._treeview.get_toplevel()
532
533 self._properties_dialog.add_callback = add_callback
534 self._properties_dialog.set_indicator(options)
535 if self._properties_dialog.run() == Gtk.ResponseType.OK:
536 options = self._properties_dialog.get_indicator()
537 else:
538 options = None
539 self._properties_dialog.hide()
540 return options
541
542 def _is_duplicate(self, name):
543 return name in SingleIndicators and any(row[Row.Name] == name
544 for row in self._model if row[Row.State])
545
546 def _add_indicator(self, options):
547 self._set_row(None, options)
548
549 def _on_key_press(self, treeview, event):
550 if Gdk.keyval_name(event.keyval) == 'Delete':
551 self._remove_selection()
552 elif Gdk.keyval_name(event.keyval) == 'F2':
553 model, rowiter = self._selection.get_selected()
554 treeview.row_activated(model.get_path(rowiter), None)
555 else:
556 return False
557 return True
558
559 def _on_row_activated(self, treeview, path, column):
560 if column != self._state_column:
561 options = self._edit_indicator(self._model[path][Row.Options].data)
562 if options:
563 self._set_row(self._model.get_iter(path), options)
564
565 def _on_button_release(self, treeview, event):
566 if event.button != 3:
567 return False
568
569 pos = treeview.get_path_at_pos(int(event.x), int(event.y))
570 if not pos:
571 return False
572
573 row = self._model[pos[0]]
574 if row[Row.HasState] and not row[Row.State]:
575 return False
576
577 if not self._row_menu:
578 self._row_menu = Gtk.Menu()
579 self._row_menu_reset = Gtk.MenuItem(C_('option-entry|indicators',
580 'Reset to _defaults'))
581 self._row_menu_text = Gtk.CheckMenuItem(C_('option-entry|indicators',
582 'Display _label'))
583 self._row_menu_image = Gtk.CheckMenuItem(C_('option-entry|indicators',
584 'Display _image'))
585 self._row_menu_remove = Gtk.MenuItem(
586 C_('option-entry|indicators', '_Remove'))
587
588 self._row_menu_text_id = self._row_menu_text.connect('toggled',
589 self._on_row_menu_toggled,
590 Option.Text)
591 self._row_menu_image_id = self._row_menu_image.connect('toggled',
592 self._on_row_menu_toggled,
593 Option.Image)
594 self._row_menu_reset.connect(
595 'activate', self._on_row_menu_reset_clicked)
596 self._row_menu_remove.connect('activate', self._on_remove_clicked)
597
598 self._row_menu.append(self._row_menu_reset)
599 self._row_menu.append(self._row_menu_text)
600 self._row_menu.append(self._row_menu_image)
601 self._row_menu.append(Gtk.SeparatorMenuItem())
602 self._row_menu.append(self._row_menu_remove)
603
604 for item in self._row_menu:
605 if type(item) is not Gtk.SeparatorMenuItem:
606 item.props.use_underline = True
607 item.props.visible = True
608
609 options = row[Row.Options].data
610
611 with self._row_menu_text.handler_block(self._row_menu_text_id):
612 self._row_menu_text.props.active = Option.Text in options
613 with self._row_menu_image.handler_block(self._row_menu_image_id):
614 self._row_menu_image.props.active = Option.Image in options
615
616 editable = options[Option.Name] not in {
617 Indicators.Spacer, Indicators.Separator}
618 self._row_menu_reset.props.sensitive = editable
619 self._row_menu_text.props.sensitive = editable
620 self._row_menu_image.props.sensitive = editable
621
622 self._row_menu.popup(None, None, None, None, 0,
623 Gtk.get_current_event_time())
624
625 return True
626
627 def _on_button_release_19(self, treeview, event):
628 pass
629
630 def _on_row_menu_reset_clicked(self, item):
631 model, rowiter = self._selection.get_selected()
632 if rowiter:
633 name = model[rowiter][Row.Name]
634 options = deepcopy(self.DefaultOptions[name])
635 options[Option.Name] = name
636 with model.handler_block(self._on_row_changed_id):
637 model[rowiter] = self._create_row_tuple(options)
638 model.row_changed(model.get_path(rowiter), rowiter)
639
640 def _on_row_menu_toggled(self, item, option):
641 model, rowiter = self._selection.get_selected()
642 options = model[rowiter][Row.Options].data
643 if item.props.active:
644 options.setdefault(option, None)
645 else:
646 options.pop(option, None)
647 model[rowiter] = self._create_row_tuple(options)
648
649 def _on_state_toggled(self, renderer, path):
650 self._model[path][Row.State] = not self._model[path][Row.State]
651
652 def _on_selection_changed(self, selection=None):
653 model, rowiter = self._selection.get_selected()
654 if rowiter:
655 row = model[rowiter]
656 self._remove.props.sensitive = not row[
657 Row.HasState] or row[Row.State]
658 self._down.props.sensitive = model.iter_next(rowiter)
659 self._up.props.sensitive = model.iter_previous(rowiter)
660 self._treeview.scroll_to_cell(model.get_path(rowiter))
661 else:
662 self._remove.props.sensitive = False
663 self._down.props.sensitive = False
664 self._up.props.sensitive = False
665
666 def _on_add_clicked(self, button=None):
667 options = self._edit_indicator(self.DefaultOptions[Indicators.External],
668 add_callback=self._add_indicator)
669 if options:
670 self._set_row(None, options, select=True)
671
672 def _on_remove_clicked(self, button=None):
673 self._remove_selection()
674
675 def _on_up_clicked(self, button=None):
676 self._move_selection(move_up=True)
677
678 def _on_down_clicked(self, button=None):
679 self._move_selection(move_up=False)
680
681 def _on_tools_clicked(self, button=None):
682 if not self._tools_menu:
683 self._tools_menu = Gtk.Menu()
684 self._tools_menu.attach_to_widget(self._tools)
685
686 unused_item = Gtk.CheckMenuItem(C_('option-entry|indicators', 'Show unused items'))
687 unused_item.connect('toggled', self._tools_show_unused_toggled)
688 self._tools_menu.append(unused_item)
689
690 header_item = Gtk.MenuItem(C_('option-entry|indicators', 'Predefined templates:'))
691 header_item.props.sensitive = False
692 self._tools_menu.append(Gtk.SeparatorMenuItem())
693 self._tools_menu.append(header_item)
694
695 templates = (
696 ('host ~ clock, language, session, power',
697 '~host;~spacer;~language;~session;~power'),
698 ('host ~ clock ~ language, session, a11y, power',
699 '~host;~spacer;~clock;~spacer;~language;~session;~a11y;~power'),
700 ('host, layout, clock ~ language, session, power',
701 '~host;~layout;~clock;~spacer;~language;~session;~power'))
702
703 for title, value in templates:
704 item = Gtk.MenuItem(title)
705 item.connect('activate', self._on_tools_template_clicked, value)
706 self._tools_menu.append(item)
707
708 self._tools_menu.show_all()
709 self._tools_menu.popup(None, None, None, None, 0,
710 Gtk.get_current_event_time())
711
712 def _on_tools_template_clicked(self, item, value):
713 self._set_value(value)
714
715 def _tools_show_unused_toggled(self, widget=None):
716 if widget:
717 self._show_unused = widget.props.active
718 self._state_column.props.visible = self._show_unused
719
720 used = {row[Row.Name]: row
721 for row in self._model if row[Row.Name] in SingleIndicators}
722 if self._show_unused:
723 for name in SingleIndicators - used.keys():
724 options = deepcopy(self.DefaultOptions[name])
725 options[Option.Name] = name
726 with self._model.handler_block(self._on_row_changed_id),\
727 self._model.handler_block(self._on_row_inserted_id):
728 rowiter = self._set_row(None, options, select=False)
729 self._model[rowiter][Row.State] = False
730 else:
731 for row in used.values():
732 if row[Row.HasState] and not row[Row.State]:
733 with self._model.handler_block(self._on_row_deleted_id):
734 self._model.remove(row.iter)
0 #!/usr/bin/env python3
1 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2 # LightDM GTK Greeter Settings
3 # Copyright (C) 2014 Andrew P. <pan.pav.7c5@gmail.com>
4 #
5 # This program is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License version 3, as published
7 # by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranties of
11 # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
12 # PURPOSE. See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18 from gi.repository import Gtk
19
20 from lightdm_gtk_greeter_settings.helpers import WidgetsWrapper
21 from lightdm_gtk_greeter_settings.MultiheadSetupDialog import MultiheadSetupDialog
22 from lightdm_gtk_greeter_settings.OptionEntry import BaseEntry
23 from lightdm_gtk_greeter_settings.OptionGroup import BaseGroup
24
25
26 __all__ = ['MonitorsGroup']
27
28
29 class MonitorsGroup(BaseGroup):
30 GROUP_PREFIX = 'monitor:'
31
32 def __init__(self, widgets):
33 super().__init__(widgets)
34 self._entries = {}
35 self._widgets = WidgetsWrapper(widgets, 'multihead')
36 self._dialog = None
37 self._widgets['label'].connect('activate-link', self._on_label_link_activate)
38
39 def read(self, config):
40 self._entries.clear()
41 for name, section in config.items():
42 if not name.startswith(self.GROUP_PREFIX):
43 continue
44 name = name[len(self.GROUP_PREFIX):].strip()
45 entry = MonitorEntry(self._widgets)
46 entry['background'] = section.get('background', None)
47 entry['user-background'] = section.getboolean('user-background', None)
48 entry['laptop'] = section.getboolean('laptop', None)
49 self._entries[name] = entry
50 self.entry_added.emit(entry, name)
51
52 def write(self, config):
53 for name in config.sections():
54 if name.startswith(self.GROUP_PREFIX):
55 config.remove_section(name)
56 for name, entry in self._entries.items():
57 section = '{prefix} {name}'.format(prefix=self.GROUP_PREFIX, name=name)
58 config.add_section(section)
59 for key, value in entry:
60 if value is not None:
61 config.set(section, key, value)
62
63 def _on_label_link_activate(self, label, uri):
64 if not self._dialog:
65 self._dialog = MultiheadSetupDialog()
66 self._dialog.props.transient_for = self._widgets['label'].get_toplevel()
67
68 self._dialog.set_model(self._entries)
69
70 if self._dialog.run() == Gtk.ResponseType.OK:
71 current_names = set(self._entries.keys())
72 for name, values in self._dialog.get_model().items():
73 if name in self._entries:
74 self._entries[name].assign(values)
75 current_names.discard(name)
76 else:
77 entry = MonitorEntry(self._widgets, values)
78 self._entries[name] = entry
79 self.entry_added.emit(entry, name)
80 for name in current_names:
81 self.entry_added.emit(self._entries.pop(name), name)
82 self._dialog.hide()
83 return True
84
85
86 class MonitorEntry(BaseEntry):
87
88 def __init__(self, widgets, values=None):
89 super().__init__(widgets)
90 self._values = values or {}
91
92 def _get_value(self):
93 return self._values.copy()
94
95 def _set_value(self, value):
96 self._values = value.copy()
97
98 def __getitem__(self, key):
99 return self._values[key]
100
101 def __setitem__(self, key, value):
102 self._values[key] = value
103
104 def __iter__(self):
105 return iter(self._values.items())
106
107 def assign(self, values):
108 if not self._values == values:
109 self._values.update(values)
110 self._emit_changed()
1818 from builtins import max
1919 from locale import gettext as _
2020
21 from gi.repository import Gtk, Gdk, GdkPixbuf
22 from lightdm_gtk_greeter_settings import helpers
23 from lightdm_gtk_greeter_settings.OptionEntry import BaseEntry
24 from lightdm_gtk_greeter_settings.helpers import WidgetsWrapper, C_, ModelRowEnum
25
26 from lightdm_gtk_greeter_settings.OptionGroup import BaseGroup
21 from gi.repository import (
22 Gdk,
23 GdkPixbuf,
24 Gtk)
25
26 from lightdm_gtk_greeter_settings.helpers import (
27 C_,
28 check_path_accessibility,
29 get_data_path,
30 SimpleEnum,
31 WidgetsEnum)
2732
2833
2934 __all__ = ['MultiheadSetupDialog']
3035
3136
32 ROW = ModelRowEnum('NAME', 'BACKGROUND',
33 'USER_BG', 'USER_BG_DISABLED',
34 'LAPTOP', 'LAPTOP_DISABLED',
35 'BACKGROUND_PIXBUF', 'BACKGROUND_IS_COLOR')
36
37 BG_ROW = ModelRowEnum('TEXT', 'TYPE')
37 class Row(SimpleEnum):
38 Name = ()
39 Background = ()
40 UserBg = ()
41 UserBgDisabled = ()
42 Laptop = ()
43 LaptopDisabled = ()
44 BackgroundPixbuf = ()
45 BackgroundIsColor = ()
46 ErrorVisible = ()
47 ErrorText = ()
48
49
50 class BackgroundRow(SimpleEnum):
51 Text = ()
52 Type = ()
3853
3954
4055 class MultiheadSetupDialog(Gtk.Dialog):
41
4256 __gtype_name__ = 'MultiheadSetupDialog'
4357
4458 def __new__(cls):
4559 builder = Gtk.Builder()
46 builder.add_from_file(helpers.get_data_path('%s.ui' % cls.__name__))
60 builder.add_from_file(get_data_path('%s.ui' % cls.__name__))
4761 window = builder.get_object('multihead_setup_dialog')
48 window._widgets = WidgetsWrapper(builder)
62 window.builder = builder
4963 builder.connect_signals(window)
50 window._init_window()
64 window.init_window()
5165 return window
5266
53 def _init_window(self):
67 class Widgets(WidgetsEnum):
68 treeview = 'monitors_treeview'
69 model = 'monitors_model'
70 selection = 'monitors_selection'
71 bg_model = 'background_model'
72 bg_renderer = 'bg_renderer'
73 bg_column = 'background_column'
74 name_column = 'name_column'
75 remove = 'remove_button'
76 available = 'monitors_label'
77
78 builder = None
79
80 def init_window(self):
81 self._widgets = self.Widgets(builder=self.builder)
5482 self._group = None
5583 self._available_monitors = None
5684
57 self._remove_button = self._widgets['remove_button']
58 self._treeview = self._widgets['monitors_treeview']
59 self._model = self._widgets['monitors_model']
60 self._bg_model = self._widgets['background_model']
61 self._selection = self._treeview.get_selection()
62 self._bg_renderer = self._widgets['bg_renderer']
63 self._bg_column = self._widgets['background_column']
64 self._name_column = self._widgets['name_column']
6585 self._file_dialog = None
6686 self._color_dialog = None
6787 self._invalid_name_dialog = None
6888 self._name_exists_dialog = None
6989
70 self._bg_renderer.set_property('placeholder-text',
71 C_('option|multihead', 'Use default value'))
90 self._widgets.treeview.props.tooltip_column = Row.ErrorText
91 self._widgets.bg_renderer.set_property('placeholder-text',
92 C_('option|multihead', 'Use default value'))
7293
7394 def _update_monitors_label(self):
74 used = set(row[ROW.NAME] for row in self._model)
75 monitors = ['<a href="{name}">{name}</a>'.format(name=name)
76 for name in self._available_monitors if name not in used]
77 label = C_('option|monitors', 'Available monitors: <i>{monitors}</i>')\
78 .format(monitors=', '.join(monitors or ('none',)))
79 self._widgets['monitors_label'].props.label = label
80
95 if not self._available_monitors:
96 self._widgets.available.props.visible = False
97 return
98
99 used = set(row[Row.Name] for row in self._widgets.model)
100 monitors = []
101 for name in self._available_monitors:
102 if name in used:
103 monitors.append(name)
104 else:
105 monitors.append('<i><a href="{name}">{name}</a></i>'.format(name=name))
106
107 label = C_('option|multihead',
108 'Available monitors: {monitors}').format(monitors=', '.join(monitors))
109 self._widgets.available.props.label = label
110 self._widgets.available.props.visible = True
81111
82112 def set_model(self, values):
83 self._model.clear()
113 self._widgets.model.clear()
84114 for name, entry in values.items():
85 rowiter = self._model.append(ROW(NAME=name,
86 BACKGROUND=entry['background'],
87 USER_BG=entry['user-background'],
88 USER_BG_DISABLED=entry['user-background'] is None,
89 LAPTOP=entry['laptop'],
90 LAPTOP_DISABLED=entry['laptop'] is None,
91 BACKGROUND_PIXBUF=None,
92 BACKGROUND_IS_COLOR=False))
93 self._update_row_appearance(rowiter)
115 row = Row._make(Name=name,
116 Background=entry['background'],
117 UserBg=entry['user-background'],
118 UserBgDisabled=entry['user-background'] is None,
119 Laptop=entry['laptop'],
120 LaptopDisabled=entry['laptop'] is None,
121 BackgroundPixbuf=None,
122 BackgroundIsColor=False,
123 ErrorVisible=False,
124 ErrorText=None)
125 self._update_row_appearance(self._widgets.model.append(row))
94126 screen = Gdk.Screen.get_default()
95127 self._available_monitors = [screen.get_monitor_plug_name(i)
96128 for i in range(screen.get_n_monitors())]
97129 self._update_monitors_label()
98130
99131 def get_model(self):
100 return {row[ROW.NAME]:
101 {
102 'background': row[ROW.BACKGROUND],
103 'user-background': self._get_toggle_state(row, ROW.USER_BG, ROW.USER_BG_DISABLED),
104 'laptop': self._get_toggle_state(row, ROW.LAPTOP, ROW.LAPTOP_DISABLED)
105 }
106 for row in self._model}
132 return {
133 row[Row.Name]:
134 {
135 'background': row[Row.Background],
136 'user-background': self._get_toggle_state(row, Row.UserBg, Row.UserBgDisabled),
137 'laptop': self._get_toggle_state(row, Row.Laptop, Row.LaptopDisabled)
138 }
139 for row in self._widgets.model}
107140
108141 def _update_row_appearance(self, rowiter):
109 row = self._model[rowiter]
110 bg = row[ROW.BACKGROUND]
111
112 color = Gdk.color_parse(bg)
113 if color:
114 pixbuf = row[ROW.BACKGROUND_PIXBUF]
142 row = self._widgets.model[rowiter]
143 bg = row[Row.Background]
144
145 error = None
146 color = Gdk.RGBA()
147 if color.parse(bg):
148 pixbuf = row[Row.BackgroundPixbuf]
115149 if not pixbuf:
116 pixbuf = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB,
117 False, 8, 16, 16)
118 row[ROW.BACKGROUND_PIXBUF] = pixbuf
119 value = (int(0xFF / Gdk.Color.MAX_VALUE * color.red) << 24) + \
120 (int(0xFF / Gdk.Color.MAX_VALUE * color.green) << 16) + \
121 (int(0xFF / Gdk.Color.MAX_VALUE * color.blue) << 8)
150 pixbuf = GdkPixbuf.Pixbuf.new(GdkPixbuf.Colorspace.RGB, False, 8, 16, 16)
151 row[Row.BackgroundPixbuf] = pixbuf
152 value = (int(0xFF * color.red) << 24) + \
153 (int(0xFF * color.green) << 16) + \
154 (int(0xFF * color.blue) << 8)
122155 pixbuf.fill(value)
123 row[ROW.BACKGROUND_IS_COLOR] = True
156 row[Row.BackgroundIsColor] = True
124157 else:
125 row[ROW.BACKGROUND_IS_COLOR] = False
126
127 _TOGGLE_STATES = {None: True, False: None, True: False}
158 row[Row.BackgroundIsColor] = False
159 if bg:
160 error = check_path_accessibility(bg)
161
162 row[Row.ErrorVisible] = error is not None
163 row[Row.ErrorText] = error
164
165 ToggleStatesSeq = {None: True, False: None, True: False}
128166
129167 def _get_toggle_state(self, row, active_column, inconsistent_column):
130168 return None if row[inconsistent_column] else row[active_column]
131169
132170 def _toggle_state(self, row, active_column, inconsistent_column):
133171 state = self._get_toggle_state(row, active_column, inconsistent_column)
134 row[active_column] = self._TOGGLE_STATES[state]
135 row[inconsistent_column] = self._TOGGLE_STATES[state] is None
172 row[active_column] = self.ToggleStatesSeq[state]
173 row[inconsistent_column] = self.ToggleStatesSeq[state] is None
136174
137175 def on_monitors_add_clicked(self, button):
138176 prefix = 'monitor'
139 numbers = (row[ROW.NAME][len(prefix):]
140 for row in self._model if row[ROW.NAME].startswith(prefix))
177 numbers = (row[Row.Name][len(prefix):]
178 for row in self._widgets.model if row[Row.Name].startswith(prefix))
141179 try:
142180 max_number = max(int(v) for v in numbers if v.isdigit())
143181 except ValueError:
144182 max_number = 0
145 rowiter = self._model.append(ROW(NAME='%s%d' % (prefix, max_number + 1),
146 USER_BG=False,
147 USER_BG_ENABLED=False,
148 LAPTOP=True,
149 LAPTOP_ENABLED=False,
150 BACKGROUND='',
151 BACKGROUND_PIXBUF=None,
152 BACKGROUND_IS_COLOR=False))
153 self._treeview.set_cursor(self._model.get_path(rowiter), self._name_column, True)
183
184 row = Row._make(Name='%s%d' % (prefix, max_number + 1),
185 UserBg=False,
186 UserBgDisabled=False,
187 Laptop=True,
188 LaptopDisabled=False,
189 Background='',
190 BackgroundPixbuf=None,
191 BackgroundIsColor=False,
192 ErrorVisible=False,
193 ErrorText=None)
194 rowiter = self._widgets.model.append(row)
195 self._widgets.treeview.set_cursor(self._widgets.model.get_path(rowiter),
196 self._widgets.name_column, True)
154197
155198 def on_monitors_remove_clicked(self, button):
156 model, rowiter = self._treeview.get_selection().get_selected()
199 model, rowiter = self._widgets.selection.get_selected()
157200 model.remove(rowiter)
201 self._update_monitors_label()
158202
159203 def on_selection_changed(self, selection):
160 self._remove_button.props.sensitive = selection.get_selected()[1] is not None
204 self._widgets.remove.props.sensitive = all(selection.get_selected())
161205
162206 def on_monitors_label_activate_link(self, label, name):
163 rowiter = self._model.append(ROW(NAME=name,
164 USER_BG=False,
165 USER_BG_ENABLED=False,
166 LAPTOP=True,
167 LAPTOP_ENABLED=False,
168 BACKGROUND='',
169 BACKGROUND_PIXBUF=None,
170 BACKGROUND_IS_COLOR=False))
207 row = Row._make(Name=name,
208 UserBg=False,
209 UserBgDisabled=False,
210 Laptop=True,
211 LaptopDisabled=False,
212 Background='',
213 BackgroundPixbuf=None,
214 BackgroundIsColor=True,
215 ErrorVisible=False,
216 ErrorText=None)
217
218 rowiter = self._widgets.model.append(row)
171219 self._update_row_appearance(rowiter)
172 self._treeview.get_selection().select_iter(rowiter)
220 self._widgets.selection.select_iter(rowiter)
173221 self._update_monitors_label()
174222 return True
175223
177225 combobox.connect('format-entry-text', self.on_bg_combobox_format)
178226
179227 def on_bg_combobox_format(self, combobox, path):
180 model, rowiter = self._selection.get_selected()
181 item_type = combobox.props.model[path][BG_ROW.TYPE]
182 value = model[rowiter][ROW.BACKGROUND]
228 model, rowiter = self._widgets.selection.get_selected()
229 item_type = combobox.props.model[path][BackgroundRow.Type]
230 value = model[rowiter][Row.Background]
231
183232 if item_type == 'path':
184233 if not self._file_dialog:
185234 self._file_dialog = Gtk.FileChooserDialog(
186 parent=self,
187 buttons=(_('_OK'), Gtk.ResponseType.OK,
188 _('_Cancel'), Gtk.ResponseType.CANCEL),
189 title=C_('option|multihead', 'Select background file'))
235 parent=self,
236 buttons=(_('_OK'), Gtk.ResponseType.OK,
237 _('_Cancel'), Gtk.ResponseType.CANCEL),
238 title=C_('option|multihead', 'Select background file'))
190239 self._file_dialog.props.filter = Gtk.FileFilter()
191240 self._file_dialog.props.filter.add_mime_type('image/*')
192241 if self._file_dialog.run() == Gtk.ResponseType.OK:
193242 value = self._file_dialog.get_filename()
194243 self._file_dialog.hide()
195 elif item_type == 'icon':
244 elif item_type == 'color':
196245 if not self._color_dialog:
197246 self._color_dialog = Gtk.ColorChooserDialog(parent=self)
198247 if self._color_dialog.run() == Gtk.ResponseType.OK:
200249 self._color_dialog.hide()
201250 else:
202251 value = ''
252
203253 combobox.set_active(-1)
204254 return value
205255
206256 def on_bg_renderer_edited(self, renderer, path, new_text):
207 self._model[path][ROW.BACKGROUND] = new_text
208 self._update_row_appearance(self._model.get_iter(path))
257 self._widgets.model[path][Row.Background] = new_text
258 self._update_row_appearance(self._widgets.model.get_iter(path))
209259
210260 def on_name_renderer_edited(self, renderer, path, new_name):
211 old_name = self._model[path][ROW.NAME]
261 old_name = self._widgets.model[path][Row.Name]
212262 invalid_name = not new_name.strip()
213 name_in_use = new_name != old_name and any(new_name == row[ROW.NAME] for row in self._model)
263 name_in_use = new_name != old_name and any(new_name == row[Row.Name]
264 for row in self._widgets.model)
214265 if invalid_name or name_in_use:
215266 if not self._invalid_name_dialog:
216267 self._invalid_name_dialog = Gtk.MessageDialog(parent=self,
217268 buttons=Gtk.ButtonsType.OK)
218269 self._invalid_name_dialog.set_property('text',
219 C_('option|multihead', 'Invalid name: "{name}"')
220 .format(name=new_name))
270 C_('option|multihead',
271 'Invalid name: "{name}"')
272 .format(name=new_name))
221273 if name_in_use:
222274 message = C_('option|multihead', 'This name already in use.')
223275 else:
226278 self._invalid_name_dialog.run()
227279 self._invalid_name_dialog.hide()
228280 else:
229 self._model[path][ROW.NAME] = new_name
281 self._widgets.model[path][Row.Name] = new_name
230282 self._update_monitors_label()
231283
232284 def on_user_bg_renderer_toggled(self, renderer, path):
233 self._toggle_state(self._model[path],
234 ROW.USER_BG, ROW.USER_BG_DISABLED)
285 self._toggle_state(self._widgets.model[path], Row.UserBg, Row.UserBgDisabled)
235286
236287 def on_laptop_renderer_toggled(self, renderer, path):
237 self._toggle_state(self._model[path],
238 ROW.LAPTOP, ROW.LAPTOP_DISABLED)
239
240 class MonitorsGroup(BaseGroup):
241 GROUP_PREFIX = 'monitor:'
242
243 def __init__(self, widgets):
244 super().__init__(widgets)
245 self._entries = {}
246 self._widgets = WidgetsWrapper(widgets, 'multihead')
247 self._dialog = None
248 self._widgets['label'].connect('activate-link', self._on_label_link_activate)
249
250 def read(self, config):
251 self._entries.clear()
252 for name, section in config.items():
253 if not name.startswith(self.GROUP_PREFIX):
254 continue
255 name = name[len(self.GROUP_PREFIX):].strip()
256 entry = MonitorEntry(self._widgets)
257 entry['background'] = section.get('background', None)
258 entry['user-background'] = section.getboolean('user-background', None)
259 entry['laptop'] = section.getboolean('laptop', None)
260 self._entries[name] = entry
261 self.entry_added.emit(entry, name)
262
263 def write(self, config):
264 for name in config.sections():
265 if name.startswith(self.GROUP_PREFIX):
266 config.remove_section(name)
267 for name, entry in self._entries.items():
268 section = '{prefix} {name}'.format(prefix=self.GROUP_PREFIX, name=name)
269 config.add_section(section)
270 for key, value in entry:
271 if value is not None:
272 config.set(section, key, value)
273
274 def _on_label_link_activate(self, label, uri):
275 if not self._dialog:
276 self._dialog = MultiheadSetupDialog()
277 self._dialog.props.transient_for = self._widgets['label'].get_toplevel()
278
279 self._dialog.set_model(self._entries)
280
281 if self._dialog.run() == Gtk.ResponseType.OK:
282 current_names = set(self._entries.keys())
283 for name, values in self._dialog.get_model().items():
284 if name in self._entries:
285 self._entries[name].assign(values)
286 current_names.discard(name)
287 else:
288 entry = MonitorEntry(self._widgets, values)
289 self._entries[name] = entry
290 self.entry_added.emit(entry, name)
291 for name in current_names:
292 self.entry_added.emit(self._entries.pop(name), name)
293 self._dialog.hide()
294 return True
295
296
297 class MonitorEntry(BaseEntry):
298
299 def __init__(self, widgets, values=None):
300 super().__init__(widgets)
301 self._values = values or {}
302
303 def _get_value(self):
304 return self._values.copy()
305
306 def _set_value(self, value):
307 self._values = value.copy()
308
309 def __getitem__(self, key):
310 return self._values[key]
311
312 def __setitem__(self, key, value):
313 self._values[key] = value
314
315 def __iter__(self):
316 return iter(self._values.items())
317
318 def assign(self, values):
319 if not self._values == values:
320 self._values.update(values)
321 self._emit_changed()
288 self._toggle_state(self._widgets.model[path], Row.Laptop, Row.LaptopDisabled)
1414 # You should have received a copy of the GNU General Public License along
1515 # with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17 from builtins import isinstance
18 from collections import OrderedDict
19 from itertools import product
17
18 import time
2019 from locale import gettext as _
21 import os
22 import time
23
24 from gi.repository import Gtk, Gdk, GObject, GLib
25 from lightdm_gtk_greeter_settings.IconChooserDialog import IconChooserDialog
26 from lightdm_gtk_greeter_settings.IndicatorChooserDialog import \
27 IndicatorChooserDialog
28 from lightdm_gtk_greeter_settings.helpers import C_
29 from lightdm_gtk_greeter_settings.helpers import ModelRowEnum
30 from lightdm_gtk_greeter_settings.helpers import string2bool, bool2string
31
32
33 __all__ = ['BaseEntry', 'BooleanEntry', 'StringEntry', 'ClockFormatEntry',
34 'BackgroundEntry', 'IconEntry', 'IndicatorsEntry', 'PositionEntry',
35 'AdjustmentEntry', 'ChoiceEntry']
36
37
38 class BuilderWrapper:
39
40 def __init__(self, builder, base):
41 self._builder = builder
42 self._base = base
43
44 def __getitem__(self, key):
45 return self._builder.get_object('%s_%s' % (self._base, key))
20
21 from gi.repository import (
22 Gdk,
23 GLib,
24 GObject,
25 Gtk)
26 from lightdm_gtk_greeter_settings import helpers
27 from lightdm_gtk_greeter_settings.helpers import (
28 C_,
29 bool2string,
30 string2bool, SimpleEnum)
31
32
33 __all__ = [
34 'AccessibilityStatesEntry',
35 'AdjustmentEntry',
36 'BackgroundEntry',
37 'BaseEntry',
38 'BooleanEntry',
39 'ChoiceEntry',
40 'ClockFormatEntry',
41 'InvertedBooleanEntry',
42 'StringEntry',
43 'StringPathEntry']
4644
4745
4846 class BaseEntry(GObject.GObject):
5048 def __init__(self, widgets):
5149 super().__init__()
5250 self._widgets = widgets
53 self._use = widgets['use']
54 if self._use:
55 self._use.connect('notify::active', self._on_use_toggled)
51 self._widgets_to_disable = []
52
53 self.__use = widgets['use']
54 if self.__use:
55 self.__use.connect('notify::active', self.__on_use_toggled)
56
57 self.__error = widgets['error']
5658
5759 @property
5860 def value(self):
6365
6466 @value.setter
6567 def value(self, value):
66 if self._use:
67 self._use.props.active = True
68 if self.__use:
69 self.__use.set_active(True)
6870 formatted = self.set.emit(value)
6971 self._set_value(value if formatted is None else formatted)
7072
7173 @property
7274 def enabled(self):
73 '''Visual option state. You can get/set value of disabled option'''
74 if self._use:
75 return self._use.props.active
76 return True
75 return self._get_enabled()
7776
7877 @enabled.setter
7978 def enabled(self, value):
80 if self._use:
81 self._use.props.active = value
79 self._set_enabled(value)
80
81 @property
82 def error(self):
83 return self._get_error()
84
85 @error.setter
86 def error(self, value):
87 self._set_error(value)
8288
8389 @property
8490 def widgets(self):
8995 pass
9096
9197 @GObject.Signal(flags=GObject.SIGNAL_RUN_CLEANUP)
92 def get(self, value: str) -> str: # @IgnorePep8
98 def get(self, value: str) -> str:
9399 pass
94100
95101 @GObject.Signal(flags=GObject.SIGNAL_RUN_CLEANUP)
96 def set(self, value: str) -> str: # @IgnorePep8
102 def set(self, value: str) -> str:
97103 pass
98104
99105 def __repr__(self):
110116 def _set_value(self, value):
111117 raise NotImplementedError(self.__class__)
112118
119 def _get_error(self):
120 if self.__error:
121 return self.__error.props.tooltip_text
122 return None
123
124 def _set_error(self, text):
125 if self.__error:
126 self.__error.props.visible = text is not None
127 self.__error.props.tooltip_text = text
128
129 def _get_enabled(self):
130 if self.__use:
131 return self.__use.get_active()
132 return True
133
113134 def _set_enabled(self, value):
114 raise NotImplementedError(self.__class__)
115
116 def _on_use_toggled(self, toggle, *args):
117 self._set_enabled(self._use.props.active)
135 if self.__use:
136 self.__use.set_active(value)
137 if self._widgets_to_disable:
138 for widget in self._widgets_to_disable:
139 widget.props.sensitive = value
118140 self._emit_changed()
141
142 def _show_menu(self):
143 self.__on_label_clicked()
119144
120145 def _emit_changed(self, *unused):
121146 self.changed.emit()
122147
148 def __on_use_toggled(self, toggle, *unused):
149 self._set_enabled(self.__use.props.active)
150
123151
124152 class BooleanEntry(BaseEntry):
125153
127155 super().__init__(widgets)
128156 self._value = widgets['value']
129157 self._value.connect('notify::active', self._emit_changed)
158 self._widgets_to_disable.append(self._value)
130159
131160 def _get_value(self):
132161 return bool2string(self._value.props.active)
134163 def _set_value(self, value):
135164 self._value.props.active = string2bool(value)
136165
137 def _set_enabled(self, value):
138 self._value.props.sensitive = value
166
167 class InvertedBooleanEntry(BooleanEntry):
168
169 def __init__(self, widgets):
170 super().__init__(widgets)
171
172 def _get_value(self):
173 return bool2string(not self._value.props.active)
174
175 def _set_value(self, value):
176 self._value.props.active = not string2bool(value)
139177
140178
141179 class StringEntry(BaseEntry):
143181 def __init__(self, widgets):
144182 super().__init__(widgets)
145183 self._value = widgets['value']
184 self._widgets_to_disable.append(self._value)
185 if isinstance(self._value.props.parent, Gtk.ComboBox):
186 self._widgets_to_disable += [self._value.props.parent]
146187 self._value.connect('changed', self._emit_changed)
147188
148189 def _get_value(self):
151192 def _set_value(self, value):
152193 self._value.props.text = value or ''
153194
154 def _set_enabled(self, value):
155 self._value.props.sensitive = value
195
196 class StringPathEntry(BaseEntry):
197
198 class Row(helpers.SimpleEnum):
199 Title = ()
200 Type = ()
201
202 class ItemType(SimpleEnum):
203 Select = 'select-path'
204 Value = 'value'
205 Separator = 'separator'
206
207 def __init__(self, widgets):
208 super().__init__(widgets)
209
210 self._file_dialog = None
211
212 self._combo = widgets['combo']
213 self._entry = widgets['entry']
214 self._widgets_to_disable.append(self._combo)
215 self._filters = ()
216
217 self._entry.connect('changed', self._emit_changed)
218 self._combo.connect('format-entry-text', self._on_combobox_format)
219
220 self._combo.set_row_separator_func(self._row_separator_callback, None)
221
222 def add_filter(self, file_filter):
223 if self._file_dialog:
224 self._file_dialog.add_filter(file_filter)
225 elif self._filters:
226 self._filters.append(file_filter)
227 else:
228 self._filters = [file_filter]
229
230 def _get_value(self):
231 return self._entry.props.text
232
233 def _set_value(self, value):
234 self._entry.props.text = value or ''
235
236 def _row_separator_callback(self, model, rowiter, data):
237 return model[rowiter][self.Row.Type] == self.ItemType.Separator
238
239 def _on_combobox_format(self, combobox, path):
240 value = self._entry.props.text
241 item_id = combobox.get_active_id()
242 if item_id == self.ItemType.Select:
243 if not self._file_dialog:
244 self._file_dialog = Gtk.FileChooserDialog(
245 parent=self._combo.get_toplevel(),
246 buttons=(_('_OK'), Gtk.ResponseType.OK,
247 _('_Cancel'), Gtk.ResponseType.CANCEL),
248 title=C_('option|StringPathEntry', 'Select path'))
249 for f in self._filters:
250 self._file_dialog.add_filter(f)
251 if self._file_dialog.run() == Gtk.ResponseType.OK:
252 value = self._file_dialog.get_filename()
253 self._file_dialog.hide()
254 elif item_id == self.ItemType.Value:
255 value = combobox.props.model[path][self.Row.Title]
256
257 combobox.set_active(-1)
258 combobox.grab_focus()
259 return value
156260
157261
158262 class AdjustmentEntry(BaseEntry):
161265 super().__init__(widgets)
162266 self._value = widgets['adjustment']
163267 self._view = widgets['view']
268 self._widgets_to_disable.append(self._view)
164269 self._value.connect('value-changed', self._emit_changed)
165270
166271 def _get_value(self):
172277 except ValueError:
173278 self._value.props.value = 0
174279
175 def _set_enabled(self, value):
176 self._view.props.sensitive = value
177
178280
179281 class ChoiceEntry(BaseEntry):
180282
181283 def __init__(self, widgets):
182284 super().__init__(widgets)
183285 self._value = widgets['value']
286 self._widgets_to_disable.append(self._value)
184287 self._value.connect('changed', self._emit_changed)
185288
186289 def _get_value(self):
188291
189292 def _set_value(self, value):
190293 self._value.props.active_id = value or ''
191
192 def _set_enabled(self, value):
193 self._value.props.sensitive = value
194294
195295
196296 class ClockFormatEntry(StringEntry):
215315 self._image_value = widgets['image_value']
216316 self._color_value = widgets['color_value']
217317
218 self._color_choice.connect('toggled', self._on_color_choice_toggled)
318 self._on_choice_id = self._color_choice.connect('toggled', self._on_color_choice_toggled)
219319 self._color_value.connect('color-set', self._on_color_set)
220320 self._image_value.connect('file-set', self._on_file_set)
221321
223323 if self._image_choice.props.active:
224324 return self._image_value.get_filename() or ''
225325 else:
226 return self._color_value.props.rgba.to_string()
326 r, g, b, __ = (int(0xFF * v) for v in self._color_value.props.rgba)
327 return '#%02x%02x%02x' % (r, g, b)
227328
228329 def _set_value(self, value):
229330 if value is None:
233334 if not rgba.parse(value):
234335 rgba = None
235336
236 self._color_choice.props.active = rgba is not None
237 self._image_choice.props.active = rgba is None
337 with self._color_choice.handler_block(self._on_choice_id):
338 self._color_choice.props.active = rgba is not None
339 self._image_choice.props.active = rgba is None
238340
239341 if rgba is not None:
240342 self._color_value.props.rgba = rgba
245347 else:
246348 self._image_value.unselect_all()
247349
350 self._emit_changed()
351
248352 def _on_color_choice_toggled(self, toggle):
249353 self._emit_changed()
250354
266370 def __init__(self, widgets):
267371 super().__init__(widgets)
268372 self._value = widgets['value']
373 self._widgets_to_disable.append(self._value)
269374 self._value.connect('font-set', self._emit_changed)
270375
271376 def _get_value(self):
275380 self._value.props.font_name = value or ''
276381
277382
278 class IconEntry(BaseEntry):
279
280 def __init__(self, widgets):
281 super().__init__(widgets)
282 self._value = None
283 self._image = widgets['image']
284 self._button = widgets['button']
285 self._menu = widgets['menu']
286 self._icon_item = widgets['icon_item']
287 self._path_item = widgets['path_item']
288 self._path_dialog = widgets['path_dialog']
289 self._path_dialog_preview = widgets['path_dialog_preview']
290 self._icon_dialog = None
291
292 self._button.connect('toggled', self._on_button_toggled)
293 self._menu.connect('hide', self._on_menu_hide)
294 self._icon_item.connect('activate', self._on_select_icon)
295 self._path_item.connect('activate', self._on_select_path)
296 self._path_dialog.connect(
297 'update-preview', self._on_update_path_preview)
298
299 def _get_value(self):
300 return self._value
301
302 def _set_value(self, value):
303 if value.startswith('#'):
304 self._set_icon(value[1:])
305 else:
306 self._set_path(value)
307
308 def _set_icon(self, icon):
309 self._value = '#' + icon
310 self._image.set_from_icon_name(icon, Gtk.IconSize.DIALOG)
311 self._update_menu_items(icon=icon)
312 self._emit_changed()
313
314 def _set_path(self, path):
315 self._value = path
316 self._image.set_from_file(path)
317 self._update_menu_items(path=path)
318 self._emit_changed()
319
320 def _update_menu_items(self, icon=None, path=None):
321 if icon:
322 self._icon_item.get_child().set_markup(C_('option-entry|icon',
323 '<b>Icon: {icon}</b>')
324 .format(icon=icon))
325 else:
326 self._icon_item.get_child().set_markup(
327 C_('option-entry|icon', 'Select icon name...'))
328
329 if path:
330 self._path_item.get_child()\
331 .set_markup(C_('option-entry|icon',
332 '<b>File: {path}</b>')
333 .format(path=os.path.basename(path)))
334 else:
335 self._path_item.get_child().set_markup(
336 C_('option-entry|icon', 'Select file...'))
337
338 def _get_menu_position(self, menu, widget):
339 allocation = widget.get_allocation()
340 x, y = widget.get_window().get_position()
341 x += allocation.x
342 y += allocation.y + allocation.height
343 return (x, y, False)
344
345 def _on_button_toggled(self, toggle):
346 if toggle.props.active:
347 self._menu.popup(None, None, self._get_menu_position,
348 self._button, 3, Gtk.get_current_event_time())
349
350 def _on_menu_hide(self, toggle):
351 self._button.props.active = False
352
353 def _on_select_icon(self, item):
354 if not self._icon_dialog:
355 self._icon_dialog = IconChooserDialog()
356 self._icon_dialog.props.transient_for = self._image.get_toplevel()
357 if self._value.startswith('#'):
358 self._icon_dialog.select_icon(self._value[1:])
359 if self._icon_dialog.run() == Gtk.ResponseType.OK:
360 self._set_icon(self._icon_dialog.get_iconname())
361 self._icon_dialog.hide()
362
363 def _on_select_path(self, item):
364 self._path_dialog.select_filename(self._value)
365 if self._path_dialog.run() == Gtk.ResponseType.OK:
366 self._set_path(self._path_dialog.get_filename())
367 self._path_dialog.hide()
368
369 def _on_update_path_preview(self, chooser):
370 path = chooser.get_filename()
371 if not path or not os.path.isfile(path):
372 self._path_dialog_preview.props.icon_name = 'unknown'
373 return
374 self._path_dialog_preview.set_from_file(path)
375
376
377 class IndicatorsEntry(BaseEntry):
378 ROW = ModelRowEnum('NAME', 'TOOLTIP', 'EDITABLE', 'HAS_STATE', 'STATE')
379 NAMES_DELIMITER = ';'
380 DEFAULT_TOOLTIPS = {'~spacer': C_('option-entry|indicators', 'Spacer'),
381 '~separator': C_('option-entry|indicators', 'Separator')}
382
383 def __init__(self, widgets):
384 super().__init__(widgets)
385 self._toolbar = widgets['toolbar']
386 self._treeview = widgets['treeview']
387 self._selection = widgets['selection']
388 self._state_renderer = widgets['state_renderer']
389 self._name_column = widgets['name_column']
390 self._name_renderer = widgets['name_renderer']
391 self._add = widgets['add']
392 self._remove = widgets['remove']
393 self._up = widgets['up']
394 self._down = widgets['down']
395 self._model = widgets['model']
396 self._indicators_dialog = None
397 self._initial_items = OrderedDict((item.NAME, item)
398 for item in map(self.ROW, self._model))
399
400 self._treeview.connect('key-press-event', self._on_key_press)
401 self._selection.connect('changed', self._on_selection_changed)
402 self._state_renderer.connect('toggled', self._on_state_toggled)
403 self._name_renderer.connect('edited', self._on_name_edited)
404 self._add.connect('clicked', self._on_add)
405 self._remove.connect('clicked', self._on_remove)
406 self._up.connect('clicked', self._on_up)
407 self._down.connect('clicked', self._on_down)
408
409 self._model.connect('row-changed', self._on_model_changed)
410 self._model.connect('row-deleted', self._on_model_changed)
411 self._model.connect('row-inserted', self._on_model_changed)
412 self._model.connect('rows-reordered', self._on_model_changed)
413
414 def _on_model_changed(self, *unused):
415 self._emit_changed()
416
417 def _get_value(self):
418 names = (row[self.ROW.NAME] for row in self._model
419 if not row[self.ROW.HAS_STATE] or row[self.ROW.STATE])
420 return self.NAMES_DELIMITER.join(names)
421
422 def _set_value(self, value):
423 self._model.clear()
424 last_options = self._initial_items.copy()
383 class AccessibilityStatesEntry(BaseEntry):
384
385 Options = ('keyboard', 'reader', 'contrast', 'font')
386
387 def __init__(self, widgets):
388 super().__init__(widgets)
389
390 self._states = {name: widgets[name] for name in self.Options}
391
392 for w in self._states.values():
393 w.connect('changed', self._emit_changed)
394
395 def _get_value(self):
396 states = {name: widget.props.active_id
397 for (name, widget) in self._states.items()}
398 return ';'.join(state + name
399 for (name, state) in states.items() if state not in {None, '-'})
400
401 def _set_value(self, value):
425402 if value:
426 for name in value.split(self.NAMES_DELIMITER):
427 try:
428 self._model[self._model.append(last_options.pop(name))]\
429 [self.ROW.STATE] = True
430 except KeyError:
431 self._model.append(self._get_indicator_tuple(name))
432
433 for item in list(last_options.values()):
434 self._model.append(item)
435
436 self._selection.select_path(0)
437
438 def _set_enabled(self, value):
439 self._toolbar.props.sensitive = value
440 self._treeview.props.sensitive = value
441
442 def _remove_selection(self):
443 model, rowiter = self._selection.get_selected()
444 if rowiter:
445 previter = model.iter_previous(rowiter)
446 model.remove(rowiter)
447 if previter:
448 self._selection.select_iter(previter)
449
450 def _move_selection(self, move_up):
451 model, rowiter = self._selection.get_selected()
452 if rowiter:
453 if move_up:
454 model.swap(rowiter, model.iter_previous(rowiter))
455 else:
456 model.swap(rowiter, model.iter_next(rowiter))
457 self._on_selection_changed(self._selection)
458
459 def _check_indicator(self, name):
460 ''' Returns True if name is valid, error message or False otherwise '''
461 if not name:
462 return False
463 elif name not in ('~spacer', '~separator'):
464 if any(row[self.ROW.NAME] == name for row in self._model):
465 return C_('option-entry|indicators',
466 'Indicator "{indicator}" is already in the list')\
467 .format(indicator=name)
468 return True
469
470 def _add_indicator(self, name):
471 if name:
472 rowiter = self._model.append(self._get_indicator_tuple(name))
473 self._selection.select_iter(rowiter)
474 self._treeview.grab_focus()
475
476 def _get_indicator_tuple(self, name):
477 tooltip = self.DEFAULT_TOOLTIPS.get(name,
478 C_('option-entry|indicators', 'Indicator: {name}')
479 .format(name=name))
480 editable = name not in ('~spacer', '~separator')
481 return self.ROW(NAME=name, TOOLTIP=tooltip, EDITABLE=editable,
482 HAS_STATE=False, STATE=False)
483
484 def _on_key_press(self, treeview, event):
485 if Gdk.keyval_name(event.keyval) == 'Delete':
486 self._remove_selection()
487 elif Gdk.keyval_name(event.keyval) == 'F2':
488 model, rowiter = self._selection.get_selected()
489 if rowiter and model[rowiter][self.COLUMN.EDITABLE]:
490 self._treeview.set_cursor(
491 model.get_path(rowiter), self.COLUMN.NAME, True)
492 else:
493 return False
494 return True
495
496 def _on_state_toggled(self, renderer, path):
497 self._model[path][self.ROW.STATE] = not self._model[path][self.ROW.STATE]
498
499 def _on_name_edited(self, renderer, path, name):
500 check = self._check_indicator(name)
501 if not isinstance(check, str) and check:
502 self._model[path][self.ROW.NAME] = name
503
504 def _on_selection_changed(self, selection):
505 model, rowiter = selection.get_selected()
506 has_selection = rowiter is not None
507 self._remove.props.sensitive = has_selection and \
508 not model[rowiter][self.ROW.HAS_STATE]
509 self._down.props.sensitive = has_selection and model.iter_next(
510 rowiter) is not None
511 self._up.props.sensitive = has_selection and model.iter_previous(
512 rowiter) is not None
513 if has_selection:
514 self._treeview.scroll_to_cell(model.get_path(rowiter))
515
516 def _on_add(self, *args):
517 if not self._indicators_dialog:
518 self._indicators_dialog = IndicatorChooserDialog(
519 check_callback=self._check_indicator,
520 add_callback=self._add_indicator)
521 self._indicators_dialog.props.transient_for = \
522 self._treeview.get_toplevel()
523 name = self._indicators_dialog.get_indicator()
524 if name:
525 self._add_indicator(name)
526
527 def _on_remove(self, *args):
528 self._remove_selection()
529
530 def _on_up(self, *args):
531 self._move_selection(move_up=True)
532
533 def _on_down(self, *args):
534 self._move_selection(move_up=False)
535
536
537 class PositionEntry(BaseEntry):
538
539 class Dimension:
540
541 def __init__(self, name, widgets, anchors, on_changed):
542 self.__dict__.update(('_%s' % w, widgets['%s_%s' % (name, w)])
543 for w in ('value', 'percents', 'mirror',
544 'adjustment'))
545 self._name = name
546 self._on_changed = on_changed
547 self._anchor = ''
548
549 self._percents.connect('toggled', self._on_percents_toggled)
550 self._mirror.connect('toggled', self._on_mirror_toggled)
551 self._on_value_changed_id = self._adjustment.connect(
552 'value-changed',
553 self._on_value_changed)
554
555 for (x, y), widget in list(anchors.items()):
556 widget.connect('toggled', self._on_anchor_toggled, self,
557 x if self._name == 'x' else y)
558
559 @property
560 def value(self):
561 return '%s%d%s,%s' % ('-' if self._mirror.props.active else '',
562 int(self._value.props.value),
563 '%' if self._percents.props.active else '',
564 self._anchor)
565
566 @value.setter
567 def value(self, dim_value):
568 value, _, anchor = dim_value.partition(',')
569
570 percents = value and value[-1] == '%'
571 if percents:
572 value = value[:-1]
573
574 try:
575 p = int(value)
576 except ValueError:
577 p = 0
578
579 negative = (p < 0) or (p == 0 and value and value[0] == '-')
580
581 if not anchor or anchor not in ('start', 'center', 'end'):
582 if negative:
583 anchor = 'end'
584 else:
585 anchor = 'start'
586 self._anchor = anchor
587
588 self._percents.props.active = percents
589 self._adjustment.props.upper = 100 if self._percents.props.active \
590 else 10000
591 self._mirror.props.active = negative
592 with self._adjustment.handler_block(self._on_value_changed_id):
593 self._adjustment.props.value = -p if negative else p
594
595 @property
596 def anchor(self):
597 return self._anchor
598
599 def get_scaled_position(self, screen, window, scale):
600 screen_size = screen[0] if self._name == 'x' else screen[1]
601 window_size = window[0] if self._name == 'x' else window[1]
602
603 p = int(self._adjustment.props.value)
604 if self._percents.props.active:
605 p = screen_size * p / 100
606 else:
607 p *= scale
608
609 if self._mirror.props.active:
610 p = screen_size - p
611
612 if self._anchor == 'center':
613 p -= window_size / 2
614 elif self._anchor == 'end':
615 p -= window_size
616
617 p = int(p)
618
619 if p + window_size > screen_size:
620 p = screen_size - window_size
621 if p < 0:
622 p = 0
623
624 return p
625
626 def _on_value_changed(self, widget):
627 self._on_changed(self)
628
629 def _on_percents_toggled(self, toggle):
630 self._adjustment.props.upper = 100 if toggle.props.active \
631 else 10000
632 self._on_changed(self)
633
634 def _on_mirror_toggled(self, toggle):
635 self._on_changed(self)
636
637 def _on_anchor_toggled(self, toggle, dimension, anchor):
638 if dimension == self and toggle.props.active \
639 and anchor != self._anchor:
640 self._anchor = anchor
641 self._on_changed(self)
642
643 REAL_WINDOW_SIZE = 430, 210
644
645 def __init__(self, widgets):
646 super().__init__(widgets)
647 self._screen = widgets['screen']
648 self._window = widgets['window']
649 self._screen_pos = (0, 0)
650 self._screen_size = (0, 0)
651
652 self._anchors = {(x, y): widgets['base_%s_%s' % (x, y)]
653 for x, y in product(('start', 'center', 'end'),
654 repeat=2)}
655
656 self._on_resize_id = self._screen.connect(
657 'size-allocate', self._on_resize)
658 self._screen.connect('draw', self._on_draw_screen_border)
659 self._screen.connect('screen-changed', self._on_gdkscreen_changed)
660 self._on_gdkscreen_monitors_changed_id = \
661 self._screen.get_screen().connect('monitors-changed',
662 self.
663 _on_gdkscreen_monitors_changed)
664
665 self._x = PositionEntry.Dimension(
666 'x', widgets, self._anchors, self._on_dimension_changed)
667 self._y = PositionEntry.Dimension(
668 'y', widgets, self._anchors, self._on_dimension_changed)
669
670 def _get_value(self):
671 return self._x.value + ' ' + self._y.value
672
673 def _set_value(self, value):
674 if value:
675 x, _, y = value.partition(' ')
676 self._x.value = x
677 self._y.value = y or x
678 self._anchors[self._x.anchor, self._y.anchor].props.active = True
679 self._update_layout()
680
681 def _update_layout(self):
682 screen = self._screen.get_toplevel().get_screen()
683 geometry = screen.get_monitor_geometry(screen.get_primary_monitor())
684 window_allocation = self._window.get_allocation()
685 window_size = window_allocation.width, window_allocation.height
686 scale = self._screen_size[0] / geometry.width
687
688 x = self._screen_pos[0] + \
689 self._x.get_scaled_position(self._screen_size, window_size, scale)
690 y = self._screen_pos[1] + \
691 self._y.get_scaled_position(self._screen_size, window_size, scale)
692
693 self._screen.move(self._window, x, y)
694 self._screen.check_resize()
695
696 def _on_resize(self, widget, allocation):
697 screen = self._screen.get_toplevel().get_screen()
698 geometry = screen.get_monitor_geometry(screen.get_primary_monitor())
699 screen_scale = geometry.height / geometry.width
700
701 width = allocation.width
702 height = int(width * screen_scale)
703
704 if height > allocation.height:
705 height = allocation.height
706 width = min(width, int(height / screen_scale))
707 self._screen_pos = int((allocation.width - width) / 2), 0
708 self._screen_size = (width, height)
709
710 with self._screen.handler_block(self._on_resize_id):
711 scale = width / geometry.width
712 self._window.set_size_request(
713 PositionEntry.REAL_WINDOW_SIZE[0] * scale,
714 PositionEntry.REAL_WINDOW_SIZE[1] * scale)
715 self._update_layout()
716
717 def _on_draw_screen_border(self, widget, cr):
718 width, height = self._screen_size
719 x, y = self._screen_pos
720 line_width = 2
721 width -= line_width
722 height -= line_width
723
724 x += line_width / 2
725 y += line_width / 2
726 cr.set_source_rgba(0.2, 0.1, 0.2, 0.8)
727 cr.set_line_width(line_width)
728
729 cr.move_to(x, y)
730 cr.line_to(x + width, y)
731 cr.line_to(x + width, y + height)
732 cr.line_to(x, y + height)
733 cr.line_to(x, y - line_width / 2)
734 cr.stroke_preserve()
735
736 return False
737
738 def _on_gdkscreen_changed(self, widget, prev_screen):
739 widget.queue_resize()
740 if prev_screen:
741 prev_screen.disconnect(self._on_gdkscreen_monitors_changed_id)
742 self._on_gdkscreen_monitors_changed_id = widget.get_screen().connect(
743 'monitors-changed',
744 self._on_gdkscreen_monitors_changed)
745
746 def _on_gdkscreen_monitors_changed(self, screen):
747 self._screen.queue_resize()
748
749 def _on_dimension_changed(self, dimension):
750 with self._screen.handler_block(self._on_resize_id):
751 self._update_layout()
752 self._emit_changed()
403 states = dict((v[1:], v[0]) if v[0] in ('-', '+', '~') else (v, '-')
404 for v in value.split(';') if v)
405 else:
406 states = {}
407 for name in self.Options:
408 self._states[name].props.active_id = states.get(name, '-')
1616
1717
1818 from gi.repository import GObject
19
20 from lightdm_gtk_greeter_settings.helpers import WidgetsWrapper
1921 from lightdm_gtk_greeter_settings.OptionEntry import BaseEntry
20 from lightdm_gtk_greeter_settings.helpers import WidgetsWrapper
2122
2223
23 __all__ = ['BaseGroup', 'SimpleGroup']
24 __all__ = [
25 'BaseGroup',
26 'SimpleGroup']
2427
2528
2629 # Broken solution - too complex
27
2830 class BaseGroup(GObject.GObject):
2931
3032 def __init__(self, widgets):
3133 super().__init__()
34 self.__defaults_wrapper = None
3235
3336 def read(self, config):
3437 raise NotImplementedError(self.__class__)
3538
3639 def write(self, config):
40 raise NotImplementedError(self.__class__)
41
42 @property
43 def defaults(self):
44 if not self.__defaults_wrapper:
45 class DefaultsWrapper:
46
47 def __init__(self, getter):
48 self._getter = getter
49
50 def __getitem__(self, key):
51 return self._getter(key)
52 self.__defaults_wrapper = DefaultsWrapper(self._get_default)
53 return self.__defaults_wrapper
54
55 def _get_default(self, key):
3756 raise NotImplementedError(self.__class__)
3857
3958 @GObject.Signal
84103 config.add_section(self._name)
85104
86105 for key, entry in self._entries.items():
87 if entry.enabled:
106 value = entry.value
107 if entry.enabled and value != self._get_default(key):
88108 config.set(self._name, key, entry.value)
89109 else:
90110 config.remove_option(self._name, key)
91111
112 def _get_default(self, key):
113 return self._defaults.get(key)
0 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1 # LightDM GTK Greeter Settings
2 # Copyright (C) 2014 Andrew P. <pan.pav.7c5@gmail.com>
3 #
4 # This program is free software: you can redistribute it and/or modify it
5 # under the terms of the GNU General Public License version 3, as published
6 # by the Free Software Foundation.
7 #
8 # This program is distributed in the hope that it will be useful, but
9 # WITHOUT ANY WARRANTY; without even the implied warranties of
10 # MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11 # PURPOSE. See the GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License along
14 # with this program. If not, see <http://www.gnu.org/licenses/>.
15
16
17 from itertools import product
18
19 from gi.repository import (
20 Gdk,
21 Gtk)
22
23 from lightdm_gtk_greeter_settings.helpers import WidgetsWrapper
24 from lightdm_gtk_greeter_settings.OptionEntry import BaseEntry
25
26
27 __all__ = ['PositionEntry']
28
29
30 class PositionEntry(BaseEntry):
31
32 class Dimension:
33
34 def __init__(self, widgets, on_changed):
35 self._entry = widgets['entry']
36 self._percents = widgets['percents']
37 self._mirror = widgets['mirror']
38 self._adjustment = widgets['adjustment']
39 self._on_changed = on_changed
40
41 self._anchor = None
42
43 self._on_percents_id = self._percents.connect('toggled', self._on_percents_toggled)
44 self._on_mirror_id = self._mirror.connect('toggled', self._on_mirror_toggled)
45 self._on_value_id = self._adjustment.connect('value-changed', self._on_value_changed)
46
47 @property
48 def value(self):
49 return '%s%d%s,%s' % ('-' if self._mirror.props.active else '',
50 int(self._entry.props.value),
51 '%' if self._percents.props.active else '',
52 self._anchor)
53
54 @value.setter
55 def value(self, s):
56 if isinstance(s, tuple):
57 p, percents, negative, anchor = s
58 else:
59 value, __, anchor = s.partition(',')
60
61 percents = value and value[-1] == '%'
62 if percents:
63 value = value[:-1]
64
65 try:
66 p = int(value)
67 except ValueError:
68 p = 0
69
70 negative = (p < 0) or (p == 0 and value and value[0] == '-')
71
72 if not anchor or anchor not in ('start', 'center', 'end'):
73 if negative:
74 anchor = 'end'
75 else:
76 anchor = 'start'
77
78 self._anchor = anchor
79 with self._percents.handler_block(self._on_percents_id):
80 self._percents.props.active = percents
81 self._adjustment.props.upper = 100 if self._percents.props.active else 10000
82 with self._mirror.handler_block(self._on_mirror_id):
83 self._mirror.props.active = negative
84 with self._adjustment.handler_block(self._on_value_id):
85 self._adjustment.props.value = -p if negative else p
86
87 @property
88 def anchor(self):
89 return self._anchor
90
91 @anchor.setter
92 def anchor(self, value):
93 self._anchor = value
94
95 @property
96 def negative(self):
97 return self._mirror.props.active
98
99 @negative.setter
100 def negative(self, value):
101 self._mirror.props.active = value
102
103 def get_value_for_screen(self, screen: int):
104 p = int(self._adjustment.props.value)
105
106 if self._percents.props.active:
107 p = screen * p / 100
108 if self._mirror.props.active:
109 p = screen - p
110
111 return int(p)
112
113 def _on_percents_toggled(self, toggle):
114 self._adjustment.props.upper = 100 if toggle.props.active else 10000
115 self._on_changed(self)
116
117 def _on_mirror_toggled(self, toggle):
118 self._on_changed(self)
119
120 def _on_value_changed(self, widget):
121 self._on_changed(self)
122
123 AssumedWindowSize = 430, 240
124
125 def __init__(self, widgets):
126 super().__init__(widgets)
127
128 self._screen_size = None
129 self._last_overlay_size = None
130 self._last_window_allocation = None
131
132 self._screen_frame = widgets['screen_frame']
133 self._screen_overlay = widgets['screen_overlay']
134 window_box = widgets['window_box']
135 grid = widgets['window_grid']
136
137 self._motion = False
138
139 window_box.connect('motion-notify-event', self._on_window_motion)
140 window_box.connect('button-press-event', self._on_window_button_press)
141 window_box.connect('button-release-event', self._on_window_button_release)
142
143 # Creating points grid
144 anchors_align = (Gtk.Align.START, Gtk.Align.CENTER, Gtk.Align.END)
145 anchors = [(x, y, Gtk.RadioButton())
146 for x, y in product(enumerate(('start', 'center', 'end')), repeat=2)]
147
148 self._anchors = {}
149 self._anchors_handlers = {}
150 for (left, x_anchor), (top, y_anchor), w in anchors:
151 w.props.halign = anchors_align[left]
152 w.props.valign = anchors_align[top]
153 if w != anchors[0][-1]:
154 w.props.group = anchors[0][-1]
155 grid.attach(w, left, top, 1, 1)
156 self._anchors[x_anchor, y_anchor] = w
157 self._anchors_handlers[w] = w.connect('toggled', self._on_anchor_toggled,
158 x_anchor, y_anchor)
159
160 grid.show_all()
161
162 self._x = PositionEntry.Dimension(WidgetsWrapper(widgets, 'x'), self._on_dimension_changed)
163 self._y = PositionEntry.Dimension(WidgetsWrapper(widgets, 'y'), self._on_dimension_changed)
164
165 self._on_gdk_screen_changed()
166
167 self._screen_overlay.connect('get-child-position',
168 self._on_screen_overlay_get_child_position)
169 self._screen_overlay.connect('screen-changed', self._on_gdk_screen_changed)
170
171 def _get_value(self):
172 x = self._x.value
173 y = self._y.value
174 return x + ' ' + y if x != y else x
175
176 def _set_value(self, value):
177 self._last_window_allocation = None
178 if value:
179 x, __, y = value.partition(' ')
180 self._x.value = x
181 self._y.value = y or x
182 anchor = self._anchors[self._x.anchor, self._y.anchor]
183 with anchor.handler_block(self._anchors_handlers[anchor]):
184 anchor.props.active = True
185 self._screen_overlay.queue_resize()
186 self._emit_changed()
187
188 def _get_corrected_position(self, p, screen, window, anchor):
189 if anchor == 'center':
190 p -= window / 2
191 elif anchor == 'end':
192 p -= window
193
194 if p + window > screen:
195 p = screen - window
196 if p < 0:
197 p = 0
198
199 return int(p)
200
201 def _on_dimension_changed(self, dimension):
202 self._last_window_allocation = None
203 self._screen_overlay.queue_resize()
204 self._emit_changed()
205
206 def _on_screen_overlay_get_child_position(self, overlay, child, allocation):
207 screen = overlay.get_allocation()
208
209 if self._last_window_allocation and \
210 self._last_overlay_size == (screen.width, screen.height):
211 (allocation.x, allocation.y,
212 allocation.width, allocation.height) = self._last_window_allocation
213 return True
214 self._last_overlay_size = screen.width, screen.height
215
216 scale = screen.width / self._screen_size[0]
217
218 width = int(self.AssumedWindowSize[0] * scale)
219 height = int(self.AssumedWindowSize[1] * scale)
220
221 # Set desired size
222 child.set_size_request(width, height)
223 # And check what actually we have now
224 width, height = child.size_request().width, child.size_request().height
225
226 x = int(self._x.get_value_for_screen(self._screen_size[0]) * scale)
227 y = int(self._y.get_value_for_screen(self._screen_size[1]) * scale)
228
229 x = self._get_corrected_position(x, screen.width, width, self._x.anchor)
230 y = self._get_corrected_position(y, screen.height, height, self._y.anchor)
231
232 self._last_window_allocation = x, y, width, height
233 allocation.x, allocation.y, allocation.width, allocation.height = x, y, width, height
234
235 return True
236
237 def _on_anchor_toggled(self, toggle, x, y):
238 if not toggle.props.active:
239 return
240 self._x.anchor = x
241 self._y.anchor = y
242 self._last_window_allocation = None
243 self._screen_overlay.queue_resize()
244 self._emit_changed()
245
246 def _on_gdk_screen_changed(self, widget=None, prev_screen=None):
247 screen = self._screen_overlay.get_toplevel().get_screen()
248 geometry = screen.get_monitor_geometry(screen.get_primary_monitor())
249 self._screen_size = geometry.width, geometry.height
250 self._screen_frame.props.ratio = geometry.width / geometry.height
251
252 def _on_window_motion(self, widget, event):
253 if not event.state & Gdk.ModifierType.BUTTON1_MASK:
254 return False
255
256 screen = self._screen_overlay.get_allocation()
257 x, y = widget.translate_coordinates(self._screen_overlay, event.x, event.y)
258
259 for d, p in ((self._x, int(100 * x / screen.width)),
260 (self._y, int(100 * y / screen.height))):
261 if p < 0:
262 p = 0
263 elif p > 100:
264 p = 100
265 if d.negative:
266 d.value = p - 100, True, True, d.anchor
267 else:
268 d.value = p, True, False, d.anchor
269
270 self._motion = True
271 self._last_window_allocation = None
272 self._screen_overlay.queue_resize()
273 return True
274
275 def _on_window_button_press(self, widget, event):
276 if event.button == 1:
277 self._motion = False
278
279 def _on_window_button_release(self, widget, event):
280 if self._motion and event.button == 1:
281 self._motion = False
282 self._emit_changed()
1313 #
1414 # You should have received a copy of the GNU General Public License along
1515 # with this program. If not, see <http://www.gnu.org/licenses/>.
16
1617
1718 def main():
1819 from gi.repository import Gtk
1414 # You should have received a copy of the GNU General Public License along
1515 # with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17 from collections import namedtuple
18 from itertools import chain
17
18 import configparser
19 import glob
1920 import locale
2021 import os
21
22 from gi.repository import Gtk
22 import pwd
23 import stat
24
25 from collections import (
26 namedtuple,
27 OrderedDict,
28 defaultdict)
29 from itertools import (
30 chain,
31 accumulate)
32 from locale import gettext as _
33
34 from gi.repository import (
35 GdkPixbuf,
36 GLib,
37 GObject,
38 Gtk,
39 Pango)
2340
2441
2542 __license__ = 'GPL-3'
2946
3047
3148 try:
32 from . installation_config import *
49 from . installation_config import (
50 __version__,
51 __data_directory__,
52 __config_path__)
3353 except ImportError:
3454 pass
3555
3656
37 __all__ = ['C_', 'NC_',
38 'get_data_path', 'get_config_path', 'show_message',
39 'bool2string', 'string2bool',
40 'ModelRowEnum', 'WidgetsWrapper']
57 __all__ = [
58 'bool2string',
59 'C_',
60 'clamp',
61 'check_path_accessibility',
62 'DefaultValueDict',
63 'file_is_readable_by_greeter',
64 'get_config_path',
65 'get_data_path',
66 'get_greeter_version'
67 'get_markup_error',
68 'get_version',
69 'ModelRowEnum',
70 'NC_',
71 'pixbuf_from_file_scaled_down',
72 'set_image_from_path',
73 'show_message',
74 'SimpleEnum',
75 'string2bool',
76 'TreeStoreDataWrapper',
77 'WidgetsEnum',
78 'WidgetsWrapper']
4179
4280
4381 def C_(context, message):
44 CONTEXT_SEPARATOR = '\x04'
45 message_with_context = '{}{}{}'.format(context, CONTEXT_SEPARATOR, message)
82 separator = '\x04'
83 message_with_context = '{}{}{}'.format(context, separator, message)
4684 result = locale.gettext(message_with_context)
47 if CONTEXT_SEPARATOR in result:
85 if separator in result:
4886 result = message
4987 return result
5088
62100 return os.path.abspath(__config_path__)
63101
64102
103 def get_version():
104 return __version__
105
106
107 def get_greeter_version():
108 try:
109 return get_greeter_version._version
110 except AttributeError:
111 try:
112 get_greeter_version._version = int(os.getenv('GTK_GREETER_VERSION', '0x010900'), 16)
113 except ValueError:
114 get_greeter_version._version = 0x010900
115
116 return get_greeter_version._version
117
118
119 def bool2string(value):
120 return 'true' if value else 'false'
121
122
123 def string2bool(value):
124 return value and value.lower() in ('true', 'yes', '1')
125
126
65127 def show_message(**kwargs):
66 dialog = Gtk.MessageDialog(parent=Gtk.Window.list_toplevels()[0], buttons=Gtk.ButtonsType.CLOSE, **kwargs)
128 dialog = Gtk.MessageDialog(parent=Gtk.Window.list_toplevels()[0],
129 buttons=Gtk.ButtonsType.CLOSE, **kwargs)
67130 dialog.run()
68131 dialog.destroy()
69132
70 def get_version():
71 return __version__
72
73
74 def bool2string(value):
75 return 'true' if value else 'false'
76
77
78 def string2bool(value):
79 return value and value.lower() in ('true', 'yes', '1')
80
81
82 class ModelRowEnum:
83
84 def __init__(self, *names):
85 self.__keys = tuple(names)
86 self.__values = {name: i for i, name in enumerate(names)}
87 self.__dict__.update(self.__values)
88 self.__RowTuple = namedtuple('ModelRowEnumTuple', names)
89
90 def __call__(self, *args, **kwargs):
133
134 def pixbuf_from_file_scaled_down(path, width, height):
135 pixbuf = GdkPixbuf.Pixbuf.new_from_file(path)
136 scale = max(pixbuf.props.width / width, pixbuf.props.height / height)
137
138 if scale > 1:
139 return GdkPixbuf.Pixbuf.scale_simple(pixbuf,
140 pixbuf.props.width / scale,
141 pixbuf.props.height / scale,
142 GdkPixbuf.InterpType.BILINEAR)
143 return pixbuf
144
145
146 def set_image_from_path(image, path):
147 if not path or not os.path.isfile(path):
148 image.props.icon_name = 'unknown'
149 else:
150 try:
151 width, height = image.get_size_request()
152 if -1 in (width, height):
153 width, height = 64, 64
154 pixbuf = pixbuf_from_file_scaled_down(path, width, height)
155 image.set_from_pixbuf(pixbuf)
156 return True
157 except GLib.Error:
158 image.props.icon_name = 'file-broken'
159 return False
160
161
162 def check_path_accessibility(path, file=True, executable=False):
163 """Return None if file is readable by greeter and error message otherwise"""
164
165 if not os.path.exists(path):
166 return _('File not found: {path}').format(path=path)
167
168 try:
169 uid, gids = check_path_accessibility.id_cached_data
170 except AttributeError:
171 files = glob.glob('/etc/lightdm/lightdm.d/*.conf')
172 files += ['/etc/lightdm/lightdm.conf']
173 config = configparser.RawConfigParser(strict=False)
174 config.read(files)
175 username = config.get('LightDM', 'greeter-user', fallback='lightdm')
176
177 pw = pwd.getpwnam(username)
178 uid = pw.pw_uid
179 gids = set(os.getgrouplist(username, pw.pw_gid))
180 check_path_accessibility.id_cached_data = uid, gids
181
182 parts = os.path.normpath(path).split(os.path.sep)
183 if not parts[0]:
184 parts[0] = os.path.sep
185
186 def check(p):
187 try:
188 st = os.stat(p)
189 except OSError as e:
190 return _('Failed to check permissions: {error}'.format(error=e.strerror))
191
192 if stat.S_ISDIR(st.st_mode) and not stat.S_IREAD:
193 return _('Directory is not readable: {path}'.format(path=p))
194 if st.st_uid == uid:
195 return not (st.st_mode & stat.S_IRUSR) and \
196 _('LightDM do not have permissions to read path: {path}'.format(path=p))
197 if st.st_gid in gids:
198 return not (st.st_mode & stat.S_IRGRP) and \
199 _('LightDM do not have permissions to read path: {path}'.format(path=p))
200 return not (st.st_mode & stat.S_IROTH) and \
201 _('LightDM do not have permissions to read path: {path}'.format(path=p))
202
203 errors = (check(p) for p in accumulate(parts, os.path.join))
204 error = next((error for error in errors if error), None)
205
206 if not error and file and not os.path.isfile(path):
207 return _('Path is not a regular file: {path}'.format(path=path))
208
209 if not error and executable:
210 st = os.stat(path)
211 if st.st_uid == uid:
212 if not st.st_mode & stat.S_IXUSR:
213 return _('LightDM do not have permissions to execute file: {path}'
214 .format(path=path))
215 elif st.st_gid in gids:
216 if not st.st_mode & stat.S_IXGRP:
217 return _('LightDM do not have permissions to execute file: {path}'
218 .format(path=path))
219 elif not st.st_mode & stat.S_IXOTH:
220 return _('LightDM do not have permissions to execute file: {path}'.format(path=path))
221
222 return error
223
224
225 def get_markup_error(markup):
226 try:
227 Pango.parse_markup(markup, -1, '\0')
228 except GLib.Error as e:
229 return e.message
230 return None
231
232
233 def clamp(v, a, b):
234 if v < a:
235 return a
236 if v > b:
237 return b
238 return v
239
240
241 class DefaultValueDict(defaultdict):
242
243 def __init__(self, *items, default=None, factory=None, source=None):
244 super().__init__(None, source or items)
245 self._value = default
246 self._factory = factory
247
248 def __missing__(self, key):
249 return self._factory(key) if self._factory else self._value
250
251
252 class SimpleEnumMeta(type):
253
254 @classmethod
255 def __prepare__(mcs, *args, **kwargs):
256 return OrderedDict()
257
258 def __new__(self, cls, bases, classdict):
259 obj = super().__new__(self, cls, bases, classdict)
260 obj._dict = OrderedDict((k, v)
261 for k, v in classdict.items() if obj._accept_member_(k, v))
262 obj._tuple_type = namedtuple(obj.__class__.__name__ + 'Tuple', obj._dict.keys())
263 keys = list(obj._dict.keys())
264 for i in range(len(keys)):
265 if obj._dict[keys[i]] is ():
266 v = 0 if i == 0 else obj._dict[keys[i - 1]] + 1
267 setattr(obj, keys[i], v)
268 obj._dict[keys[i]] = v
269 return obj
270
271 def __contains__(self, value):
272 return value in self._dict.values()
273
274 def __iter__(self):
275 return iter(self._dict.values())
276
277 def _make(self, *args, **kwargs):
278 return self._tuple_type._make(self._imake(*args, **kwargs))
279
280 def _imake(self, *args, **kwargs):
91281 if args:
92 return self.__RowTuple._make(chain.from_iterable(args))
282 return args
283 elif kwargs:
284 return (kwargs.get(k, v) for k, v in self._dict.items())
93285 else:
94 return self.__RowTuple._make(kwargs.get(name, i) for i, name in enumerate(self.__keys))
286 return self._dict.values()
287
288
289 class SimpleEnum(metaclass=SimpleEnumMeta):
290 _dict = None
291
292 def __init__(self, *args, **kwargs):
293 if kwargs:
294 self.__dict__.update(kwargs)
295 else:
296 self.__dict__.update((k, args[i]) for i, k in enumerate(self._dict))
297
298 def __iter__(self):
299 return (self.__dict__[k] for k in self._dict)
300
301 def __repr__(self):
302 return repr(tuple((k, self.__dict__[k]) for k in self._dict))
303
304 @classmethod
305 def _accept_member_(cls, name, value):
306 return not name.startswith('_') and not name.endswith('_')
307
308
309 class WidgetsEnum(SimpleEnum):
310
311 def __init__(self, wrapper=None, builder=None):
312 getter = wrapper.__getitem__ if wrapper else builder.get_object
313 for k, v in self._dict.items():
314 if isinstance(v, type) and issubclass(v, WidgetsEnum):
315 self.__dict__[k] = v(WidgetsWrapper(wrapper or builder, k))
316 else:
317 self.__dict__[k] = getter(v or k)
95318
96319
97320 class WidgetsWrapper:
321 _builder = None
322 _prefixes = None
98323
99324 def __init__(self, source, *prefixes):
100325 if isinstance(source, Gtk.Builder):
110335 if not isinstance(args, tuple):
111336 args = (args,)
112337 return self._builder.get_object('_'.join(chain(self._prefixes, args)))
338
339
340 class TreeStoreDataWrapper(GObject.Object):
341
342 def __init__(self, data):
343 super().__init__()
344 self.data = data
33 # Glade Files
44 [type: gettext/glade]data/GtkGreeterSettingsWindow.ui
55 [type: gettext/glade]data/IconChooserDialog.ui
6 [type: gettext/glade]data/IndicatorChooserDialog.ui
6 [type: gettext/glade]data/ImageChooserDialog.ui
7 [type: gettext/glade]data/IndicatorPropertiesDialog.ui
78 [type: gettext/glade]data/MultiheadSetupDialog.ui
89
910 # Python Files
1112 lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py
1213 lightdm_gtk_greeter_settings/helpers.py
1314 lightdm_gtk_greeter_settings/IconChooserDialog.py
14 lightdm_gtk_greeter_settings/IndicatorChooserDialog.py
15 lightdm_gtk_greeter_settings/IndicatorPropertiesDialog.py
16 lightdm_gtk_greeter_settings/IndicatorsEntry.py
17 lightdm_gtk_greeter_settings/MonitorsGroup.py
1518 lightdm_gtk_greeter_settings/MultiheadSetupDialog.py
1619 lightdm_gtk_greeter_settings/OptionEntry.py
20 lightdm_gtk_greeter_settings/OptionGroup.py
21 lightdm_gtk_greeter_settings/PositionEntry.py
22
1723
1824 com.ubuntu.pkexec.lightdm-gtk-greeter-settings.policy.in
77 msgstr ""
88 "Project-Id-Version: PACKAGE VERSION\n"
99 "Report-Msgid-Bugs-To: \n"
10 "POT-Creation-Date: 2014-03-15 23:23-0400\n"
10 "POT-Creation-Date: 2015-01-25 18:54+0300\n"
1111 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
1212 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
1313 "Language-Team: LANGUAGE <LL@li.org>\n"
2121 msgstr ""
2222
2323 #: ../data/GtkGreeterSettingsWindow.ui.h:1
24 msgctxt "option|hintstyle"
24 msgctxt "option|greeter|default-user-image"
25 msgid "Icon"
26 msgstr ""
27
28 #: ../data/GtkGreeterSettingsWindow.ui.h:2
29 msgctxt "option|greeter|default-user-image"
30 msgid "Path"
31 msgstr ""
32
33 #: ../data/GtkGreeterSettingsWindow.ui.h:3
34 msgid "LightDM GTK+ Greeter: settings"
35 msgstr ""
36
37 #: ../data/GtkGreeterSettingsWindow.ui.h:4
38 msgctxt "option|greeter|xft-rgba"
2539 msgid "None"
2640 msgstr ""
2741
28 #: ../data/GtkGreeterSettingsWindow.ui.h:2
29 msgctxt "option|hintstyle"
42 #: ../data/GtkGreeterSettingsWindow.ui.h:5
43 msgctxt "option|greeter|xft-rgba"
44 msgid "RGB"
45 msgstr ""
46
47 #: ../data/GtkGreeterSettingsWindow.ui.h:6
48 msgctxt "option|greeter|xft-rgba"
49 msgid "BGR"
50 msgstr ""
51
52 #: ../data/GtkGreeterSettingsWindow.ui.h:7
53 msgctxt "option|greeter|xft-rgba"
54 msgid "Vertical RGB"
55 msgstr ""
56
57 #: ../data/GtkGreeterSettingsWindow.ui.h:8
58 msgctxt "option|greeter|xft-rgba"
59 msgid "Vertical BGR"
60 msgstr ""
61
62 #: ../data/GtkGreeterSettingsWindow.ui.h:9
63 msgctxt "option|greeter|xft-hintstyle"
64 msgid "None"
65 msgstr ""
66
67 #: ../data/GtkGreeterSettingsWindow.ui.h:10
68 msgctxt "option|greeter|xft-hintstyle"
3069 msgid "Slight"
3170 msgstr ""
3271
33 #: ../data/GtkGreeterSettingsWindow.ui.h:3
34 msgctxt "option|hintstyle"
72 #: ../data/GtkGreeterSettingsWindow.ui.h:11
73 msgctxt "option|greeter|xft-hintstyle"
3574 msgid "Medium"
3675 msgstr ""
3776
38 #: ../data/GtkGreeterSettingsWindow.ui.h:4
39 msgctxt "option|hintstyle"
77 #: ../data/GtkGreeterSettingsWindow.ui.h:12
78 msgctxt "option|greeter|xft-hintstyle"
4079 msgid "Full"
4180 msgstr ""
4281
43 #: ../data/GtkGreeterSettingsWindow.ui.h:5
44 msgctxt "option|rgba"
45 msgid "None"
46 msgstr ""
47
48 #: ../data/GtkGreeterSettingsWindow.ui.h:6
49 msgctxt "option|rgba"
50 msgid "RGB"
51 msgstr ""
52
53 #: ../data/GtkGreeterSettingsWindow.ui.h:7
54 msgctxt "option|rgba"
55 msgid "BGR"
56 msgstr ""
57
58 #: ../data/GtkGreeterSettingsWindow.ui.h:8
59 msgctxt "option|rgba"
60 msgid "Vertical RGB"
61 msgstr ""
62
63 #: ../data/GtkGreeterSettingsWindow.ui.h:9
64 msgctxt "option|rgba"
65 msgid "Vertical BGR"
66 msgstr ""
67
68 #: ../data/GtkGreeterSettingsWindow.ui.h:10
69 msgid "LightDM GTK+ Greeter: settings"
70 msgstr ""
71
72 #: ../data/GtkGreeterSettingsWindow.ui.h:11
73 msgctxt "option|gtk-theme"
82 #: ../data/GtkGreeterSettingsWindow.ui.h:13
83 msgctxt "option|greeter|xft-antialias"
84 msgid "Antialias"
85 msgstr ""
86
87 #: ../data/GtkGreeterSettingsWindow.ui.h:14
88 msgid "Enable this option to override system defaults"
89 msgstr ""
90
91 #: ../data/GtkGreeterSettingsWindow.ui.h:15
92 msgctxt "option|greeter|xft-dpi"
93 msgid "DPI"
94 msgstr ""
95
96 #: ../data/GtkGreeterSettingsWindow.ui.h:16
97 msgctxt "option|greeter|xft-rgba"
98 msgid "Subpixel rendering"
99 msgstr ""
100
101 #: ../data/GtkGreeterSettingsWindow.ui.h:17
102 msgctxt "option|greeter|xft-hintstyle"
103 msgid "Hinting"
104 msgstr ""
105
106 #: ../data/GtkGreeterSettingsWindow.ui.h:18
107 msgid "Additional font options"
108 msgstr ""
109
110 #: ../data/GtkGreeterSettingsWindow.ui.h:19
111 msgctxt "option|greeter|background"
112 msgid "Background"
113 msgstr ""
114
115 #: ../data/GtkGreeterSettingsWindow.ui.h:20
116 msgctxt "option|multihead"
117 msgid ""
118 " <i>(or use <a href=\"\">multihead setup</a> for individual monitors)</i>"
119 msgstr ""
120
121 #: ../data/GtkGreeterSettingsWindow.ui.h:21
122 msgctxt "option|greeter|background"
123 msgid "Color"
124 msgstr ""
125
126 #: ../data/GtkGreeterSettingsWindow.ui.h:22
127 msgctxt "option|greeter|background"
128 msgid "Image"
129 msgstr ""
130
131 #: ../data/GtkGreeterSettingsWindow.ui.h:23
132 msgctxt "option|greeter|theme-name"
74133 msgid "Theme"
75134 msgstr ""
76135
77 #: ../data/GtkGreeterSettingsWindow.ui.h:12
78 msgctxt "option|icons-theme"
136 #: ../data/GtkGreeterSettingsWindow.ui.h:24
137 msgctxt "option|greeter|icon-theme-name"
79138 msgid "Icons"
80139 msgstr ""
81140
82 #: ../data/GtkGreeterSettingsWindow.ui.h:13
83 msgctxt "option|font"
141 #: ../data/GtkGreeterSettingsWindow.ui.h:25
142 msgctxt "option|greeter|font-name"
84143 msgid "Font"
85144 msgstr ""
86145
87 #: ../data/GtkGreeterSettingsWindow.ui.h:14
88 msgctxt "option|rgba"
89 msgid "Subpixel rendering"
90 msgstr ""
91
92 #: ../data/GtkGreeterSettingsWindow.ui.h:15
93 msgid "Enable this option to override system defaults"
94 msgstr ""
95
96 #: ../data/GtkGreeterSettingsWindow.ui.h:16
97 msgctxt "option|dpi"
98 msgid "DPI"
99 msgstr ""
100
101 #: ../data/GtkGreeterSettingsWindow.ui.h:17
102 msgctxt "option|antialias"
103 msgid "Antialias"
104 msgstr ""
105
106 #: ../data/GtkGreeterSettingsWindow.ui.h:18
107 msgctxt "option|hintstyle"
108 msgid "Hinting"
109 msgstr ""
110
111 #: ../data/GtkGreeterSettingsWindow.ui.h:19
112 msgid "Additional font options"
113 msgstr ""
114
115 #: ../data/GtkGreeterSettingsWindow.ui.h:20
116 msgctxt "option|background"
117 msgid "Background"
118 msgstr ""
119
120 #: ../data/GtkGreeterSettingsWindow.ui.h:21
121 msgctxt "option|background"
122 msgid "Image"
123 msgstr ""
124
125 #: ../data/GtkGreeterSettingsWindow.ui.h:22
126 msgctxt "option|background"
127 msgid "Color"
128 msgstr ""
129
130 #: ../data/GtkGreeterSettingsWindow.ui.h:23
131 msgctxt "option|user-image"
146 #: ../data/GtkGreeterSettingsWindow.ui.h:26
147 msgctxt "option|greeter|hide-user-image"
148 msgid "User image"
149 msgstr ""
150
151 #: ../data/GtkGreeterSettingsWindow.ui.h:27
152 msgctxt "option|greeter|default-user-image"
132153 msgid "Default user image"
133154 msgstr ""
134155
135 #: ../data/GtkGreeterSettingsWindow.ui.h:24
156 #: ../data/GtkGreeterSettingsWindow.ui.h:28
157 msgctxt "option|greeter|user-background"
158 msgid "Use user wallpaper if available"
159 msgstr ""
160
161 #: ../data/GtkGreeterSettingsWindow.ui.h:29
162 msgctxt "tabs"
136163 msgid "Appearance"
137164 msgstr ""
138165
139 #: ../data/GtkGreeterSettingsWindow.ui.h:25
140 msgctxt "option|clock"
141 msgid "Clock"
142 msgstr ""
143
144 #: ../data/GtkGreeterSettingsWindow.ui.h:26
145 msgctxt "option|indicators"
146 msgid "Redefine indicators"
147 msgstr ""
148
149 #: ../data/GtkGreeterSettingsWindow.ui.h:28
166 #: ../data/GtkGreeterSettingsWindow.ui.h:31
150167 #, no-c-format
151 msgctxt "option|clock-format"
168 msgctxt "option|greeter|clock-format"
152169 msgid ""
153170 "%H %I - hours, %M - minutes, %S - seconds\n"
154171 "%d - day, %m - month, %y %Y - year\n"
155172 "%a %A - day of the week, %b %B - month name"
156173 msgstr ""
157174
158 #: ../data/GtkGreeterSettingsWindow.ui.h:31
159 msgctxt "option|indicators"
175 #: ../data/GtkGreeterSettingsWindow.ui.h:34
176 msgctxt "option|greeter|indicators"
160177 msgid "Add indicator to list"
161178 msgstr ""
162179
163 #: ../data/GtkGreeterSettingsWindow.ui.h:32
164 msgctxt "option|indicators"
180 #: ../data/GtkGreeterSettingsWindow.ui.h:35
181 msgctxt "option|greeter|indicators"
165182 msgid "Add"
166183 msgstr ""
167184
168 #: ../data/GtkGreeterSettingsWindow.ui.h:33
169 msgctxt "option|indicators"
185 #: ../data/GtkGreeterSettingsWindow.ui.h:36
186 msgctxt "option|greeter|indicators"
170187 msgid "Remove indicator from list"
171188 msgstr ""
172189
173 #: ../data/GtkGreeterSettingsWindow.ui.h:34
174 msgctxt "option|indicators"
190 #: ../data/GtkGreeterSettingsWindow.ui.h:37
191 msgctxt "option|greeter|indicators"
175192 msgid "Remove"
176193 msgstr ""
177194
178 #: ../data/GtkGreeterSettingsWindow.ui.h:35
179 msgctxt "option|indicators"
195 #: ../data/GtkGreeterSettingsWindow.ui.h:38
196 msgctxt "option|greeter|indicators"
180197 msgid "Move up"
181198 msgstr ""
182199
183 #: ../data/GtkGreeterSettingsWindow.ui.h:36
184 msgctxt "option|indicators"
200 #: ../data/GtkGreeterSettingsWindow.ui.h:39
201 msgctxt "option|greeter|indicators"
185202 msgid "Up"
186203 msgstr ""
187204
188 #: ../data/GtkGreeterSettingsWindow.ui.h:37
189 msgctxt "option|indicators"
205 #: ../data/GtkGreeterSettingsWindow.ui.h:40
206 msgctxt "option|greeter|indicators"
190207 msgid "Move down"
191208 msgstr ""
192209
193 #: ../data/GtkGreeterSettingsWindow.ui.h:38
194 msgctxt "option|indicators"
210 #: ../data/GtkGreeterSettingsWindow.ui.h:41
211 msgctxt "option|greeter|indicators"
195212 msgid "Down"
196213 msgstr ""
197214
198 #: ../data/GtkGreeterSettingsWindow.ui.h:39
199 msgctxt "option|clock-format"
200 msgid "Format:"
201 msgstr ""
202
203 #: ../data/GtkGreeterSettingsWindow.ui.h:40
215 #: ../data/GtkGreeterSettingsWindow.ui.h:42
216 msgctxt "option|greeter|indicators"
217 msgid "Templates"
218 msgstr ""
219
220 #: ../data/GtkGreeterSettingsWindow.ui.h:43
221 msgctxt "option|greeter|clock-format"
222 msgid "Clock format:"
223 msgstr ""
224
225 #: ../data/GtkGreeterSettingsWindow.ui.h:44
226 msgctxt "option|greeter|indicators"
227 msgid "Redefine indicators"
228 msgstr ""
229
230 #: ../data/GtkGreeterSettingsWindow.ui.h:45
231 msgctxt "tabs"
204232 msgid "Panel"
205233 msgstr ""
206234
207 #: ../data/GtkGreeterSettingsWindow.ui.h:41
208 msgctxt "option|position"
209 msgid "Horizontal "
210 msgstr ""
211
212 #: ../data/GtkGreeterSettingsWindow.ui.h:43
235 #: ../data/GtkGreeterSettingsWindow.ui.h:46
236 msgctxt "option|greeter|position"
237 msgid "Horizontal"
238 msgstr ""
239
240 #: ../data/GtkGreeterSettingsWindow.ui.h:47
241 msgctxt "option|greeter|position"
242 msgid "Vertical"
243 msgstr ""
244
245 #: ../data/GtkGreeterSettingsWindow.ui.h:48
246 msgid "0"
247 msgstr ""
248
249 #: ../data/GtkGreeterSettingsWindow.ui.h:50
213250 #, no-c-format
214 msgctxt "option|position"
251 msgctxt "option|greeter|position"
215252 msgid "in %"
216253 msgstr ""
217254
218 #: ../data/GtkGreeterSettingsWindow.ui.h:44
219 msgctxt "option|position"
220 msgid "Vertical"
221 msgstr ""
222
223 #: ../data/GtkGreeterSettingsWindow.ui.h:45
224 msgctxt "option|position"
225 msgid "Select base point and its position"
226 msgstr ""
227
228 #: ../data/GtkGreeterSettingsWindow.ui.h:46
229 msgctxt "option|position"
255 #: ../data/GtkGreeterSettingsWindow.ui.h:51
256 msgctxt "option|greeter|position"
230257 msgid "from right"
231258 msgstr ""
232259
233 #: ../data/GtkGreeterSettingsWindow.ui.h:47
234 msgctxt "option|position"
260 #: ../data/GtkGreeterSettingsWindow.ui.h:52
261 msgctxt "option|greeter|position"
235262 msgid "from bottom"
236263 msgstr ""
237264
238 #: ../data/GtkGreeterSettingsWindow.ui.h:48
265 #: ../data/GtkGreeterSettingsWindow.ui.h:53
266 msgctxt "option|greeter|position"
267 msgid "Select base point and its position."
268 msgstr ""
269
270 #: ../data/GtkGreeterSettingsWindow.ui.h:54
271 msgctxt "tabs"
239272 msgid "Window position"
240273 msgstr ""
241274
242 #: ../data/GtkGreeterSettingsWindow.ui.h:49
243 msgctxt "option|timeout"
275 #: ../data/GtkGreeterSettingsWindow.ui.h:55
276 msgctxt "option|greeter|screensaver-timeout"
277 msgid "Never"
278 msgstr ""
279
280 #: ../data/GtkGreeterSettingsWindow.ui.h:56
281 msgid "Accessibility"
282 msgstr ""
283
284 #: ../data/GtkGreeterSettingsWindow.ui.h:57
285 msgctxt "option|greeter|reader"
286 msgid "Select path to reader..."
287 msgstr ""
288
289 #: ../data/GtkGreeterSettingsWindow.ui.h:58
290 msgctxt "option|greeter|reader"
291 msgid "Command to launch screen reader"
292 msgstr ""
293
294 #: ../data/GtkGreeterSettingsWindow.ui.h:59
295 msgctxt "option|greeter|keyboard"
296 msgid "Select path to keyboard..."
297 msgstr ""
298
299 #: ../data/GtkGreeterSettingsWindow.ui.h:60
300 msgctxt "option|greeter|keyboard"
301 msgid "Command to launch on-screen keyboard"
302 msgstr ""
303
304 #: ../data/GtkGreeterSettingsWindow.ui.h:61
305 msgctxt "option|greeter|a11y-states"
306 msgid "Disabled at start"
307 msgstr ""
308
309 #: ../data/GtkGreeterSettingsWindow.ui.h:62
310 msgctxt "option|greeter|a11y-states"
311 msgid "Enabled at start"
312 msgstr ""
313
314 #: ../data/GtkGreeterSettingsWindow.ui.h:63
315 msgctxt "option|greeter|a11y-states"
316 msgid "Save state between launches"
317 msgstr ""
318
319 #: ../data/GtkGreeterSettingsWindow.ui.h:64
320 msgctxt "option|greeter|a11y-theme"
321 msgid "Contrast theme"
322 msgstr ""
323
324 #: ../data/GtkGreeterSettingsWindow.ui.h:65
325 msgctxt "option|greeter|a11y-font"
326 msgid "Large font"
327 msgstr ""
328
329 #: ../data/GtkGreeterSettingsWindow.ui.h:66
330 msgctxt "greeter|option|reader"
331 msgid "Reader"
332 msgstr ""
333
334 #: ../data/GtkGreeterSettingsWindow.ui.h:67
335 msgctxt "greeter|option|keyboard"
336 msgid "Keyboard"
337 msgstr ""
338
339 #: ../data/GtkGreeterSettingsWindow.ui.h:68
340 msgctxt "option|greeter|screensaver-timeout"
244341 msgid "Timeout until the screen blanks "
245342 msgstr ""
246343
247 #: ../data/GtkGreeterSettingsWindow.ui.h:50
248 msgctxt "option|keyboard"
249 msgid "Onscreen keyboard"
250 msgstr ""
251
252 #: ../data/GtkGreeterSettingsWindow.ui.h:51
253 msgctxt "option|timeout"
254 msgid "Never"
255 msgstr ""
256
257 #: ../data/GtkGreeterSettingsWindow.ui.h:52
344 #: ../data/GtkGreeterSettingsWindow.ui.h:69
345 msgctxt "greeter|option|allow-debugging"
346 msgid "Debugging mode"
347 msgstr ""
348
349 #: ../data/GtkGreeterSettingsWindow.ui.h:70
350 msgctxt "greeter|option|allow-debugging"
351 msgid ""
352 "Enable keys to launch GtkInspector\n"
353 "More informative log"
354 msgstr ""
355
356 #: ../data/GtkGreeterSettingsWindow.ui.h:72
357 msgctxt "tabs"
258358 msgid "Misc."
259359 msgstr ""
260360
261 #: ../data/GtkGreeterSettingsWindow.ui.h:53
361 #: ../data/GtkGreeterSettingsWindow.ui.h:73
262362 msgid "You don't have permissions to change greeter configuration"
263363 msgstr ""
264364
265 #: ../data/GtkGreeterSettingsWindow.ui.h:54
266 #: ../data/IndicatorChooserDialog.ui.h:2
365 #: ../data/GtkGreeterSettingsWindow.ui.h:74
366 #: ../data/IndicatorPropertiesDialog.ui.h:3
267367 msgctxt "button"
268368 msgid "_Close"
269369 msgstr ""
270370
271 #: ../data/GtkGreeterSettingsWindow.ui.h:55
371 #: ../data/GtkGreeterSettingsWindow.ui.h:75
272372 msgctxt "button"
273373 msgid "_Save"
274374 msgstr ""
275375
276 #: ../data/GtkGreeterSettingsWindow.ui.h:56
376 #: ../data/GtkGreeterSettingsWindow.ui.h:76
277377 msgctxt "button"
278378 msgid "_Reload"
279379 msgstr ""
280380
281 #: ../data/GtkGreeterSettingsWindow.ui.h:57
381 #: ../data/GtkGreeterSettingsWindow.ui.h:77
282382 msgid "Read configuration file"
283383 msgstr ""
284384
285 #: ../data/GtkGreeterSettingsWindow.ui.h:58
286 msgid "Select image"
287 msgstr ""
288
289385 #: ../data/IconChooserDialog.ui.h:1
290386 msgctxt "icon-dialog"
291387 msgid "Select icon"
292388 msgstr ""
293389
294 #: ../data/IconChooserDialog.ui.h:2
390 #: ../data/IconChooserDialog.ui.h:2 ../data/MultiheadSetupDialog.ui.h:5
295391 msgctxt "button"
296392 msgid "_Cancel"
297393 msgstr ""
298394
299 #: ../data/IconChooserDialog.ui.h:3 ../data/IndicatorChooserDialog.ui.h:3
395 #: ../data/IconChooserDialog.ui.h:3 ../data/IndicatorPropertiesDialog.ui.h:4
396 #: ../data/MultiheadSetupDialog.ui.h:6
300397 msgctxt "button"
301398 msgid "_OK"
302399 msgstr ""
303400
304 #: ../data/IconChooserDialog.ui.h:4 ../data/IndicatorChooserDialog.ui.h:4
401 #: ../data/IconChooserDialog.ui.h:4
305402 msgid "Add selected indicator to the list and close this window"
306403 msgstr ""
307404
325422 msgid "List _standard icons only"
326423 msgstr ""
327424
328 #: ../data/IndicatorChooserDialog.ui.h:1
329 msgctxt "indicators-dialog"
330 msgid "Select indicator"
331 msgstr ""
332
333 #: ../data/IndicatorChooserDialog.ui.h:5
425 #: ../data/ImageChooserDialog.ui.h:1
426 #: ../lightdm_gtk_greeter_settings/MultiheadSetupDialog.py:238
427 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:251
428 msgid "_Cancel"
429 msgstr ""
430
431 #: ../data/ImageChooserDialog.ui.h:2
432 #: ../lightdm_gtk_greeter_settings/MultiheadSetupDialog.py:237
433 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:250
434 msgid "_OK"
435 msgstr ""
436
437 #: ../data/IndicatorPropertiesDialog.ui.h:1
438 msgctxt "option-entry|indicators"
439 msgid "Select file..."
440 msgstr ""
441
442 #: ../data/IndicatorPropertiesDialog.ui.h:2
443 msgctxt "option-entry|indicators"
444 msgid "Indicator properties"
445 msgstr ""
446
447 #: ../data/IndicatorPropertiesDialog.ui.h:5
334448 msgctxt "button"
335449 msgid "_Add"
336450 msgstr ""
337451
338 #: ../data/IndicatorChooserDialog.ui.h:6
339 msgid "Add selected indicator to the list without closing this window"
340 msgstr ""
341
342 #: ../data/IndicatorChooserDialog.ui.h:7
343 msgctxt "indicators-dialog"
344 msgid "Short name"
345 msgstr ""
346
347 #: ../data/IndicatorChooserDialog.ui.h:8
348 msgctxt "indicators-dialog"
349 msgid "Indicators that greeter can find without using absolute pathes"
350 msgstr ""
351
352 #: ../data/IndicatorChooserDialog.ui.h:9
353 msgctxt "indicators-dialog"
354 msgid "Path"
355 msgstr ""
356
357 #: ../data/IndicatorChooserDialog.ui.h:10
358 msgctxt "indicators-dialog"
359 msgid "Absolute path to indicator library file (*.so)"
360 msgstr ""
361
362 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:102
452 #: ../data/IndicatorPropertiesDialog.ui.h:6
453 msgctxt "option-entry|indicators"
454 msgid "Indicator"
455 msgstr ""
456
457 #: ../data/IndicatorPropertiesDialog.ui.h:7
458 msgctxt "option-entry|indicators"
459 msgid "Display label"
460 msgstr ""
461
462 #: ../data/IndicatorPropertiesDialog.ui.h:8
463 msgctxt "option-entry|indicators"
464 msgid "Leave empty to use default value"
465 msgstr ""
466
467 #: ../data/IndicatorPropertiesDialog.ui.h:9
468 msgctxt "option-entry|indicators"
469 msgid "Display image"
470 msgstr ""
471
472 #: ../data/IndicatorPropertiesDialog.ui.h:10
473 msgctxt "option-entry|indicators"
474 msgid "Indicator library/service:"
475 msgstr ""
476
477 #: ../data/IndicatorPropertiesDialog.ui.h:11
478 msgid "page 1"
479 msgstr ""
480
481 #: ../data/IndicatorPropertiesDialog.ui.h:12
482 msgctxt "option-entry|indicators"
483 msgid "Hide disabled power actions"
484 msgstr ""
485
486 #: ../data/IndicatorPropertiesDialog.ui.h:13
487 msgid "page 2"
488 msgstr ""
489
490 #: ../data/IndicatorPropertiesDialog.ui.h:14
491 msgctxt "option-entry|indicators"
492 msgid "Text to display:"
493 msgstr ""
494
495 #: ../data/IndicatorPropertiesDialog.ui.h:15
496 msgid "page 3"
497 msgstr ""
498
499 #: ../data/IndicatorPropertiesDialog.ui.h:16
500 msgctxt "option-entry|indicators"
501 msgid "Spacer - fills the maximum available space"
502 msgstr ""
503
504 #: ../data/IndicatorPropertiesDialog.ui.h:17
505 msgctxt "option-entry|indicators"
506 msgid "Separator - draw a separator"
507 msgstr ""
508
509 #: ../data/MultiheadSetupDialog.ui.h:1
510 msgctxt "option|multihead"
511 msgid "Select a file"
512 msgstr ""
513
514 #: ../data/MultiheadSetupDialog.ui.h:2
515 msgctxt "option|multihead"
516 msgid "Select color"
517 msgstr ""
518
519 #: ../data/MultiheadSetupDialog.ui.h:3
520 #: ../lightdm_gtk_greeter_settings/MultiheadSetupDialog.py:93
521 msgctxt "option|multihead"
522 msgid "Use default value"
523 msgstr ""
524
525 #: ../data/MultiheadSetupDialog.ui.h:4
526 msgctxt "option|multihead"
527 msgid "Multihead setup"
528 msgstr ""
529
530 #: ../data/MultiheadSetupDialog.ui.h:7
531 msgctxt "option|multihead"
532 msgid "Monitor"
533 msgstr ""
534
535 #: ../data/MultiheadSetupDialog.ui.h:8
536 msgctxt "option|multihead"
537 msgid "User's"
538 msgstr ""
539
540 #: ../data/MultiheadSetupDialog.ui.h:9
541 msgctxt "option|multihead"
542 msgid "Laptop"
543 msgstr ""
544
545 #: ../data/MultiheadSetupDialog.ui.h:10
546 msgctxt "option|multihead"
547 msgid "Background"
548 msgstr ""
549
550 #: ../data/MultiheadSetupDialog.ui.h:11
551 msgctxt "option|multihead"
552 msgid "Add monior to the list"
553 msgstr ""
554
555 #: ../data/MultiheadSetupDialog.ui.h:12
556 msgctxt "option|multihead"
557 msgid "Add"
558 msgstr ""
559
560 #: ../data/MultiheadSetupDialog.ui.h:13
561 msgctxt "option|multihead"
562 msgid "Remove monitor from the list"
563 msgstr ""
564
565 #: ../data/MultiheadSetupDialog.ui.h:14
566 msgctxt "option|multihead"
567 msgid "Remove"
568 msgstr ""
569
570 #: ../data/MultiheadSetupDialog.ui.h:15
571 msgctxt "option|multihead"
572 msgid ""
573 "<i>Note: greeter do not set monitors geometry.\n"
574 "You need to configure it by yourself.</i>"
575 msgstr ""
576
577 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:129
363578 msgid "No permissions to save configuration"
364579 msgstr ""
365580
366 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:104
581 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:131
367582 #, python-brace-format
368583 msgid ""
369584 "It seems that you don't have permissions to write to file:\n"
372587 "Try to run this program using \"sudo\" or \"pkexec\""
373588 msgstr ""
374589
375 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:133
376 #, python-brace-format
377 msgctxt "option|timeout"
590 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:148
591 #, python-brace-format
592 msgid "Failed to read configuration file: {path}"
593 msgstr ""
594
595 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:260
596 msgid "<i>disabled</i>"
597 msgstr ""
598
599 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:262
600 msgid "<i>empty string</i>"
601 msgstr ""
602
603 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:264
604 msgid "<i>None</i>"
605 msgstr ""
606
607 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:285
608 #, python-brace-format
609 msgid "Reset to initial value: <b>{value}</b>"
610 msgstr ""
611
612 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:296
613 #, python-brace-format
614 msgid "Reset to default value: <b>{value}</b>"
615 msgstr ""
616
617 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:315
618 #, python-brace-format
619 msgctxt "option|greeter|screensaver-timeout"
378620 msgid "{count} min"
379621 msgstr ""
380622
381 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:150
382 #, python-brace-format
383 msgid "Failed to read configuration file: {path}"
384 msgstr ""
385
386 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:186
623 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:358
624 msgctxt "option|greeter|theme-name"
625 msgid "Selected theme is not available"
626 msgstr ""
627
628 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:371
629 msgctxt "option|greeter|icon-theme-name"
630 msgid "Selected theme is not available"
631 msgstr ""
632
633 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:378
634 msgctxt "option|greeter|allow-debugging"
635 msgid "GtkInspector is not available on your system"
636 msgstr ""
637
638 #: ../lightdm_gtk_greeter_settings/GtkGreeterSettingsWindow.py:407
639 msgid "Do not leave this field empty"
640 msgstr ""
641
642 #: ../lightdm_gtk_greeter_settings/helpers.py:150
643 #, python-brace-format
644 msgid "File not found: {path}"
645 msgstr ""
646
647 #: ../lightdm_gtk_greeter_settings/helpers.py:174
648 #, python-brace-format
649 msgid "Failed to check permissions: {error}"
650 msgstr ""
651
652 #: ../lightdm_gtk_greeter_settings/helpers.py:177
653 #, python-brace-format
654 msgid "Directory is not readable: {path}"
655 msgstr ""
656
657 #: ../lightdm_gtk_greeter_settings/helpers.py:180
658 #: ../lightdm_gtk_greeter_settings/helpers.py:183
659 #: ../lightdm_gtk_greeter_settings/helpers.py:185
660 #, python-brace-format
661 msgid "LightDM do not have permissions to read path: {path}"
662 msgstr ""
663
664 #: ../lightdm_gtk_greeter_settings/helpers.py:191
665 #, python-brace-format
666 msgid "Path is not a regular file: {path}"
667 msgstr ""
668
669 #: ../lightdm_gtk_greeter_settings/helpers.py:197
670 #: ../lightdm_gtk_greeter_settings/helpers.py:201
671 #: ../lightdm_gtk_greeter_settings/helpers.py:204
672 #, python-brace-format
673 msgid "LightDM do not have permissions to execute file: {path}"
674 msgstr ""
675
676 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:200
387677 msgctxt "icon-dialog"
388678 msgid "All contexts"
389679 msgstr ""
390680
391681 #. separator
392 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:188
682 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:202
393683 msgctxt "icon-dialog"
394684 msgid "Actions"
395685 msgstr ""
396686
397 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:189
687 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:203
398688 msgctxt "icon-dialog"
399689 msgid "Applications"
400690 msgstr ""
401691
402 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:190
692 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:204
403693 msgctxt "icon-dialog"
404694 msgid "Categories"
405695 msgstr ""
406696
407 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:191
697 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:205
408698 msgctxt "icon-dialog"
409699 msgid "Devices"
410700 msgstr ""
411701
412 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:192
702 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:206
413703 msgctxt "icon-dialog"
414704 msgid "Emblems"
415705 msgstr ""
416706
417 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:193
707 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:207
418708 msgctxt "icon-dialog"
419709 msgid "Emoticons"
420710 msgstr ""
421711
422 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:194
712 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:208
423713 msgctxt "icon-dialog"
424714 msgid "International"
425715 msgstr ""
426716
427 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:195
717 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:209
428718 msgctxt "icon-dialog"
429719 msgid "MIME Types"
430720 msgstr ""
431721
432 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:196
722 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:210
433723 msgctxt "icon-dialog"
434724 msgid "Places"
435725 msgstr ""
436726
437 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:197
727 #: ../lightdm_gtk_greeter_settings/IconChooserDialog.py:211
438728 msgctxt "icon-dialog"
439729 msgid "Status"
440730 msgstr ""
441731
442 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:290
732 #: ../lightdm_gtk_greeter_settings/IndicatorPropertiesDialog.py:71
733 msgctxt "option-entry|indicators"
734 msgid "<b>Using default value</b>"
735 msgstr ""
736
737 #: ../lightdm_gtk_greeter_settings/IndicatorPropertiesDialog.py:77
738 msgctxt "option-entry|indicators"
739 msgid "Use default value..."
740 msgstr ""
741
742 #: ../lightdm_gtk_greeter_settings/IndicatorPropertiesDialog.py:233
743 msgctxt "option-entry|indicators"
744 msgid "Path/Service field is not filled"
745 msgstr ""
746
747 #: ../lightdm_gtk_greeter_settings/IndicatorPropertiesDialog.py:237
748 #, python-brace-format
749 msgctxt "option-entry|indicators"
750 msgid ""
751 "Indicator \"{name}\" is already in the list.\n"
752 "It will be overwritten."
753 msgstr ""
754
755 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:131
756 msgctxt "option-entry|indicators|name"
757 msgid "External library/service"
758 msgstr ""
759
760 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:132
761 msgctxt "option-entry|indicators|name"
762 msgid "Spacer"
763 msgstr ""
764
765 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:133
766 msgctxt "option-entry|indicators|name"
767 msgid "Separator"
768 msgstr ""
769
770 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:134
771 msgctxt "option-entry|indicators|name"
772 msgid "Text"
773 msgstr ""
774
775 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:135
776 msgctxt "option-entry|indicators|name"
777 msgid "Clock"
778 msgstr ""
779
780 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:136
781 msgctxt "option-entry|indicators|name"
782 msgid "Host name"
783 msgstr ""
784
785 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:137
786 msgctxt "option-entry|indicators|name"
787 msgid "Keyboard layout"
788 msgstr ""
789
790 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:138
791 msgctxt "option-entry|indicators|name"
792 msgid "Sessions menu"
793 msgstr ""
794
795 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:139
796 msgctxt "option-entry|indicators|name"
797 msgid "Languages menu"
798 msgstr ""
799
800 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:140
801 msgctxt "option-entry|indicators|name"
802 msgid "Accessibility menu"
803 msgstr ""
804
805 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:141
806 msgctxt "option-entry|indicators|name"
807 msgid "Power menu"
808 msgstr ""
809
810 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:148
811 msgctxt "option-entry|indicators|tooltip"
812 msgid "Spacer"
813 msgstr ""
814
815 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:149
816 msgctxt "option-entry|indicators|tooltip"
817 msgid "Separator"
818 msgstr ""
819
820 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:150
821 msgctxt "option-entry|indicators|tooltip"
822 msgid "Custom text or/and image"
823 msgstr ""
824
825 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:151
826 msgctxt "option-entry|indicators|tooltip"
827 msgid "Host name"
828 msgstr ""
829
830 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:152
831 msgctxt "option-entry|indicators|tooltip"
832 msgid "Clock"
833 msgstr ""
834
835 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:153
836 msgctxt "option-entry|indicators|tooltip"
837 msgid "Layout indicator"
838 msgstr ""
839
840 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:155
841 msgctxt "option-entry|indicators|tooltip"
842 msgid "Sessions menu (xfce, unity, gnome etc.)"
843 msgstr ""
844
845 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:156
846 msgctxt "option-entry|indicators|tooltip"
847 msgid "Languages menu"
848 msgstr ""
849
850 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:157
851 msgctxt "option-entry|indicators|tooltip"
852 msgid "Accessibility menu"
853 msgstr ""
854
855 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:158
856 msgctxt "option-entry|indicators|tooltip"
857 msgid "Power menu"
858 msgstr ""
859
860 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:581
861 msgctxt "option-entry|indicators"
862 msgid "Reset to _defaults"
863 msgstr ""
864
865 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:583
866 msgctxt "option-entry|indicators"
867 msgid "Display _label"
868 msgstr ""
869
870 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:585
871 msgctxt "option-entry|indicators"
872 msgid "Display _image"
873 msgstr ""
874
875 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:587
876 msgctxt "option-entry|indicators"
877 msgid "_Remove"
878 msgstr ""
879
880 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:687
881 msgctxt "option-entry|indicators"
882 msgid "Show unused items"
883 msgstr ""
884
885 #: ../lightdm_gtk_greeter_settings/IndicatorsEntry.py:691
886 msgctxt "option-entry|indicators"
887 msgid "Predefined templates:"
888 msgstr ""
889
890 #: ../lightdm_gtk_greeter_settings/MultiheadSetupDialog.py:109
891 #, python-brace-format
892 msgctxt "option|multihead"
893 msgid "Available monitors: {monitors}"
894 msgstr ""
895
896 #: ../lightdm_gtk_greeter_settings/MultiheadSetupDialog.py:239
897 msgctxt "option|multihead"
898 msgid "Select background file"
899 msgstr ""
900
901 #: ../lightdm_gtk_greeter_settings/MultiheadSetupDialog.py:272
902 #, python-brace-format
903 msgctxt "option|multihead"
904 msgid "Invalid name: \"{name}\""
905 msgstr ""
906
907 #: ../lightdm_gtk_greeter_settings/MultiheadSetupDialog.py:275
908 msgctxt "option|multihead"
909 msgid "This name already in use."
910 msgstr ""
911
912 #: ../lightdm_gtk_greeter_settings/MultiheadSetupDialog.py:277
913 msgctxt "option|multihead"
914 msgid "This name is not valid."
915 msgstr ""
916
917 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:252
918 msgctxt "option|StringPathEntry"
919 msgid "Select path"
920 msgstr ""
921
922 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:426
443923 #, python-brace-format
444924 msgctxt "option-entry|icon"
445925 msgid "<b>Icon: {icon}</b>"
446926 msgstr ""
447927
448 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:294
928 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:431
449929 msgctxt "option-entry|icon"
450930 msgid "Select icon name..."
451931 msgstr ""
452932
453 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:299
933 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:435
934 #, python-brace-format
935 msgctxt "option-entry|icon"
936 msgid "<b>File: {path}</b> (failed to load)"
937 msgstr ""
938
939 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:437
454940 #, python-brace-format
455941 msgctxt "option-entry|icon"
456942 msgid "<b>File: {path}</b>"
457943 msgstr ""
458944
459 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:303
945 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:443
460946 msgctxt "option-entry|icon"
461947 msgid "Select file..."
462 msgstr ""
463
464 #: ../lightdm_gtk_greeter_settings/OptionEntry.py:444
465 #, python-brace-format
466 msgctxt "option-entry|indicators"
467 msgid "Indicator \"{indicator}\" is already in the list"
468948 msgstr ""
469949
470950 #: ../com.ubuntu.pkexec.lightdm-gtk-greeter-settings.policy.in.h:1