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()
184 button_restart
= Gtk
.Button()
185 button_restart
.set_label(_("Restart"))
186 button_restart
.set_size_request(100, -1)
187 button_restart
.connect('clicked', self
.cb_button_restart_clicked
)
188 headerbar
.pack_start(button_restart
)
190 button_start
= Gtk
.Button()
191 button_start
.set_label(_("Start Tails"))
192 button_start
.set_size_request(100, -1)
193 Gtk
.StyleContext
.add_class(button_start
.get_style_context(),
195 button_start
.connect('clicked', self
.cb_button_start_clicked
)
196 headerbar
.pack_end(button_start
)
198 button_tour
= Gtk
.Button()
199 button_tour
.set_label(_("Take a Tour"))
200 button_tour
.set_size_request(100, -1)
201 button_tour
.connect('clicked', self
.cb_button_tour_clicked
)
202 headerbar
.pack_end(button_tour
)
206 # Align CheckBoxes to the left
207 for cb
in [checkbutton_language_save
,
208 self
.checkbutton_storage_show_passphrase
,
209 checkbutton_settings_save
]:
210 cb
.set_direction(Gtk
.TextDirection
.RTL
)
213 self
.popover_text
= self
.__add
_popover
(
214 self
.listboxrow_text
,
216 closed_cb
=self
.cb_popover_text_closed
)
217 self
.popover_keyboard
= self
.__add
_popover
(
218 self
.listboxrow_keyboard
,
219 box_keyboard_popover
,
220 closed_cb
=self
.cb_popover_keyboard_closed
)
221 self
.popover_formats
= self
.__add
_popover
(
222 self
.listboxrow_formats
,
224 closed_cb
=self
.cb_popover_formats_closed
)
225 self
.popover_tz
= self
.__add
_popover
(
228 closed_cb
=self
.cb_popover_tz_closed
)
230 self
.popover_admin
= self
.__add
_popover
(
231 self
.listboxrow_settings_admin
,
233 closed_cb
=self
.cb_popover_admin_closed
)
234 self
.popover_macspoof
= self
.__add
_popover
(
235 self
.listboxrow_settings_macspoof
,
236 box_macspoof_popover
,
237 closed_cb
=self
.cb_popover_macspoof_closed
)
238 self
.popover_network
= self
.__add
_popover
(
239 self
.listboxrow_settings_network
,
241 closed_cb
=self
.cb_popover_network_closed
)
242 self
.popover_camouflage
= self
.__add
_popover
(
243 self
.listboxrow_settings_camouflage
,
244 box_camouflage_popover
,
245 closed_cb
=self
.cb_popover_camouflage_closed
)
247 # Add children to ApplicationWindow
249 self
.set_titlebar(headerbar
)
251 # Create "Add Privacy Setting" dialog
252 self
.window_add_setting
.set_transient_for(self
)
254 # Fill language treeviews
255 for language
in greeterdata
.languages
:
256 liststore_text
.append(language
)
257 self
.__fill
_tv
("Text Language", treeview_text
)
258 self
.liststore_text_filtered
= liststore_text
.filter_new()
259 self
.liststore_text_filtered
.set_visible_func(
260 self
.cb_liststore_filtered_visible_func
, data
=searchentry_text
)
261 treeview_text
.set_model(self
.liststore_text_filtered
)
263 for layout
in greeterdata
.layouts
:
264 liststore_keyboard
.append(layout
)
265 self
.__fill
_tv
("Keyboard Layout", treeview_keyboard
)
266 self
.liststore_keyboard_filtered
= liststore_keyboard
.filter_new()
267 self
.liststore_keyboard_filtered
.set_visible_func(
268 self
.cb_liststore_filtered_visible_func
, data
=searchentry_keyboard
)
269 treeview_keyboard
.set_model(self
.liststore_keyboard_filtered
)
271 for locale
in greeterdata
.locales
:
272 liststore_formats
.append(locale
)
273 self
.__fill
_tv
("Format", treeview_formats
)
274 self
.liststore_formats_filtered
= liststore_formats
.filter_new()
275 self
.liststore_formats_filtered
.set_visible_func(
276 self
.cb_liststore_filtered_visible_func
, data
=searchentry_formats
)
277 treeview_formats
.set_model(self
.liststore_formats_filtered
)
279 for timezone
in greeterdata
.timezones
:
280 liststore_tz
.append(timezone
)
281 self
.__fill
_tv
("Time Zone", treeview_tz
)
282 self
.liststore_tz_filtered
= liststore_tz
.filter_new()
283 self
.liststore_tz_filtered
.set_visible_func(
284 self
.cb_liststore_filtered_visible_func
, data
=searchentry_tz
)
285 treeview_tz
.set_model(self
.liststore_tz_filtered
)
287 # Storage configuration/unlocking
288 if os
.getenv('TAILS_HAS_PERSISTENCE'):
289 self
.button_storage_configure
.set_visible(False)
290 self
.checkbutton_storage_show_passphrase
.set_visible(True)
291 self
.box_storage_unlock
.set_visible(True)
292 self
.button_storage_state
.set_visible(True)
293 self
.entry_storage_passphrase
.set_visible(True)
294 self
.button_storage_unlock
.set_visible(True)
297 switch_macspoof
.connect('notify::active', self
.cb_switch_macspoof_active
)
298 switch_camouflage
.connect('notify::active', self
.cb_switch_camouflage_active
)
300 def setting_admin_check(self
):
301 password
= self
.entry_admin_password
.get_text()
302 verify
= self
.entry_admin_verify
.get_text()
303 if verify
and verify
== password
:
304 icon
= 'emblem-ok-symbolic'
305 elif verify
and not (verify
== password
):
306 icon
= 'dialog-warning-symbolic'
309 self
.entry_admin_verify
.set_icon_from_icon_name(
310 Gtk
.EntryIconPosition
.SECONDARY
, icon
)
311 return (verify
== password
)
313 def setting_admin_apply(self
):
314 if self
.setting_admin_check():
315 self
.label_settings_admin_value
.set_text(
316 self
.__get
_on
_off
_string
(self
.entry_admin_password
.get_text()))
317 self
.popover_admin
.set_visible(False)
325 def __add_popover(widget
, content
, closed_cb
=None):
326 popover
= Gtk
.Popover
.new(widget
)
327 popover
.set_position(Gtk
.PositionType
.BOTTOM
)
330 popover
.connect('closed', closed_cb
)
334 def __fill_tv (name
, treeview
):
335 assert isinstance(name
, str)
336 assert isinstance(treeview
, Gtk
.TreeView
)
337 renderer
= Gtk
.CellRendererText()
338 column
= Gtk
.TreeViewColumn(name
, renderer
, text
=1)
339 treeview
.append_column(column
)
342 def __popover_toggle(popover
):
343 if popover
.get_visible():
344 popover
.set_visible(False)
346 popover
.set_visible(True)
349 def __get_on_off_string(value
):
357 def cb_button_help_clicked(self
, widget
, user_data
=None):
358 dialog
= Gtk
.MessageDialog(
360 Gtk
.DialogFlags
.DESTROY_WITH_PARENT
,
361 Gtk
.MessageType
.INFO
,
362 Gtk
.ButtonsType
.CLOSE
,
363 _("You would see the help page for this element."))
368 def cb_button_restart_clicked(self
, widget
, user_data
=None):
372 def cb_button_start_clicked(self
, widget
, user_data
=None):
376 def cb_button_storage_configure_clicked(self
, user_data
=None):
377 dialog
= Gtk
.MessageDialog(
379 Gtk
.DialogFlags
.DESTROY_WITH_PARENT
,
380 Gtk
.MessageType
.INFO
,
381 Gtk
.ButtonsType
.CLOSE
,
382 _("You would be able to set up an encrypted storage."))
387 def cb_button_tour_clicked(self
, user_data
=None):
388 dialog
= Gtk
.MessageDialog(
390 Gtk
.DialogFlags
.DESTROY_WITH_PARENT
,
391 Gtk
.MessageType
.INFO
,
392 Gtk
.ButtonsType
.CLOSE
,
393 _("You would be guided through options by a wizard."))
399 def cb_button_storage_lock_clicked(self
, widget
, user_data
=None):
400 self
.button_storage_lock
.set_visible(False)
401 self
.checkbutton_storage_show_passphrase
.set_visible(True)
402 self
.box_storage_unlock
.set_visible(True)
403 self
.button_storage_state
.set_visible(True)
404 self
.image_storage_state
.set_from_icon_name('tails-locked',
406 self
.entry_storage_passphrase
.set_visible(True)
407 self
.entry_storage_passphrase
.set_sensitive(True)
408 self
.button_storage_unlock
.set_visible(True)
409 self
.button_storage_unlock
.set_sensitive(True)
410 self
.button_storage_unlock
.set_label(_("Unlock"))
413 def cb_button_storage_unlock_clicked(self
, widget
, user_data
=None):
414 self
.checkbutton_storage_show_passphrase
.set_visible(False)
415 self
.entry_storage_passphrase
.set_sensitive(False)
416 self
.button_storage_unlock
.set_sensitive(False)
417 self
.button_storage_unlock
.set_label(_("Unlocking"))
418 self
.button_storage_state
.set_visible(False)
419 self
.button_storage_spinner
.set_visible(True)
420 GLib
.timeout_add_seconds(2, self
.cb_timeout_storage_unlocked
, user_data
=None)
423 def cb_checkbutton_storage_show_passphrase_toggled(self
, widget
, user_data
=None):
424 self
.entry_storage_passphrase
.set_visibility(widget
.get_active())
426 def cb_entry_admin_changed(self
, editable
, user_data
=None):
427 self
.setting_admin_check()
430 def cb_entry_admin_focus_out_event(self
, widget
, event
, user_data
=None):
431 self
.setting_admin_apply()
434 def cb_entry_admin_password_activate(self
, widget
, user_data
=None):
435 self
.entry_admin_verify
.grab_focus()
438 def cb_entry_admin_verify_activate(self
, widget
, user_data
=None):
439 self
.setting_admin_apply()
442 def cb_listbox_add_setting_focus(self
, widget
, direction
, user_data
=None):
443 # Workaround autoselection of 1st item on focus
444 self
.listbox_add_setting
.unselect_all()
447 def cb_listbox_add_setting_row_activated(self
, listbox
, row
, user_data
=None):
448 if not row
: # this happens when the row gets unselected
451 self
.listbox_settings
.add(row
)
452 self
.window_add_setting
.set_visible(False)
453 if row
== self
.listboxrow_settings_admin
:
454 self
.__popover
_toggle
(self
.popover_admin
)
455 elif row
== self
.listboxrow_settings_macspoof
:
456 self
.__popover
_toggle
(self
.popover_macspoof
)
457 elif row
== self
.listboxrow_settings_network
:
458 self
.__popover
_toggle
(self
.popover_network
)
459 elif row
== self
.listboxrow_settings_camouflage
:
460 self
.__popover
_toggle
(self
.popover_camouflage
)
461 if len(listbox
.get_children()) == 0:
462 self
.toolbutton_settings_add
.set_sensitive(False)
465 def cb_listbox_language_row_activated(self
, listbox
, row
, user_data
=None):
466 if row
== self
.listboxrow_text
:
467 self
.__popover
_toggle
(self
.popover_text
)
468 elif row
== self
.listboxrow_keyboard
:
469 self
.__popover
_toggle
(self
.popover_keyboard
)
470 elif row
== self
.listboxrow_formats
:
471 self
.__popover
_toggle
(self
.popover_formats
)
472 elif row
== self
.listboxrow_tz
:
473 self
.__popover
_toggle
(self
.popover_tz
)
476 def cb_listbox_network_row_activated(self
, listbox
, row
, user_data
=None):
477 if row
== self
.listboxrow_network_clear
:
478 self
.image_network_clear
.set_visible(True)
479 self
.image_network_specific
.set_visible(False)
480 self
.image_network_off
.set_visible(False)
481 self
.label_settings_network_value
.set_text(_("Direct"))
482 elif row
== self
.listboxrow_network_specific
:
483 self
.image_network_specific
.set_visible(True)
484 self
.image_network_clear
.set_visible(False)
485 self
.image_network_off
.set_visible(False)
486 self
.label_settings_network_value
.set_text(_("Censored"))
487 elif row
== self
.listboxrow_network_off
:
488 self
.image_network_off
.set_visible(True)
489 self
.image_network_specific
.set_visible(False)
490 self
.image_network_clear
.set_visible(False)
491 self
.label_settings_network_value
.set_text(_("Off"))
492 self
.popover_network
.set_visible(False)
495 def cb_listbox_settings_add(self
, listbox
, row
, user_data
=None):
496 self
._last
_selected
_setting
_row
.append(row
)
497 if len(listbox
.get_children()) > 0:
498 self
.toolbutton_settings_remove
.set_sensitive(True)
501 def cb_listbox_settings_remove(self
, container
, object, user_data
=None):
502 if len(container
.get_children()) == 0:
503 self
.toolbutton_settings_remove
.set_sensitive(False)
506 def cb_listbox_settings_row_selected(self
, listbox
, row
, user_data
=None):
508 self
._last
_selected
_setting
_row
.append(row
)
510 def cb_listbox_settings_row_activated(self
, listbox
, row
, user_data
=None):
511 if row
== self
.listboxrow_settings_admin
:
512 self
.__popover
_toggle
(self
.popover_admin
)
513 elif row
== self
.listboxrow_settings_macspoof
:
514 self
.__popover
_toggle
(self
.popover_macspoof
)
515 elif row
== self
.listboxrow_settings_network
:
516 self
.__popover
_toggle
(self
.popover_network
)
517 elif row
== self
.listboxrow_settings_camouflage
:
518 self
.__popover
_toggle
(self
.popover_camouflage
)
521 def cb_liststore_filtered_visible_func(self
, model
, treeiter
, searchentry
):
522 search_query
= searchentry
.get_text().lower()
523 value
= model
.get_value(treeiter
, 1).lower()
526 elif search_query
in value
:
531 def cb_popover_text_closed(self
, popover
, user_data
=None):
532 self
.listbox_language
.unselect_all()
535 def cb_popover_keyboard_closed(self
, popover
, user_data
=None):
536 self
.listbox_language
.unselect_all()
539 def cb_popover_formats_closed(self
, popover
, user_data
=None):
540 self
.listbox_language
.unselect_all()
543 def cb_popover_tz_closed(self
, popover
, user_data
=None):
544 self
.listbox_language
.unselect_all()
547 def cb_popover_admin_closed(self
, popover
, user_data
=None):
548 self
.listbox_settings
.unselect_all()
551 def cb_popover_macspoof_closed(self
, popover
, user_data
=None):
552 self
.listbox_settings
.unselect_all()
555 def cb_popover_network_closed(self
, popover
, user_data
=None):
556 self
.listbox_settings
.unselect_all()
559 def cb_popover_camouflage_closed(self
, popover
, user_data
=None):
560 self
.listbox_settings
.unselect_all()
563 def cb_searchentry_formats_search_changed(self
, widget
, user_data
=None):
564 self
.liststore_formats_filtered
.refilter()
567 def cb_searchentry_keyboard_search_changed(self
, widget
, user_data
=None):
568 self
.liststore_keyboard_filtered
.refilter()
571 def cb_searchentry_text_search_changed(self
, widget
, user_data
=None):
572 self
.liststore_text_filtered
.refilter()
575 def cb_searchentry_tz_search_changed(self
, widget
, user_data
=None):
576 self
.liststore_tz_filtered
.refilter()
579 def cb_switch_camouflage_active(self
, switch
, pspec
, user_data
=None):
580 self
.label_settings_camouflage_value
.set_text(
581 self
.__get
_on
_off
_string
(switch
.get_state()))
582 self
.popover_camouflage
.set_visible(False)
584 def cb_switch_macspoof_active(self
, switch
, pspec
, user_data
=None):
585 self
.label_settings_macspoof_value
.set_text(
586 self
.__get
_on
_off
_string
(switch
.get_state()))
587 self
.popover_macspoof
.set_visible(False)
589 def cb_timeout_storage_unlocked(self
, user_data
=None):
590 self
.button_storage_spinner
.set_visible(False)
591 self
.entry_storage_passphrase
.set_visible(False)
592 self
.button_storage_unlock
.set_visible(False)
593 self
.image_storage_state
.set_from_icon_name('tails-unlocked',
595 self
.button_storage_state
.set_visible(True)
596 self
.button_storage_lock
.set_visible(True)
599 def cb_toolbutton_settings_add_clicked(self
, user_data
=None):
600 self
.window_add_setting
.show_all()
603 def cb_toolbutton_settings_remove_clicked(self
, user_data
=None):
605 row
= self
._last
_selected
_setting
_row
.pop()
608 self
.listbox_settings
.remove(row
)
609 self
.listbox_add_setting
.add(row
)
612 def cb_treeview_formats_row_activated(self
, treeview
, path
, column
, user_data
=None):
613 treemodel
= treeview
.get_model()
614 value
= treemodel
.get_value(treemodel
.get_iter(path
), 1)
615 self
.label_formats_value
.set_text(value
)
616 self
.label_language_header_status
.set_text(_("Custom settings"))
617 self
.popover_formats
.set_visible(False)
619 def cb_treeview_keyboard_row_activated(self
, treeview
, path
, column
, user_data
=None):
620 treemodel
= treeview
.get_model()
621 value
= treemodel
.get_value(treemodel
.get_iter(path
), 1)
622 self
.label_keyboard_value
.set_text(value
)
623 self
.label_language_header_status
.set_text(_("Custom settings"))
624 self
.popover_keyboard
.set_visible(False)
626 def cb_treeview_text_row_activated(self
, treeview
, path
, column
, user_data
=None):
627 treemodel
= treeview
.get_model()
628 value
= treemodel
.get_value(treemodel
.get_iter(path
), 1)
629 self
.label_text_value
.set_text(value
)
630 self
.label_language_header_status
.set_text(_("Custom settings"))
631 self
.popover_text
.set_visible(False)
633 def cb_treeview_tz_row_activated(self
, treeview
, path
, column
, user_data
=None):
634 treemodel
= treeview
.get_model()
635 value
= treemodel
.get_value(treemodel
.get_iter(path
), 1)
636 self
.label_tz_value
.set_text(value
)
637 self
.label_language_header_status
.set_text(_("Custom settings"))
638 self
.popover_tz
.set_visible(False)
640 class GreeterBackgroundWindow(Gtk
.ApplicationWindow
):
642 def __init__(self
, app
):
643 Gtk
.Window
.__init
__(self
, title
=APPLICATION_TITLE
, application
=app
)
644 self
.set_icon_name(APPLICATION_ICON_NAME
)
645 self
.override_background_color(
646 Gtk
.StateFlags
.NORMAL
, Gdk
.RGBA(0, 0, 0, 1))
648 class GreeterApplication(Gtk
.Application
):
651 Gtk
.Application
.__init
__(self
)
652 self
.set_application_id
= 'org.boum.tails.greeter'
654 def do_activate(self
):
655 backgroundwindow
= GreeterBackgroundWindow(self
)
656 backgroundwindow
.maximize()
657 appwindow
= GreeterMainWindow(self
)
658 appwindow
.set_transient_for(backgroundwindow
)
660 if not os
.getenv('DEBUG'):
661 backgroundwindow
.show()
664 def do_startup(self
):
665 Gtk
.Application
.do_startup(self
)
667 app
= GreeterApplication()
668 exit_status
= app
.run(sys
.argv
)
669 sys
.exit(exit_status
)