3 # Copyright 2015 Tails developers <tails@boum.org>
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program. If not, see <http://www.gnu.org/licenses/>
18 ################################################################################
21 # * help button should not look like buttons
22 # * settings change position when added, then removed
23 # * fill formats with formats (cf gnome-control-center)
24 # * show time when timezone is selected (we'll need to have it editable at some poit)
25 # * add a way cancel setting adding
26 ################################################################################
33 gi
.require_version('GLib', '2.0')
34 from gi
.repository
import GLib
35 gi
.require_version('Gdk', '3.0')
36 from gi
.repository
import Gdk
37 gi
.require_version('Gtk', '3.0')
38 from gi
.repository
import Gtk
42 # To ease future internationalisation
45 UI_FILE
= 'greeter.ui'
47 APPLICATION_ICON_NAME
= 'gdm-setup'
48 APPLICATION_TITLE
= 'Welcome to Tails!'
50 class GreeterMainWindow(Gtk
.ApplicationWindow
):
52 def __init__(self
, app
):
53 Gtk
.Window
.__init
__(self
, title
=APPLICATION_TITLE
, application
=app
)
55 self
.set_icon_name(APPLICATION_ICON_NAME
)
57 self
.set_position(Gtk
.WindowPosition
.CENTER
)
58 self
._last
_selected
_setting
_row
= []
61 # Load UI interface definition
62 self
._builder
= Gtk
.Builder()
63 self
._builder
.add_from_file(UI_FILE
)
64 self
._builder
.connect_signals(self
)
66 # Map interface objects
67 box_main
= self
._builder
.get_object('box_main')
69 self
.label_language_header_status
= \
70 self
._builder
.get_object('label_language_header_status')
71 checkbutton_language_save
= \
72 self
._builder
.get_object('checkbutton_language_save')
73 self
.listbox_language
= self
._builder
.get_object('listbox_language')
74 self
.listboxrow_text
= self
._builder
.get_object('listboxrow_text')
75 self
.label_text_value
= self
._builder
.get_object('label_text_value')
76 self
.listboxrow_keyboard
= self
._builder
.get_object('listboxrow_keyboard')
77 self
.label_keyboard_value
= self
._builder
.get_object('label_keyboard_value')
78 self
.listboxrow_formats
= self
._builder
.get_object('listboxrow_formats')
79 self
.label_formats_value
= self
._builder
.get_object('label_formats_value')
80 self
.listboxrow_tz
= self
._builder
.get_object('listboxrow_tz')
81 self
.label_tz_value
= self
._builder
.get_object('label_tz_value')
83 self
.checkbutton_storage_show_passphrase
= \
84 self
._builder
.get_object('checkbutton_storage_show_passphrase')
85 self
.button_storage_configure
= \
86 self
._builder
.get_object('button_storage_configure')
87 self
.button_storage_state
= self
._builder
.get_object('button_storage_state')
88 self
.image_storage_state
= self
._builder
.get_object('image_storage_state')
89 self
.button_storage_spinner
= \
90 self
._builder
.get_object('button_storage_spinner')
91 self
.spinner_storage_unlock
= \
92 self
._builder
.get_object('spinner_storage_unlock')
93 self
.entry_storage_passphrase
= \
94 self
._builder
.get_object('entry_storage_passphrase')
95 self
.button_storage_lock
= self
._builder
.get_object('button_storage_lock')
96 self
.button_storage_unlock
=self
._builder
.get_object('button_storage_unlock')
97 self
.box_storage_unlock
= self
._builder
.get_object('box_storage_unlock')
99 checkbutton_settings_save
= \
100 self
._builder
.get_object('checkbutton_settings_save')
101 self
.listbox_settings
= self
._builder
.get_object('listbox_settings')
102 self
.listboxrow_settings_admin
= \
103 self
._builder
.get_object('listboxrow_settings_admin')
104 self
.label_settings_admin_value
= \
105 self
._builder
.get_object('label_settings_admin_value')
106 self
.listboxrow_settings_macspoof
= \
107 self
._builder
.get_object('listboxrow_settings_macspoof')
108 self
.label_settings_macspoof_value
= \
109 self
._builder
.get_object('label_settings_macspoof_value')
110 self
.listboxrow_settings_network
= \
111 self
._builder
.get_object('listboxrow_settings_network')
112 self
.label_settings_network_value
= \
113 self
._builder
.get_object('label_settings_network_value')
114 self
.listboxrow_settings_camouflage
= \
115 self
._builder
.get_object('listboxrow_settings_camouflage')
116 self
.label_settings_camouflage_value
= \
117 self
._builder
.get_object('label_settings_camouflage_value')
119 label_settings_default
= \
120 self
._builder
.get_object('label_settings_default')
121 self
.toolbutton_settings_remove
= \
122 self
._builder
.get_object('toolbutton_settings_remove')
123 self
.toolbutton_settings_add
= \
124 self
._builder
.get_object('toolbutton_settings_add')
126 self
.window_add_setting
= self
._builder
.get_object('window_add_setting')
127 self
.listbox_add_setting
= self
._builder
.get_object('listbox_add_setting')
129 box_text_popover
= self
._builder
.get_object('box_text_popover')
130 searchentry_text
= self
._builder
.get_object('searchentry_text')
131 liststore_text
= self
._builder
.get_object('liststore_text')
132 treeview_text
= self
._builder
.get_object('treeview_text')
133 box_keyboard_popover
= self
._builder
.get_object('box_keyboard_popover')
134 searchentry_keyboard
= self
._builder
.get_object('searchentry_keyboard')
135 liststore_keyboard
= self
._builder
.get_object('liststore_keyboard')
136 treeview_keyboard
= self
._builder
.get_object('treeview_keyboard')
137 box_formats_popover
= self
._builder
.get_object('box_formats_popover')
138 searchentry_formats
= self
._builder
.get_object('searchentry_formats')
139 liststore_formats
= self
._builder
.get_object('liststore_formats')
140 treeview_formats
= self
._builder
.get_object('treeview_formats')
141 box_tz_popover
= self
._builder
.get_object('box_tz_popover')
142 searchentry_tz
= self
._builder
.get_object('searchentry_tz')
143 liststore_tz
= self
._builder
.get_object('liststore_tz')
144 treeview_tz
= self
._builder
.get_object('treeview_tz')
146 box_admin_popover
= self
._builder
.get_object('box_admin_popover')
147 self
.entry_admin_password
= \
148 self
._builder
.get_object('entry_admin_password')
149 self
.entry_admin_verify
= self
._builder
.get_object('entry_admin_verify')
150 box_macspoof_popover
= self
._builder
.get_object('box_macspoof_popover')
151 switch_macspoof
= self
._builder
.get_object('switch_macspoof')
152 box_network_popover
= self
._builder
.get_object('box_network_popover')
153 self
.listbox_network_controls
= \
154 self
._builder
.get_object('listbox_network_controls')
155 self
.listboxrow_network_clear
= \
156 self
._builder
.get_object('listboxrow_network_clear')
157 self
.image_network_clear
= \
158 self
._builder
.get_object('image_network_clear')
159 self
.listboxrow_network_specific
= \
160 self
._builder
.get_object('listboxrow_network_specific')
161 self
.image_network_specific
= \
162 self
._builder
.get_object('image_network_specific')
163 self
.listboxrow_network_off
= \
164 self
._builder
.get_object('listboxrow_network_off')
165 self
.image_network_off
= \
166 self
._builder
.get_object('image_network_off')
167 box_camouflage_popover
= \
168 self
._builder
.get_object('box_camouflage_popover')
169 switch_camouflage
= self
._builder
.get_object('switch_camouflage')
172 self
.set_default_size(600, -1)
174 # Add our icon dir to icon theme
175 icon_theme
= Gtk
.IconTheme
.get_default()
176 icon_theme
.prepend_search_path(ICON_DIR
)
178 # Add placeholder to settings ListBox
179 self
.listbox_settings
.set_placeholder(label_settings_default
)
182 headerbar
= Gtk
.HeaderBar()
183 headerbar_sizegroup
= Gtk
.SizeGroup(Gtk
.SizeGroupMode
.HORIZONTAL
)
185 button_restart
= Gtk
.Button()
186 button_restart
.set_label(_("Restart"))
187 button_restart
.connect('clicked', self
.cb_button_restart_clicked
)
188 headerbar_sizegroup
.add_widget(button_restart
)
189 headerbar
.pack_start(button_restart
)
191 button_start
= Gtk
.Button()
192 button_start
.set_label(_("Start Tails"))
193 Gtk
.StyleContext
.add_class(button_start
.get_style_context(),
195 button_start
.connect('clicked', self
.cb_button_start_clicked
)
196 headerbar_sizegroup
.add_widget(button_start
)
197 headerbar
.pack_end(button_start
)
199 button_tour
= Gtk
.Button()
200 button_tour
.set_label(_("Take a Tour"))
201 button_tour
.connect('clicked', self
.cb_button_tour_clicked
)
202 headerbar_sizegroup
.add_widget(button_tour
)
203 headerbar
.pack_end(button_tour
)
207 # Align CheckBoxes to the left
208 for cb
in [checkbutton_language_save
,
209 self
.checkbutton_storage_show_passphrase
,
210 checkbutton_settings_save
]:
211 cb
.set_direction(Gtk
.TextDirection
.RTL
)
214 self
.popover_text
= self
.__add
_popover
(
215 self
.listboxrow_text
,
217 closed_cb
=self
.cb_popover_text_closed
)
218 self
.popover_keyboard
= self
.__add
_popover
(
219 self
.listboxrow_keyboard
,
220 box_keyboard_popover
,
221 closed_cb
=self
.cb_popover_keyboard_closed
)
222 self
.popover_formats
= self
.__add
_popover
(
223 self
.listboxrow_formats
,
225 closed_cb
=self
.cb_popover_formats_closed
)
226 self
.popover_tz
= self
.__add
_popover
(
229 closed_cb
=self
.cb_popover_tz_closed
)
231 self
.popover_admin
= self
.__add
_popover
(
232 self
.listboxrow_settings_admin
,
234 closed_cb
=self
.cb_popover_admin_closed
)
235 self
.popover_macspoof
= self
.__add
_popover
(
236 self
.listboxrow_settings_macspoof
,
237 box_macspoof_popover
,
238 closed_cb
=self
.cb_popover_macspoof_closed
)
239 self
.popover_network
= self
.__add
_popover
(
240 self
.listboxrow_settings_network
,
242 closed_cb
=self
.cb_popover_network_closed
)
243 self
.popover_camouflage
= self
.__add
_popover
(
244 self
.listboxrow_settings_camouflage
,
245 box_camouflage_popover
,
246 closed_cb
=self
.cb_popover_camouflage_closed
)
248 # Add children to ApplicationWindow
250 self
.set_titlebar(headerbar
)
252 # Create "Add Privacy Setting" dialog
253 self
.window_add_setting
.set_transient_for(self
)
255 # Fill language treeviews
256 for language
in greeterdata
.languages
:
257 liststore_text
.append(language
)
258 self
.__fill
_tv
("Text Language", treeview_text
)
259 self
.liststore_text_filtered
= liststore_text
.filter_new()
260 self
.liststore_text_filtered
.set_visible_func(
261 self
.cb_liststore_filtered_visible_func
, data
=searchentry_text
)
262 treeview_text
.set_model(self
.liststore_text_filtered
)
264 for layout
in greeterdata
.layouts
:
265 liststore_keyboard
.append(layout
)
266 self
.__fill
_tv
("Keyboard Layout", treeview_keyboard
)
267 self
.liststore_keyboard_filtered
= liststore_keyboard
.filter_new()
268 self
.liststore_keyboard_filtered
.set_visible_func(
269 self
.cb_liststore_filtered_visible_func
, data
=searchentry_keyboard
)
270 treeview_keyboard
.set_model(self
.liststore_keyboard_filtered
)
272 for locale
in greeterdata
.locales
:
273 liststore_formats
.append(locale
)
274 self
.__fill
_tv
("Format", treeview_formats
)
275 self
.liststore_formats_filtered
= liststore_formats
.filter_new()
276 self
.liststore_formats_filtered
.set_visible_func(
277 self
.cb_liststore_filtered_visible_func
, data
=searchentry_formats
)
278 treeview_formats
.set_model(self
.liststore_formats_filtered
)
280 for timezone
in greeterdata
.timezones
:
281 liststore_tz
.append(timezone
)
282 self
.__fill
_tv
("Time Zone", treeview_tz
)
283 self
.liststore_tz_filtered
= liststore_tz
.filter_new()
284 self
.liststore_tz_filtered
.set_visible_func(
285 self
.cb_liststore_filtered_visible_func
, data
=searchentry_tz
)
286 treeview_tz
.set_model(self
.liststore_tz_filtered
)
288 # Storage configuration/unlocking
289 if os
.getenv('TAILS_HAS_PERSISTENCE'):
290 self
.button_storage_configure
.set_visible(False)
291 self
.checkbutton_storage_show_passphrase
.set_visible(True)
292 self
.box_storage_unlock
.set_visible(True)
293 self
.button_storage_state
.set_visible(True)
294 self
.entry_storage_passphrase
.set_visible(True)
295 self
.button_storage_unlock
.set_visible(True)
298 switch_macspoof
.connect('notify::active', self
.cb_switch_macspoof_active
)
299 switch_camouflage
.connect('notify::active', self
.cb_switch_camouflage_active
)
301 def setting_admin_check(self
):
302 password
= self
.entry_admin_password
.get_text()
303 verify
= self
.entry_admin_verify
.get_text()
304 if verify
and verify
== password
:
305 icon
= 'emblem-ok-symbolic'
306 elif verify
and not (verify
== password
):
307 icon
= 'dialog-warning-symbolic'
310 self
.entry_admin_verify
.set_icon_from_icon_name(
311 Gtk
.EntryIconPosition
.SECONDARY
, icon
)
312 return (verify
== password
)
314 def setting_admin_apply(self
):
315 if self
.setting_admin_check():
316 self
.label_settings_admin_value
.set_text(
317 self
.__get
_on
_off
_string
(self
.entry_admin_password
.get_text()))
318 self
.popover_admin
.set_visible(False)
326 def __add_popover(widget
, content
, closed_cb
=None):
327 popover
= Gtk
.Popover
.new(widget
)
328 popover
.set_position(Gtk
.PositionType
.BOTTOM
)
331 popover
.connect('closed', closed_cb
)
335 def __fill_tv (name
, treeview
):
336 assert isinstance(name
, str)
337 assert isinstance(treeview
, Gtk
.TreeView
)
338 renderer
= Gtk
.CellRendererText()
339 column
= Gtk
.TreeViewColumn(name
, renderer
, text
=1)
340 treeview
.append_column(column
)
343 def __popover_toggle(popover
):
344 if popover
.get_visible():
345 popover
.set_visible(False)
347 popover
.set_visible(True)
350 def __get_on_off_string(value
):
358 def cb_button_help_clicked(self
, widget
, user_data
=None):
359 dialog
= Gtk
.MessageDialog(
361 Gtk
.DialogFlags
.DESTROY_WITH_PARENT
,
362 Gtk
.MessageType
.INFO
,
363 Gtk
.ButtonsType
.CLOSE
,
364 _("You would see the help page for this element."))
369 def cb_button_restart_clicked(self
, widget
, user_data
=None):
373 def cb_button_start_clicked(self
, widget
, user_data
=None):
377 def cb_button_storage_configure_clicked(self
, user_data
=None):
378 dialog
= Gtk
.MessageDialog(
380 Gtk
.DialogFlags
.DESTROY_WITH_PARENT
,
381 Gtk
.MessageType
.INFO
,
382 Gtk
.ButtonsType
.CLOSE
,
383 _("You would be able to set up an encrypted storage."))
388 def cb_button_tour_clicked(self
, user_data
=None):
389 dialog
= Gtk
.MessageDialog(
391 Gtk
.DialogFlags
.DESTROY_WITH_PARENT
,
392 Gtk
.MessageType
.INFO
,
393 Gtk
.ButtonsType
.CLOSE
,
394 _("You would be guided through options by a wizard."))
400 def cb_button_storage_lock_clicked(self
, widget
, user_data
=None):
401 self
.button_storage_lock
.set_visible(False)
402 self
.checkbutton_storage_show_passphrase
.set_visible(True)
403 self
.box_storage_unlock
.set_visible(True)
404 self
.button_storage_state
.set_visible(True)
405 self
.image_storage_state
.set_from_icon_name('tails-locked',
407 self
.entry_storage_passphrase
.set_visible(True)
408 self
.entry_storage_passphrase
.set_sensitive(True)
409 self
.button_storage_unlock
.set_visible(True)
410 self
.button_storage_unlock
.set_sensitive(True)
411 self
.button_storage_unlock
.set_label(_("Unlock"))
414 def cb_button_storage_unlock_clicked(self
, widget
, user_data
=None):
415 self
.checkbutton_storage_show_passphrase
.set_visible(False)
416 self
.entry_storage_passphrase
.set_sensitive(False)
417 self
.button_storage_unlock
.set_sensitive(False)
418 self
.button_storage_unlock
.set_label(_("Unlocking"))
419 self
.button_storage_state
.set_visible(False)
420 self
.button_storage_spinner
.set_visible(True)
421 GLib
.timeout_add_seconds(2, self
.cb_timeout_storage_unlocked
, user_data
=None)
424 def cb_checkbutton_storage_show_passphrase_toggled(self
, widget
, user_data
=None):
425 self
.entry_storage_passphrase
.set_visibility(widget
.get_active())
427 def cb_entry_admin_changed(self
, editable
, user_data
=None):
428 self
.setting_admin_check()
431 def cb_entry_admin_focus_out_event(self
, widget
, event
, user_data
=None):
432 self
.setting_admin_apply()
435 def cb_entry_admin_password_activate(self
, widget
, user_data
=None):
436 self
.entry_admin_verify
.grab_focus()
439 def cb_entry_admin_verify_activate(self
, widget
, user_data
=None):
440 self
.setting_admin_apply()
443 def cb_listbox_add_setting_focus(self
, widget
, direction
, user_data
=None):
444 # Workaround autoselection of 1st item on focus
445 self
.listbox_add_setting
.unselect_all()
448 def cb_listbox_add_setting_row_activated(self
, listbox
, row
, user_data
=None):
449 if not row
: # this happens when the row gets unselected
452 self
.listbox_settings
.add(row
)
453 self
.window_add_setting
.set_visible(False)
454 if row
== self
.listboxrow_settings_admin
:
455 self
.__popover
_toggle
(self
.popover_admin
)
456 elif row
== self
.listboxrow_settings_macspoof
:
457 self
.__popover
_toggle
(self
.popover_macspoof
)
458 elif row
== self
.listboxrow_settings_network
:
459 self
.__popover
_toggle
(self
.popover_network
)
460 elif row
== self
.listboxrow_settings_camouflage
:
461 self
.__popover
_toggle
(self
.popover_camouflage
)
462 if len(listbox
.get_children()) == 0:
463 self
.toolbutton_settings_add
.set_sensitive(False)
466 def cb_listbox_language_row_activated(self
, listbox
, row
, user_data
=None):
467 if row
== self
.listboxrow_text
:
468 self
.__popover
_toggle
(self
.popover_text
)
469 elif row
== self
.listboxrow_keyboard
:
470 self
.__popover
_toggle
(self
.popover_keyboard
)
471 elif row
== self
.listboxrow_formats
:
472 self
.__popover
_toggle
(self
.popover_formats
)
473 elif row
== self
.listboxrow_tz
:
474 self
.__popover
_toggle
(self
.popover_tz
)
477 def cb_listbox_network_row_activated(self
, listbox
, row
, user_data
=None):
478 if row
== self
.listboxrow_network_clear
:
479 self
.image_network_clear
.set_visible(True)
480 self
.image_network_specific
.set_visible(False)
481 self
.image_network_off
.set_visible(False)
482 self
.label_settings_network_value
.set_text(_("Direct"))
483 elif row
== self
.listboxrow_network_specific
:
484 self
.image_network_specific
.set_visible(True)
485 self
.image_network_clear
.set_visible(False)
486 self
.image_network_off
.set_visible(False)
487 self
.label_settings_network_value
.set_text(_("Censored"))
488 elif row
== self
.listboxrow_network_off
:
489 self
.image_network_off
.set_visible(True)
490 self
.image_network_specific
.set_visible(False)
491 self
.image_network_clear
.set_visible(False)
492 self
.label_settings_network_value
.set_text(_("Off"))
493 self
.popover_network
.set_visible(False)
496 def cb_listbox_settings_add(self
, listbox
, row
, user_data
=None):
497 self
._last
_selected
_setting
_row
.append(row
)
498 if len(listbox
.get_children()) > 0:
499 self
.toolbutton_settings_remove
.set_sensitive(True)
502 def cb_listbox_settings_remove(self
, container
, object, user_data
=None):
503 if len(container
.get_children()) == 0:
504 self
.toolbutton_settings_remove
.set_sensitive(False)
507 def cb_listbox_settings_row_selected(self
, listbox
, row
, user_data
=None):
509 self
._last
_selected
_setting
_row
.append(row
)
511 def cb_listbox_settings_row_activated(self
, listbox
, row
, user_data
=None):
512 if row
== self
.listboxrow_settings_admin
:
513 self
.__popover
_toggle
(self
.popover_admin
)
514 elif row
== self
.listboxrow_settings_macspoof
:
515 self
.__popover
_toggle
(self
.popover_macspoof
)
516 elif row
== self
.listboxrow_settings_network
:
517 self
.__popover
_toggle
(self
.popover_network
)
518 elif row
== self
.listboxrow_settings_camouflage
:
519 self
.__popover
_toggle
(self
.popover_camouflage
)
522 def cb_liststore_filtered_visible_func(self
, model
, treeiter
, searchentry
):
523 search_query
= searchentry
.get_text().lower()
524 value
= model
.get_value(treeiter
, 1).lower()
527 elif search_query
in value
:
532 def cb_popover_text_closed(self
, popover
, user_data
=None):
533 self
.listbox_language
.unselect_all()
536 def cb_popover_keyboard_closed(self
, popover
, user_data
=None):
537 self
.listbox_language
.unselect_all()
540 def cb_popover_formats_closed(self
, popover
, user_data
=None):
541 self
.listbox_language
.unselect_all()
544 def cb_popover_tz_closed(self
, popover
, user_data
=None):
545 self
.listbox_language
.unselect_all()
548 def cb_popover_admin_closed(self
, popover
, user_data
=None):
549 self
.listbox_settings
.unselect_all()
552 def cb_popover_macspoof_closed(self
, popover
, user_data
=None):
553 self
.listbox_settings
.unselect_all()
556 def cb_popover_network_closed(self
, popover
, user_data
=None):
557 self
.listbox_settings
.unselect_all()
560 def cb_popover_camouflage_closed(self
, popover
, user_data
=None):
561 self
.listbox_settings
.unselect_all()
564 def cb_searchentry_formats_search_changed(self
, widget
, user_data
=None):
565 self
.liststore_formats_filtered
.refilter()
568 def cb_searchentry_keyboard_search_changed(self
, widget
, user_data
=None):
569 self
.liststore_keyboard_filtered
.refilter()
572 def cb_searchentry_text_search_changed(self
, widget
, user_data
=None):
573 self
.liststore_text_filtered
.refilter()
576 def cb_searchentry_tz_search_changed(self
, widget
, user_data
=None):
577 self
.liststore_tz_filtered
.refilter()
580 def cb_switch_camouflage_active(self
, switch
, pspec
, user_data
=None):
581 self
.label_settings_camouflage_value
.set_text(
582 self
.__get
_on
_off
_string
(switch
.get_state()))
583 self
.popover_camouflage
.set_visible(False)
585 def cb_switch_macspoof_active(self
, switch
, pspec
, user_data
=None):
586 self
.label_settings_macspoof_value
.set_text(
587 self
.__get
_on
_off
_string
(switch
.get_state()))
588 self
.popover_macspoof
.set_visible(False)
590 def cb_timeout_storage_unlocked(self
, user_data
=None):
591 self
.button_storage_spinner
.set_visible(False)
592 self
.entry_storage_passphrase
.set_visible(False)
593 self
.button_storage_unlock
.set_visible(False)
594 self
.image_storage_state
.set_from_icon_name('tails-unlocked',
596 self
.button_storage_state
.set_visible(True)
597 self
.button_storage_lock
.set_visible(True)
600 def cb_toolbutton_settings_add_clicked(self
, user_data
=None):
601 self
.window_add_setting
.show_all()
604 def cb_toolbutton_settings_remove_clicked(self
, user_data
=None):
606 row
= self
._last
_selected
_setting
_row
.pop()
609 self
.listbox_settings
.remove(row
)
610 self
.listbox_add_setting
.add(row
)
613 def cb_treeview_formats_row_activated(self
, treeview
, path
, column
, user_data
=None):
614 treemodel
= treeview
.get_model()
615 value
= treemodel
.get_value(treemodel
.get_iter(path
), 1)
616 self
.label_formats_value
.set_text(value
)
617 self
.label_language_header_status
.set_text(_("Custom settings"))
618 self
.popover_formats
.set_visible(False)
620 def cb_treeview_keyboard_row_activated(self
, treeview
, path
, column
, user_data
=None):
621 treemodel
= treeview
.get_model()
622 value
= treemodel
.get_value(treemodel
.get_iter(path
), 1)
623 self
.label_keyboard_value
.set_text(value
)
624 self
.label_language_header_status
.set_text(_("Custom settings"))
625 self
.popover_keyboard
.set_visible(False)
627 def cb_treeview_text_row_activated(self
, treeview
, path
, column
, user_data
=None):
628 treemodel
= treeview
.get_model()
629 value
= treemodel
.get_value(treemodel
.get_iter(path
), 1)
630 self
.label_text_value
.set_text(value
)
631 self
.label_language_header_status
.set_text(_("Custom settings"))
632 self
.popover_text
.set_visible(False)
634 def cb_treeview_tz_row_activated(self
, treeview
, path
, column
, user_data
=None):
635 treemodel
= treeview
.get_model()
636 value
= treemodel
.get_value(treemodel
.get_iter(path
), 1)
637 self
.label_tz_value
.set_text(value
)
638 self
.label_language_header_status
.set_text(_("Custom settings"))
639 self
.popover_tz
.set_visible(False)
641 class GreeterBackgroundWindow(Gtk
.ApplicationWindow
):
643 def __init__(self
, app
):
644 Gtk
.Window
.__init
__(self
, title
=APPLICATION_TITLE
, application
=app
)
645 self
.set_icon_name(APPLICATION_ICON_NAME
)
646 self
.override_background_color(
647 Gtk
.StateFlags
.NORMAL
, Gdk
.RGBA(0, 0, 0, 1))
649 class GreeterApplication(Gtk
.Application
):
652 Gtk
.Application
.__init
__(self
)
653 self
.set_application_id
= 'org.boum.tails.greeter'
655 def do_activate(self
):
656 backgroundwindow
= GreeterBackgroundWindow(self
)
657 backgroundwindow
.maximize()
658 appwindow
= GreeterMainWindow(self
)
659 appwindow
.set_transient_for(backgroundwindow
)
661 if not os
.getenv('DEBUG'):
662 backgroundwindow
.show()
665 def do_startup(self
):
666 Gtk
.Application
.do_startup(self
)
668 app
= GreeterApplication()
669 exit_status
= app
.run(sys
.argv
)
670 sys
.exit(exit_status
)