4
from gettext import gettext as _
3
6
from gi.repository import GObject, Gtk
5
8
from landscape.ui.constants import (
6
9
CANONICAL_MANAGED, LOCAL_MANAGED, NOT_MANAGED)
11
# Note, I think this may not be fully compliant with the changes in RFC 1123
12
HOST_NAME_REGEXP = re.compile("^(([a-zA-Z][a-zA-Z0-9\-]*)?[a-zA-Z0-9][\.]?)*"
13
"(([A-Za-z][A-Za-z0-9\-]*)?[A-Za-z0-9])$")
16
def sanitise_host_name(host_name):
18
Do some minimal host name sanitation.
20
return host_name.strip()
23
def is_valid_host_name(host_name):
25
Check that the provided host name complies with L{HOST_NAME_REGEXP} and is
28
return HOST_NAME_REGEXP.match(host_name) is not None
33
Test that the provided string contains only characters from the ASCII set.
38
except UnicodeDecodeError:
9
42
class ClientSettingsDialog(Gtk.Dialog):
16
49
GLADE_FILE = "landscape-client-settings.glade"
17
NO_SERVICE_TEXT = "None"
18
HOSTED_SERVICE_TEXT = "Landscape - hosted by Canonical"
19
LOCAL_SERVICE_TEXT = "Landscape - dedicated server"
20
REGISTER_BUTTON_TEXT = "Register"
21
DISABLE_BUTTON_TEXT = "Disable"
23
53
def __init__(self, controller):
24
54
super(ClientSettingsDialog, self).__init__(
25
title="Management Service",
55
title=_("Management Service"),
26
56
flags=Gtk.DialogFlags.MODAL)
27
57
self.set_default_icon_name("preferences-management-service")
28
58
self.set_resizable(False)
29
59
self._initialised = False
60
self._validation_errors = set()
61
self._errored_entries = []
30
62
self.controller = controller
33
65
# One extra revert to reset after loading data
34
66
self.controller.revert()
68
def indicate_error_on_entry(self, entry):
70
Show a warning icon on a L{Gtk.Entry} to indicate some associated
73
entry.set_icon_from_stock(
74
Gtk.EntryIconPosition.PRIMARY, Gtk.STOCK_DIALOG_WARNING)
75
self._errored_entries.append(entry)
77
def check_local_landscape_host_name_entry(self):
78
host_name = sanitise_host_name(
79
self.local_landscape_host_entry.get_text())
80
ascii_ok = is_ascii(host_name)
81
host_name_ok = is_valid_host_name(host_name)
82
if ascii_ok and host_name_ok:
83
self.local_landscape_host_entry.set_text(host_name)
86
self.indicate_error_on_entry(self.local_landscape_host_entry)
88
self._validation_errors.add(self.INVALID_HOST_NAME)
90
self._validation_errors.add(self.UNICODE_IN_ENTRY)
93
def check_entry(self, entry):
95
Check that the text content of a L{Gtk.Entry} is acceptable.
97
if is_ascii(entry.get_text()):
100
self.indicate_error_on_entry(entry)
101
self._validation_errors.add(self.UNICODE_IN_ENTRY)
104
def validity_check(self):
105
self._validation_errors = set()
106
if self._info_bar_container.get_visible():
107
self.dismiss_infobar(None)
108
active_iter = self.liststore.get_iter(
109
self.use_type_combobox.get_active())
110
[management_type] = self.liststore.get(active_iter, 0)
111
if management_type == NOT_MANAGED:
113
elif management_type == CANONICAL_MANAGED:
114
account_name_ok = self.check_entry(self.hosted_account_name_entry)
115
password_ok = self.check_entry(self.hosted_password_entry)
116
return account_name_ok and password_ok
118
host_name_ok = self.check_local_landscape_host_name_entry()
119
password_ok = self.check_entry(self.local_password_entry)
120
return host_name_ok and password_ok
123
def NO_SERVICE_TEXT(self):
127
def HOSTED_SERVICE_TEXT(self):
128
return _("Landscape - hosted by Canonical")
131
def LOCAL_SERVICE_TEXT(self):
132
return _("Landscape - dedicated server")
135
def REGISTER_BUTTON_TEXT(self):
139
def DISABLE_BUTTON_TEXT(self):
143
def INVALID_HOST_NAME_MESSAGE(self):
144
return _("Invalid host name.")
147
def UNICODE_IN_ENTRY_MESSAGE(self):
148
return _("Only ASCII characters are allowed.")
36
150
def _set_use_type_combobox_from_controller(self):
38
152
Load the persisted L{management_type} from the controller and set the
123
237
self.response(Gtk.ResponseType.CANCEL)
125
239
def register_response(self, widget):
126
self.response(Gtk.ResponseType.OK)
240
if self.validity_check():
241
self.response(Gtk.ResponseType.OK)
244
if self.UNICODE_IN_ENTRY in self._validation_errors:
245
error_text.append(self.UNICODE_IN_ENTRY_MESSAGE)
246
if self.INVALID_HOST_NAME in self._validation_errors:
247
error_text.append(self.INVALID_HOST_NAME_MESSAGE)
248
self.info_message.set_text("\n".join(error_text))
249
self._info_bar_container.show()
128
251
def set_button_text(self, management_type):
129
252
[alignment] = self.register_button.get_children()
148
271
self.register_button.show()
149
272
self.register_button.connect("clicked", self.register_response)
274
def dismiss_infobar(self, widget):
275
self._info_bar_container.hide()
276
for entry in self._errored_entries:
277
entry.set_icon_from_stock(Gtk.EntryIconPosition.PRIMARY, None)
278
self._errored_entries = []
280
def setup_info_bar(self):
281
labels_size_group = self._builder.get_object("labels-sizegroup")
282
entries_size_group = self._builder.get_object("entries-sizegroup")
283
labels_size_group.set_ignore_hidden(False)
284
entries_size_group.set_ignore_hidden(False)
285
self._info_bar_container = Gtk.HBox()
286
self._info_bar_container.set_spacing(12)
287
info_bar = Gtk.InfoBar()
288
entries_size_group.add_widget(info_bar)
290
empty_label = Gtk.Label()
291
labels_size_group.add_widget(empty_label)
293
self._info_bar_container.pack_start(empty_label, expand=False,
294
fill=False, padding=0)
295
self._info_bar_container.pack_start(info_bar, expand=False, fill=False,
297
content_area = info_bar.get_content_area()
299
self.info_message = Gtk.Label()
300
self.info_message.set_alignment(0, 0.5)
301
self.info_message.show()
302
hbox.pack_start(self.info_message, expand=True, fill=True, padding=6)
303
ok_button = Gtk.Button("Dismiss")
304
ok_button.connect("clicked", self.dismiss_infobar)
306
hbox.pack_start(ok_button, expand=True, fill=True, padding=0)
308
content_area.pack_start(hbox, expand=True, fill=True, padding=0)
151
310
def setup_ui(self):
152
311
self._builder = Gtk.Builder()
312
self._builder.set_translation_domain("landscape-client")
153
313
self._builder.add_from_file(
155
315
os.path.dirname(__file__), "ui", self.GLADE_FILE))
156
316
content_area = self.get_content_area()
157
317
content_area.set_spacing(12)
158
318
self.set_border_width(12)
319
self.setup_info_bar()
159
320
self._vbox = self._builder.get_object("toplevel-vbox")
160
321
self._vbox.unparent()
161
content_area.pack_start(self._vbox, expand=True, fill=True, padding=12)
322
content_area.pack_start(self._vbox, expand=True, fill=True,
324
self._vbox.pack_start(self._info_bar_container, expand=False,
325
fill=False, padding=0)
162
326
self.liststore = self.make_liststore()
163
327
self.link_use_type_combobox(self.liststore)
164
328
self.link_hosted_service_widgets()