def make_file_view(self): tv = gtk.TreeView(self.store) self.scrl_win.add(tv) set_props(tv, headers_visible=False) column = gtk.TreeViewColumn() renderer = gtk.CellRendererPixbuf() column.pack_start(renderer, expand=False) column.set_attributes(renderer, stock_id=COLUMN_ICON) renderer = gtk.CellRendererText() renderer.set_property('style', pango.STYLE_ITALIC) column.pack_start(renderer, expand=True) column.set_attributes(renderer, text=COLUMN_NAME, style_set=COLUMN_ITALIC) tv.append_column(column) tv.connect('test_expand_row', self.tree_expand_row) tv.connect('test_collapse_row', self.tree_collapse_row) sel = tv.get_selection() sel.connect('changed', self.select_dentry)
def __init__(self, field_type): gtk.Label.__init__(self) self.set_selectable(True) self.field_type = field_type if field_type.right_justify: set_props(self, xalign=1.0) else: set_props(self, xalign=0.0) self.modify_font(INFO_LABEL_FONT) if hasattr(field_type, 'width_chars'): context = self.get_pango_context() desc = INFO_LABEL_FONT.copy() desc.set_size(context.get_font_description().get_size()) metrics = context.get_metrics(desc, context.get_language()) char_width = metrics.get_approximate_char_width() digit_width = metrics.get_approximate_digit_width() char_pixels = pango.PIXELS(max(char_width, digit_width)) self.set_size_request(char_pixels * field_type.width_chars, -1)
def make_progress_box(self): self.dialog = gtk.Window() set_props(self.dialog, title=self.title, resizable=False, modal=True, type_hint=gtk.gdk.WINDOW_TYPE_HINT_DIALOG) def ignore(w, e): return True self.dialog.connect('delete-event', ignore) self.dialog.set_transient_for(self.parent) vbox = gtk.VBox() set_props(vbox, spacing=0, homogeneous=False, border_width=4, parent=self.dialog) label = gtk.Label(self.desc + '...') vbox.pack_start(label, expand=False, fill=False) self.pbar = gtk.ProgressBar() vbox.pack_start(self.pbar, expand=False, fill=False) self.dialog.show_all()
def main(): import types widgets = [] symbols = globals() for class_type in symbols.itervalues(): if isinstance(class_type, types.TypeType) and hasattr(class_type, 'label'): widgets.append(class_type) def dummy(*args): gtk.main_quit() window = gtk.Window() window.connect('delete_event', dummy) table = gtk.Table(rows=len(widgets), columns=2) set_props(table, row_spacing=4, column_spacing=4, border_width=4, parent=window) for row, widget_type in enumerate(widgets): label = gtk.Label() label.set_text_with_mnemonic(widget_type.label + ':') set_props(label, xalign=1.0) table.attach(label, 0, 1, row, row + 1) widget = widget_type() table.attach(widget, 1, 2, row, row + 1) window.show_all() gtk.main()
def about(parent): import gtk from guiutil import set_props if gtk.pygtk_version >= (2,6,0): copyright = 'Copyright (C) 2002, 2007 Oracle. All rights reserved.' license = ''' This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ''' blurb = 'GUI frontend for OCFS2 management' #logo = gtk.gdk.pixbuf_new_from_file('logo.png') dialog = gtk.AboutDialog() dialog.set_transient_for(parent) dialog.set_destroy_with_parent(True) set_props(dialog, name='OCFS2 Console', version=OCFS2TOOLS_VERSION, copyright=copyright, license=license, website='http://oss.oracle.com', comments=blurb) #logo=logo) else: dialog = gtk.MessageDialog(parent=parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=gtk.BUTTONS_CLOSE) dialog.label.set_text( '''OCFS2 Console Version %s Copyright (C) 2002, 2005 Oracle. All Rights Reserved.''' % OCFS2TOOLS_VERSION) dialog.run() dialog.destroy()
def about(parent): import gtk from guiutil import set_props if gtk.pygtk_version >= (2, 6, 0): copyright = 'Copyright (C) 2002, 2007 Oracle. All rights reserved.' license = ''' This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. ''' blurb = 'GUI frontend for OCFS2 management' #logo = gtk.gdk.pixbuf_new_from_file('logo.png') dialog = gtk.AboutDialog() dialog.set_transient_for(parent) dialog.set_destroy_with_parent(True) set_props(dialog, name='OCFS2 Console', version=OCFS2TOOLS_VERSION, copyright=copyright, license=license, website='http://oss.oracle.com', comments=blurb) #logo=logo) else: dialog = gtk.MessageDialog(parent=parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=gtk.BUTTONS_CLOSE) dialog.label.set_text('''OCFS2 Console Version %s Copyright (C) 2002, 2005 Oracle. All Rights Reserved.''' % OCFS2TOOLS_VERSION) dialog.run() dialog.destroy()
def query_mount(parent, device): default_mountpoint, default_options = get_defaults(device) dialog = gtk.Dialog(parent=parent, flags=gtk.DIALOG_DESTROY_WITH_PARENT, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) table = gtk.Table(rows=2, columns=2) set_props(table, row_spacing=6, column_spacing=6, border_width=6, parent=dialog.vbox) def text_changed(entry): text = entry.get_text() valid = len(text) > 1 and text.startswith('/') dialog.set_response_sensitive(gtk.RESPONSE_OK, valid) mountpoint = gtk.Entry() mountpoint.connect('changed', text_changed) mountpoint.set_text(default_mountpoint) text_changed(mountpoint) options = gtk.Entry() options.set_text(default_options) row = 0 for prompt, entry in (('_Mountpoint', mountpoint), ('O_ptions', options)): label = gtk.Label() label.set_text_with_mnemonic(prompt + ':') set_props(label, xalign=0.0) table.attach(label, 0, 1, row, row + 1) entry.set_activates_default(True) label.set_mnemonic_widget(entry) table.attach(entry, 1, 2, row, row + 1) row = row + 1 dialog.show_all() if dialog.run() == gtk.RESPONSE_OK: mount_params = mountpoint.get_text(), options.get_text() else: mount_params = None, None dialog.destroy() return mount_params
def __init__(self, device=None): gtk.Table.__init__(self, rows=5, columns=2) set_props(self, row_spacing=4, column_spacing=4, border_width=4) fs = super = dinode = None if device: try: fs = ocfs2.Filesystem(device) super = fs.fs_super blkno = fs.lookup_system_inode(ocfs2.GLOBAL_BITMAP_SYSTEM_INODE) dinode = fs.read_cached_inode(blkno) except ocfs2.error: pass for row, field_type in enumerate(fields): field = field_type(fs, super, dinode) label = gtk.Label(field.label + ':') set_props(label, xalign=1.0) self.attach(label, 0, 1, row, row + 1, xoptions=gtk.FILL, yoptions=gtk.FILL) label = gtk.Label(field.text) set_props(label, xalign=0.0) self.attach(label, 1, 2, row, row + 1, xoptions=gtk.FILL, yoptions=gtk.FILL)
def make_ls_fields(self): table = gtk.Table(rows=2, columns=7) set_props(table, row_spacing=4, column_spacing=4, border_width=4) self.pack_end(table, expand=False, fill=False) self.info_labels = [] for column, field in enumerate(fields): label = gtk.Label(field.label) if field.right_justify: set_props(label, xalign=1.0) else: set_props(label, xalign=0.0) xoptions = yoptions = gtk.FILL xpadding = 2 table.attach(label, column, column + 1, 0, 1, xoptions, yoptions, xpadding) label = InfoLabel(field) table.attach(label, column, column + 1, 1, 2, xoptions, yoptions, xpadding) self.info_labels.append(label)
def __init__(self, device=None): self.device = device gtk.VBox.__init__(self, spacing=4) label = gtk.Label('/') set_props(label, xalign=0.0, selectable=True, wrap=True) self.pack_start(label, expand=False) self.path_label = label self.scrl_win = gtk.ScrolledWindow() self.scrl_win.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) self.add(self.scrl_win) self.make_dentry_store() self.make_file_view() self.make_ls_fields() self.connect('destroy', self.destroy_handler) self.refresh()
def main(): import types widgets = [] symbols = globals() for class_type in symbols.itervalues(): if isinstance(class_type, types.TypeType) and hasattr( class_type, 'label'): widgets.append(class_type) def dummy(*args): gtk.main_quit() window = gtk.Window() window.connect('delete_event', dummy) table = gtk.Table(rows=len(widgets), columns=2) set_props(table, row_spacing=4, column_spacing=4, border_width=4, parent=window) for row, widget_type in enumerate(widgets): label = gtk.Label() label.set_text_with_mnemonic(widget_type.label + ':') set_props(label, xalign=1.0) table.attach(label, 0, 1, row, row + 1) widget = widget_type() table.attach(widget, 1, 2, row, row + 1) window.show_all() gtk.main()
def __init__(self, device=None): gtk.Table.__init__(self, rows=5, columns=2) set_props(self, row_spacing=4, column_spacing=4, border_width=4) fs = super = dinode = None if device: try: fs = ocfs2.Filesystem(device) super = fs.fs_super blkno = fs.lookup_system_inode( ocfs2.GLOBAL_BITMAP_SYSTEM_INODE) dinode = fs.read_cached_inode(blkno) except ocfs2.error: pass for row, field_type in enumerate(fields): field = field_type(fs, super, dinode) label = gtk.Label(field.label + ':') set_props(label, xalign=1.0) self.attach(label, 0, 1, row, row + 1, xoptions=gtk.FILL, yoptions=gtk.FILL) label = gtk.Label(field.text) set_props(label, xalign=0.0) self.attach(label, 1, 2, row, row + 1, xoptions=gtk.FILL, yoptions=gtk.FILL)
def node_query(self, title='Node Attributes', defaults=None, editing=False): existing_names = {} existing_ip_addrs = {} for row in self.store: name = row[COLUMN_NAME] ip_addr = row[COLUMN_IP_ADDRESS] if not (editing and name == defaults[COLUMN_NAME]): existing_names[name] = 1 if not (editing and ip_addr == defaults[COLUMN_IP_ADDRESS]): existing_ip_addrs[ip_addr] = name dialog = Dialog(parent=self, title=title, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order( (gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=4, columns=2) set_props(table, row_spacing=4, column_spacing=4, border_width=4, parent=dialog.vbox) widgets = [] for row, field in enumerate(fields): if field.widget_type is None: widgets.append(None) continue label = gtk.Label(field.title + ':') set_props(label, xalign=1.0) table.attach(label, 0, 1, row, row + 1) widget = field.widget_type() table.attach(widget, 1, 2, row, row + 1) if field.column == COLUMN_NAME: widget.set_max_length(o2cb.O2NM_MAX_NAME_LEN) elif field.column == COLUMN_IP_PORT: widget.set_numeric(True) adjustment = gtk.Adjustment(PORT_DEFAULT, PORT_MINIMUM, PORT_MAXIMUM, 1, 100) widget.set_adjustment(adjustment) widget.set_value(PORT_DEFAULT) widgets.append(widget) if defaults: for w, d in zip(widgets, defaults): if w and d: w.set_text(d) dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return None ip_port = widgets[COLUMN_IP_PORT].get_text() name = widgets[COLUMN_NAME].get_text() if not name: error_box(dialog, 'Node name not specified') continue try: ip_addr = widgets[COLUMN_IP_ADDRESS].get_text() except (IPMissing, IPError), msg: error_box(dialog, msg[0]) continue if name in existing_names: error_box(dialog, 'Node %s already exists in the configuration' % name) elif ip_addr in existing_ip_addrs: error_box( dialog, 'IP %s is already assigned to node %s' % (ip_addr, existing_ip_addrs[ip_addr])) else: break
def __init__(self): gtk.Window.__init__(self) set_props(self, title='OCFS2 Console', default_width=600, default_height=460, border_width=0) self.connect('delete_event', self.cleanup) notebook = gtk.Notebook() notebook.set_tab_pos(gtk.POS_TOP) info_frames = [] for desc, info in info_items: frame = gtk.Frame() set_props(frame, shadow=gtk.SHADOW_NONE, border_width=0) notebook.add_with_properties(frame, 'tab_label', desc) info_frames.append((frame, info)) self.pv = PartitionView(info_frames) self.pv.set_size_request(-1, 100) vbox = gtk.VBox() self.add(vbox) menu = Menu(self) menubar, sel_items, unmounted_items = menu.get_widgets() vbox.pack_start(menubar, expand=False, fill=False) self.pv.add_sel_widgets(sel_items) self.pv.add_unmount_widgets(unmounted_items) toolbar = Toolbar(self) tb, buttons, filter_entry = toolbar.get_widgets() vbox.pack_start(tb, expand=False, fill=False) self.pv.add_mount_widgets([buttons['unmount']]) self.pv.add_unmount_widgets([buttons['mount']]) filter_entry.connect('activate', self.refresh) self.pv.set_filter_entry(filter_entry) vpaned = gtk.VPaned() vpaned.set_border_width(4) vbox.pack_start(vpaned, expand=True, fill=True) scrl_win = gtk.ScrolledWindow() set_props(scrl_win, hscrollbar_policy=gtk.POLICY_AUTOMATIC, vscrollbar_policy=gtk.POLICY_AUTOMATIC) scrl_win.add(self.pv) vpaned.pack1(scrl_win) vpaned.pack2(notebook) self.pv.grab_focus() self.show_all() self.refresh()
def format_partition(parent, device): partitions = [] def add_partition(device, fstype): partitions.append((device, fstype)) partition_list(add_partition, unmounted=True) if not partitions: error_box(parent, 'No unmounted partitions') return False def sort_partition(x, y): return cmp(x[0], y[0]) partitions.sort(sort_partition) dialog = Dialog(parent=parent, title='Format', buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=5, columns=2) set_props(table, row_spacing=6, column_spacing=6, border_width=6, parent=dialog.vbox) widgets = [] for row, widget_type in enumerate(entries): widget = widget_type() label = gtk.Label() label.set_text_with_mnemonic(widget_type.label + ':') label.set_mnemonic_widget(widget) set_props(label, xalign=0.0) table.attach(label, 0, 1, row, row + 1) if widget_type == Device: widget.fill(partitions, device) if isinstance(widget, gtk.Entry): widget.set_activates_default(True) if isinstance(widget, gtk.SpinButton): attach_widget = gtk.HBox() attach_widget.pack_start(widget, expand=False, fill=False) else: attach_widget = widget table.attach(attach_widget, 1, 2, row, row + 1) widgets.append(widget) widgets[0].grab_focus() dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return False dev = widgets[0].get_device() msg = 'Are you sure you want to format %s?' % dev ask = gtk.MessageDialog(parent=dialog, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format=msg) if ask.run() == gtk.RESPONSE_YES: break else: ask.destroy() command = list(base_command) for widget in widgets[1:]: arg = widget.get_arg() if arg: command.extend(arg) command.append(dev) dialog.destroy() mkfs = Process(command, 'Format', 'Formatting...', parent, spin_now=True) success, output, k = mkfs.reap() if not success: error_box(parent, 'Format error: %s' % output) return False return True
def tune_action(widget_type, parent, device): try: widget = widget_type(device) except ocfs2.error: desc = widget_type.label.replace('_', '') desc = desc.lower() error_box(parent, 'Could not get current %s for device %s' % (desc, device)) return False dialog = Dialog(parent=parent, title=widget_type.title, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=1, columns=2) set_props(table, row_spacing=6, column_spacing=6, border_width=6, parent=dialog.vbox) label = gtk.Label() label.set_text_with_mnemonic(widget_type.label + ':') set_props(label, xalign=0.0) table.attach(label, 0, 1, 0, 1) label.set_mnemonic_widget(widget) table.attach(widget, 1, 2, 0, 1) if isinstance(widget, gtk.Entry): widget.set_activates_default(True) widget.grab_focus() dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return False new_label = widget.get_text() if not new_label: if widget_type.empty_ok: msg = ('Are you sure you want to clear the %s on %s?' % (widget_type.lower(), device)) ask = gtk.MessageDialog(parent=dialog, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format=msg) if ask.run() == gtk.RESPONSE_YES: break else: ask.destroy() else: error_box( dialog, '%s cannot be empty.' % widget_type.lower().ucfirst()) else: break command = list(base_command) command.extend(widget.get_arg()) command.append(device) dialog.destroy() tunefs = Process(command, widget_type.title, widget_type.action + '...', parent, spin_now=True) success, output, k = tunefs.reap() if not success: error_box(parent, 'File system tune error: %s' % output) return False return True
def __init__(self, cluster_name=DEFAULT_CLUSTER_NAME, parent=None): self.cluster_name = cluster_name Dialog.__init__(self, parent=parent, title='Node Configuration', buttons=(gtk.STOCK_APPLY, gtk.RESPONSE_APPLY, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE)) if parent is None: self.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL) frame = gtk.Frame() frame.set_shadow_type(gtk.SHADOW_NONE) self.vbox.add(frame) label = gtk.Label() label.set_text_with_mnemonic('_Nodes:') frame.set_label_widget(label) hbox = gtk.HBox(spacing=4) hbox.set_border_width(4) frame.add(hbox) scrl_win = gtk.ScrolledWindow() scrl_win.set_policy(hscrollbar_policy=gtk.POLICY_AUTOMATIC, vscrollbar_policy=gtk.POLICY_AUTOMATIC) hbox.pack_start(scrl_win) self.setup_treeview() label.set_mnemonic_widget(self.tv) scrl_win.add(self.tv) vbbox = gtk.VButtonBox() set_props(vbbox, layout_style=gtk.BUTTONBOX_START, spacing=5, border_width=5) hbox.pack_end(vbbox, expand=False, fill=False) self.add_button = gtk.Button(stock=gtk.STOCK_ADD) self.add_button.connect('clicked', self.add_node) vbbox.add(self.add_button) try: edit_construct_args = {'stock': gtk.STOCK_EDIT} except AttributeError: edit_construct_args = {'label': '_Edit'} self.edit_button = gtk.Button(**edit_construct_args) self.edit_button.connect('clicked', self.edit_node) vbbox.add(self.edit_button) self.remove_button = gtk.Button(stock=gtk.STOCK_REMOVE) self.remove_button.connect('clicked', self.remove_node) vbbox.add(self.remove_button) self.can_edit(False) self.can_apply(False) self.sel = self.tv.get_selection() self.sel.connect('changed', self.on_select) self.tv.connect('row_activated', self.on_row_activated) self.load_cluster_state()
def tune_action(widget_type, parent, device): try: widget = widget_type(device) except ocfs2.error: desc = widget_type.label.replace('_', '') desc = desc.lower() error_box(parent, 'Could not get current %s for device %s' % (desc, device)) return False dialog = Dialog(parent=parent, title=widget_type.title, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=1, columns=2) set_props(table, row_spacing=6, column_spacing=6, border_width=6, parent=dialog.vbox) label = gtk.Label() label.set_text_with_mnemonic(widget_type.label + ':') set_props(label, xalign=0.0) table.attach(label, 0, 1, 0, 1) label.set_mnemonic_widget(widget) table.attach(widget, 1, 2, 0, 1) if isinstance(widget, gtk.Entry): widget.set_activates_default(True) widget.grab_focus() dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return False new_label = widget.get_text() if not new_label: if widget_type.empty_ok: msg = ('Are you sure you want to clear the %s on %s?' % (widget_type.lower(), device)) ask = gtk.MessageDialog(parent=dialog, flags=gtk.DIALOG_DESTROY_WITH_PARENT, type=gtk.MESSAGE_QUESTION, buttons=gtk.BUTTONS_YES_NO, message_format=msg) if ask.run() == gtk.RESPONSE_YES: break else: ask.destroy() else: error_box(dialog, '%s cannot be empty.' % widget_type.lower().ucfirst()) else: break command = list(base_command) command.extend(widget.get_arg()) command.append(device) dialog.destroy() tunefs = Process(command, widget_type.title, widget_type.action + '...', parent, spin_now=True) success, output, k = tunefs.reap() if not success: error_box(parent, 'File system tune error: %s' % output) return False return True
def node_query(self, title='Node Attributes', defaults=None, editing=False): existing_names = {} existing_ip_addrs = {} for row in self.store: name = row[COLUMN_NAME] ip_addr = row[COLUMN_IP_ADDRESS] if not (editing and name == defaults[COLUMN_NAME]): existing_names[name] = 1 if not (editing and ip_addr == defaults[COLUMN_IP_ADDRESS]): existing_ip_addrs[ip_addr] = name dialog = Dialog(parent=self, title=title, buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_OK, gtk.RESPONSE_OK)) dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL)) dialog.set_default_response(gtk.RESPONSE_OK) table = gtk.Table(rows=4, columns=2) set_props(table, row_spacing=4, column_spacing=4, border_width=4, parent=dialog.vbox) widgets = [] for row, field in enumerate(fields): if field.widget_type is None: widgets.append(None) continue label = gtk.Label(field.title + ':') set_props(label, xalign=1.0) table.attach(label, 0, 1, row, row + 1) widget = field.widget_type() table.attach(widget, 1, 2, row, row + 1) if field.column == COLUMN_NAME: widget.set_max_length(o2cb.O2NM_MAX_NAME_LEN) elif field.column == COLUMN_IP_PORT: widget.set_numeric(True) adjustment = gtk.Adjustment(PORT_DEFAULT, PORT_MINIMUM, PORT_MAXIMUM, 1, 100) widget.set_adjustment(adjustment) widget.set_value(PORT_DEFAULT) widgets.append(widget) if defaults: for w, d in zip(widgets, defaults): if w and d: w.set_text(d) dialog.show_all() while 1: if dialog.run() != gtk.RESPONSE_OK: dialog.destroy() return None ip_port = widgets[COLUMN_IP_PORT].get_text() name = widgets[COLUMN_NAME].get_text() if not name: error_box(dialog, 'Node name not specified') continue try: ip_addr = widgets[COLUMN_IP_ADDRESS].get_text() except (IPMissing, IPError), msg: error_box(dialog, msg[0]) continue if name in existing_names: error_box(dialog, 'Node %s already exists in the configuration' % name) elif ip_addr in existing_ip_addrs: error_box(dialog, 'IP %s is already assigned to node %s' % (ip_addr, existing_ip_addrs[ip_addr])) else: break