def __init__(self, app): flags = gtk.DIALOG_DESTROY_WITH_PARENT buttons = (gtk.STOCK_REVERT_TO_SAVED, RESPONSE_REVERT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) windowing.Dialog.__init__(self, app=app, title=_('Preferences'), parent=app.drawWindow, flags=flags, buttons=buttons) self.connect('response', self.on_response) self.in_update_ui = False # Set up widgets nb = gtk.Notebook() nb.set_border_width(12) self.vbox.pack_start(nb, expand=True, padding=0) ### Input tab table = gtk.Table(5, 3) table.set_border_width(12) table.set_col_spacing(0, 12) table.set_col_spacing(1, 12) table.set_row_spacings(6) current_row = 0 # TRANSLATORS: Tab label nb.append_page(table, gtk.Label(_('Pen Input'))) xopt = gtk.FILL | gtk.EXPAND yopt = gtk.FILL l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Input Device</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_line_wrap(True) l.set_markup(_('Scale input pressure to brush pressure. This is applied to all input devices. The mouse button has an input pressure of 0.5 when pressed.')) table.attach(l, 1, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 t = gtk.Table(4, 4) self.cv = CurveWidget(self.pressure_curve_changed_cb, magnetic=False) t.attach(self.cv, 0, 3, 0, 3, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 5, 0) l1 = gtk.Label('1.0') if l1.set_angle: # TRANSLATORS: Graph y-axis label l2 = gtk.Label(_('Brush Pressure')) l2.set_angle(90) else: l2 = gtk.Label('') l3 = gtk.Label('0.0') t.attach(l1, 3, 4, 0, 1, 0, 0, 5, 0) t.attach(l2, 3, 4, 1, 2, 0, gtk.EXPAND, 5, 0) t.attach(l3, 3, 4, 2, 3, 0, 0, 5, 0) l4 = gtk.Label('0.0') # TRANSLATORS: Graph x-axis label l5 = gtk.Label(_('Input Pressure')) l5.set_justify(gtk.JUSTIFY_CENTER) l6 = gtk.Label('1.0') t.attach(l4, 0, 1, 3, 4, 0, 0, 5, 0) t.attach(l5, 1, 2, 3, 4, gtk.EXPAND, 0, 5, 0) t.attach(l6, 2, 3, 3, 4, 0, 0, 5, 0) table.attach(t, 1, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label(_('Mode: ')) l.set_alignment(0.0, 0.5) table.attach(l, 1, 2, current_row, current_row + 1, xopt, yopt) combo = self.input_devices_combo = gtk.combo_box_new_text() for m, s in device_modes: combo.append_text(s) combo.connect('changed', self.input_devices_combo_changed_cb) table.attach(combo, 2, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 ### Pointer actions tab assert app.preferences.has_key("input.button_mapping") vbox = gtk.VBox() actions_possible = canvasevent.ModeRegistry.get_action_names() actions_possible = [n for n in actions_possible if issubclass(canvasevent.ModeRegistry.get_mode_class(n), canvasevent.SpringLoadedModeMixin) ] actions_possible += canvasevent.extra_actions self.button_map_editor = ButtonMappingEditor(app=app, bindings=app.preferences["input.button_mapping"], actions_possible=actions_possible) self.button_map_editor.bindings_observers.append( self.button_mapping_editor_bindings_edited_cb) vbox.set_border_width(12) vbox.set_spacing(12) vbox.pack_start(self.button_map_editor, True, True) button_map_label = gtk.Label() button_map_label.set_markup( _("<small>Space can be used like Button2. Note that some pads " "have buttons that cannot be held down.</small>")) vbox.pack_start(button_map_label, False, False) nb.append_page(vbox, gtk.Label(_("Buttons"))) ### Saving tab table = gtk.Table(5, 3) table.set_border_width(12) table.set_col_spacing(0, 12) table.set_col_spacing(1, 12) table.set_row_spacings(6) current_row = 0 nb.append_page(table, gtk.Label(_('Saving'))) xopt = gtk.FILL | gtk.EXPAND yopt = gtk.FILL l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Saving</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label(_('Default file format:')) l.set_alignment(0.0, 0.5) combo = self.defaultsaveformat_combo = gtk.combo_box_new_text() self.defaultsaveformat_values = [filehandling.SAVE_FORMAT_ORA, filehandling.SAVE_FORMAT_PNGSOLID, filehandling.SAVE_FORMAT_JPEG] for saveformat in self.defaultsaveformat_values: format_desc = self.app.filehandler.saveformats[saveformat][0] combo.append_text(format_desc) combo.connect('changed', self.defaultsaveformat_combo_changed_cb) table.attach(l, 1, 2, current_row, current_row + 1, xopt, yopt) table.attach(combo, 2, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Save Next Scrap</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label(_('Path and filename prefix:')) l.set_alignment(0.0, 0.5) self.prefix_entry = gtk.Entry() self.prefix_entry.connect('changed', self.prefix_entry_changed_cb) table.attach(l, 1, 2, current_row, current_row + 1, xopt, yopt) table.attach(self.prefix_entry, 2, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 ### View tab table = gtk.Table(2, 4) table.set_border_width(12) table.set_col_spacing(0, 12) table.set_col_spacing(1, 12) table.set_row_spacings(6) current_row = 0 nb.append_page(table, gtk.Label(_('View'))) xopt = gtk.FILL | gtk.EXPAND yopt = gtk.FILL l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Default View</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label(_('Default zoom:')) l.set_alignment(0.0, 0.5) combo = self.defaultzoom_combo = gtk.combo_box_new_text() # Different from doc.zoomlevel_values because we only want a subset # - keep sorted for bisect self.defaultzoom_values = [0.25, 0.50, 1.0, 2.0] for val in self.defaultzoom_values: combo.append_text('%d%%' % (val*100)) combo.connect('changed', self.defaultzoom_combo_changed_cb) table.attach(l, 1, 2, current_row, current_row + 1, xopt, yopt) table.attach(combo, 2, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 b = self.highqualityzoom_checkbox = gtk.CheckButton(_('High quality zoom (may result in slow scrolling)')) b.connect('toggled', self.highqualityzoom_checkbox_changed_cb) table.attach(b, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Fullscreen</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 b = self.fullscreenhidemenubar_checkbox = gtk.CheckButton(_('Hide menu bar')) b.connect('toggled', self.fullscreenhidemenubar_checkbox_changed_cb) table.attach(b, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 b = self.fullscreenhidetoolbar_checkbox = gtk.CheckButton(_('Hide toolbar')) b.connect('toggled', self.fullscreenhidetoolbar_checkbox_changed_cb) table.attach(b, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 b = self.fullscreenhidesubwindows_checkbox = gtk.CheckButton(_('Hide tools')) b.connect('toggled', self.fullscreenhidesubwindows_checkbox_changed_cb) table.attach(b, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1
class Window(windowing.Dialog): '''Window for manipulating preferences.''' def __init__(self, app): flags = gtk.DIALOG_DESTROY_WITH_PARENT buttons = (gtk.STOCK_REVERT_TO_SAVED, RESPONSE_REVERT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT) windowing.Dialog.__init__(self, app=app, title=_('Preferences'), parent=app.drawWindow, flags=flags, buttons=buttons) self.connect('response', self.on_response) self.in_update_ui = False # Set up widgets nb = gtk.Notebook() nb.set_border_width(12) self.vbox.pack_start(nb, expand=True, padding=0) ### Input tab table = gtk.Table(5, 3) table.set_border_width(12) table.set_col_spacing(0, 12) table.set_col_spacing(1, 12) table.set_row_spacings(6) current_row = 0 # TRANSLATORS: Tab label nb.append_page(table, gtk.Label(_('Pen Input'))) xopt = gtk.FILL | gtk.EXPAND yopt = gtk.FILL l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Input Device</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_line_wrap(True) l.set_markup(_('Scale input pressure to brush pressure. This is applied to all input devices. The mouse button has an input pressure of 0.5 when pressed.')) table.attach(l, 1, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 t = gtk.Table(4, 4) self.cv = CurveWidget(self.pressure_curve_changed_cb, magnetic=False) t.attach(self.cv, 0, 3, 0, 3, gtk.EXPAND | gtk.FILL, gtk.EXPAND | gtk.FILL, 5, 0) l1 = gtk.Label('1.0') if l1.set_angle: # TRANSLATORS: Graph y-axis label l2 = gtk.Label(_('Brush Pressure')) l2.set_angle(90) else: l2 = gtk.Label('') l3 = gtk.Label('0.0') t.attach(l1, 3, 4, 0, 1, 0, 0, 5, 0) t.attach(l2, 3, 4, 1, 2, 0, gtk.EXPAND, 5, 0) t.attach(l3, 3, 4, 2, 3, 0, 0, 5, 0) l4 = gtk.Label('0.0') # TRANSLATORS: Graph x-axis label l5 = gtk.Label(_('Input Pressure')) l5.set_justify(gtk.JUSTIFY_CENTER) l6 = gtk.Label('1.0') t.attach(l4, 0, 1, 3, 4, 0, 0, 5, 0) t.attach(l5, 1, 2, 3, 4, gtk.EXPAND, 0, 5, 0) t.attach(l6, 2, 3, 3, 4, 0, 0, 5, 0) table.attach(t, 1, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label(_('Mode: ')) l.set_alignment(0.0, 0.5) table.attach(l, 1, 2, current_row, current_row + 1, xopt, yopt) combo = self.input_devices_combo = gtk.combo_box_new_text() for m, s in device_modes: combo.append_text(s) combo.connect('changed', self.input_devices_combo_changed_cb) table.attach(combo, 2, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 ### Pointer actions tab assert app.preferences.has_key("input.button_mapping") vbox = gtk.VBox() actions_possible = canvasevent.ModeRegistry.get_action_names() actions_possible = [n for n in actions_possible if issubclass(canvasevent.ModeRegistry.get_mode_class(n), canvasevent.SpringLoadedModeMixin) ] actions_possible += canvasevent.extra_actions self.button_map_editor = ButtonMappingEditor(app=app, bindings=app.preferences["input.button_mapping"], actions_possible=actions_possible) self.button_map_editor.bindings_observers.append( self.button_mapping_editor_bindings_edited_cb) vbox.set_border_width(12) vbox.set_spacing(12) vbox.pack_start(self.button_map_editor, True, True) button_map_label = gtk.Label() button_map_label.set_markup( _("<small>Space can be used like Button2. Note that some pads " "have buttons that cannot be held down.</small>")) vbox.pack_start(button_map_label, False, False) nb.append_page(vbox, gtk.Label(_("Buttons"))) ### Saving tab table = gtk.Table(5, 3) table.set_border_width(12) table.set_col_spacing(0, 12) table.set_col_spacing(1, 12) table.set_row_spacings(6) current_row = 0 nb.append_page(table, gtk.Label(_('Saving'))) xopt = gtk.FILL | gtk.EXPAND yopt = gtk.FILL l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Saving</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label(_('Default file format:')) l.set_alignment(0.0, 0.5) combo = self.defaultsaveformat_combo = gtk.combo_box_new_text() self.defaultsaveformat_values = [filehandling.SAVE_FORMAT_ORA, filehandling.SAVE_FORMAT_PNGSOLID, filehandling.SAVE_FORMAT_JPEG] for saveformat in self.defaultsaveformat_values: format_desc = self.app.filehandler.saveformats[saveformat][0] combo.append_text(format_desc) combo.connect('changed', self.defaultsaveformat_combo_changed_cb) table.attach(l, 1, 2, current_row, current_row + 1, xopt, yopt) table.attach(combo, 2, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Save Next Scrap</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label(_('Path and filename prefix:')) l.set_alignment(0.0, 0.5) self.prefix_entry = gtk.Entry() self.prefix_entry.connect('changed', self.prefix_entry_changed_cb) table.attach(l, 1, 2, current_row, current_row + 1, xopt, yopt) table.attach(self.prefix_entry, 2, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 ### View tab table = gtk.Table(2, 4) table.set_border_width(12) table.set_col_spacing(0, 12) table.set_col_spacing(1, 12) table.set_row_spacings(6) current_row = 0 nb.append_page(table, gtk.Label(_('View'))) xopt = gtk.FILL | gtk.EXPAND yopt = gtk.FILL l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Default View</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label(_('Default zoom:')) l.set_alignment(0.0, 0.5) combo = self.defaultzoom_combo = gtk.combo_box_new_text() # Different from doc.zoomlevel_values because we only want a subset # - keep sorted for bisect self.defaultzoom_values = [0.25, 0.50, 1.0, 2.0] for val in self.defaultzoom_values: combo.append_text('%d%%' % (val*100)) combo.connect('changed', self.defaultzoom_combo_changed_cb) table.attach(l, 1, 2, current_row, current_row + 1, xopt, yopt) table.attach(combo, 2, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 b = self.highqualityzoom_checkbox = gtk.CheckButton(_('High quality zoom (may result in slow scrolling)')) b.connect('toggled', self.highqualityzoom_checkbox_changed_cb) table.attach(b, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 l = gtk.Label() l.set_alignment(0.0, 0.5) l.set_markup(_('<b>Fullscreen</b>')) table.attach(l, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 b = self.fullscreenhidemenubar_checkbox = gtk.CheckButton(_('Hide menu bar')) b.connect('toggled', self.fullscreenhidemenubar_checkbox_changed_cb) table.attach(b, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 b = self.fullscreenhidetoolbar_checkbox = gtk.CheckButton(_('Hide toolbar')) b.connect('toggled', self.fullscreenhidetoolbar_checkbox_changed_cb) table.attach(b, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 b = self.fullscreenhidesubwindows_checkbox = gtk.CheckButton(_('Hide tools')) b.connect('toggled', self.fullscreenhidesubwindows_checkbox_changed_cb) table.attach(b, 0, 3, current_row, current_row + 1, xopt, yopt) current_row += 1 def on_response(self, dialog, response, *args): if response == gtk.RESPONSE_ACCEPT: self.app.save_settings() self.hide() elif response == RESPONSE_REVERT: self.app.load_settings() self.app.apply_settings() def update_ui(self): """Update the preferences window to reflect the current settings.""" if self.in_update_ui: return self.in_update_ui = True p = self.app.preferences self.cv.points = p['input.global_pressure_mapping'] self.prefix_entry.set_text(p['saving.scrap_prefix']) # Device mode mode_config = p.get("input.device_mode", None) mode_idx = i = 0 for mode_name, junk in device_modes: if mode_config == mode_name: mode_idx = i break i += 1 self.input_devices_combo.set_active(mode_idx) zoom = p['view.default_zoom'] zoomlevel = min(bisect_left(self.defaultzoom_values, zoom), len(self.defaultzoom_values) - 1) self.defaultzoom_combo.set_active(zoomlevel) self.fullscreenhidemenubar_checkbox.set_active(p['ui.hide_menubar_in_fullscreen']) self.fullscreenhidetoolbar_checkbox.set_active(p['ui.hide_toolbar_in_fullscreen']) self.fullscreenhidesubwindows_checkbox.set_active(p['ui.hide_subwindows_in_fullscreen']) self.highqualityzoom_checkbox.set_active(p['view.high_quality_zoom']) saveformat_config = p['saving.default_format'] saveformat_idx = self.app.filehandler.config2saveformat[saveformat_config] idx = self.defaultsaveformat_values.index(saveformat_idx) # FIXME: ^^^^^^^^^ try/catch/default may be more tolerant & futureproof self.defaultsaveformat_combo.set_active(idx) # Button mapping self.button_map_editor.set_bindings(p["input.button_mapping"]) # Input curve self.cv.queue_draw() self.in_update_ui = False # Callbacks for widgets that manipulate settings def input_devices_combo_changed_cb(self, widget): i = widget.get_property("active") mode = device_modes[i][0] self.app.preferences['input.device_mode'] = mode self.app.apply_settings() def button_mapping_editor_bindings_edited_cb(self, editor): self.app.button_mapping.update(editor.bindings) def pressure_curve_changed_cb(self, widget): self.app.preferences['input.global_pressure_mapping'] = self.cv.points[:] self.app.apply_settings() def prefix_entry_changed_cb(self, widget): self.app.preferences['saving.scrap_prefix'] = widget.get_text() def defaultzoom_combo_changed_cb(self, widget): zoomlevel = self.defaultzoom_combo.get_active() zoom = self.defaultzoom_values[zoomlevel] self.app.preferences['view.default_zoom'] = zoom def fullscreenhidemenubar_checkbox_changed_cb(self, widget): self.app.preferences['ui.hide_menubar_in_fullscreen'] = bool(widget.get_active()) def fullscreenhidetoolbar_checkbox_changed_cb(self, widget): self.app.preferences['ui.hide_toolbar_in_fullscreen'] = bool(widget.get_active()) def fullscreenhidesubwindows_checkbox_changed_cb(self, widget): self.app.preferences['ui.hide_subwindows_in_fullscreen'] = bool(widget.get_active()) def highqualityzoom_checkbox_changed_cb(self, widget): self.app.preferences['view.high_quality_zoom'] = bool(widget.get_active()) self.app.doc.tdw.queue_draw() def defaultsaveformat_combo_changed_cb(self, widget): idx = self.defaultsaveformat_combo.get_active() saveformat = self.defaultsaveformat_values[idx] # Reverse lookup for key, val in self.app.filehandler.config2saveformat.iteritems(): if val == saveformat: formatstr = key self.app.preferences['saving.default_format'] = formatstr