def __init__(self, ui, default_tab=None, select_plugin=None): Dialog.__init__(self, ui, _('Preferences')) # T: Dialog title gtknotebook = gtk.Notebook() self.vbox.add(gtknotebook) # saves a list of loaded plugins to be used later self.p_save_loaded = [p.__class__ for p in self.ui.plugins] # Dynamic tabs self.forms = {} for category, preferences in ui.preferences_register.items(): vbox = gtk.VBox() index = gtknotebook.append_page(vbox, gtk.Label(_(category))) # From GTK Doc: Note that due to historical reasons, GtkNotebook refuses # to switch to a page unless the child widget is visible. vbox.show() if category == default_tab: gtknotebook.set_current_page(index) fields = [] values = {} sections = {} for p in preferences: if len(p) == 4: section, key, type, label = p fields.append((key, type, label)) else: section, key, type, label, check = p fields.append((key, type, label, check)) values[key] = ui.preferences[section][key] sections[key] = section form = InputForm(fields, values) form.preferences_sections = sections vbox.pack_start(form, False) self.forms[category] = form if category == 'Interface': self._add_font_selection(form) # Styles tab #~ gtknotebook.append_page(StylesTab(self), gtk.Label(_('Styles'))) # Keybindings tab #~ gtknotebook.append_page(KeyBindingsTab(self), gtk.Label(_('Key bindings'))) # Plugins tab plugins_tab = PluginsTab(self, self.ui.plugins) plugins_tab_index = gtknotebook.append_page(plugins_tab, gtk.Label(_('Plugins'))) # T: Heading in preferences dialog plugins_tab.show() #~ print default_tab, index if default_tab == "Plugins": gtknotebook.set_current_page(plugins_tab_index) if not select_plugin is None: plugins_tab.select_plugin(select_plugin) # Applications tab gtknotebook.append_page(ApplicationsTab(self), gtk.Label(_('Applications')))
class TicketDialog(Dialog): def __init__(self, ui, notebook, pageview): self.notebook = notebook self.bt = notebook.bt self.pageview = pageview self.ui = ui Dialog.__init__( self, ui, _('Insert Ticket ID'), # T: Dialog title button=(_('_Insert'), 'gtk-ok'), # T: Button label defaultwindowsize=(245, 120) ) self.form = InputForm(notebook=notebook) self.vbox.pack_start(self.form, False) self.form.add_inputs(( ('ticket', 'string', _('ID')), # T: Ticket ID )) # Register global dielog key-press event, which is called for every input self.add_events(gtk.gdk.KEY_PRESS_MASK) self.connect('key-press-event', self.on_dialog_key_press) def on_dialog_key_press(self, dialog, event): # Close dialog on enter click if event.keyval == gtk.keysyms.Return: dialog.response(gtk.RESPONSE_OK) return True def do_response_ok(self): self.bt.setup_config(self.notebook.preferences) # get the ticket ID and prevent changes during http request input = self.form.widgets.get('ticket') input.set_editable(False) ticket = input.get_text() self.do_close(self) # by empty string do nothing if not ticket: return True try: # Do Request to web page an set the response data formatted at cursor position ticket_data = self.bt.get_ticket_data(ticket) buffer = self.pageview.view.get_buffer() buffer.insert_link_at_cursor(ticket_data['ticket'], ticket_data['url']) buffer.insert_at_cursor(" " + ticket_data['title'] + "\n") except RequestError as e: MessageDialog(self, e.message).run() return True
def __init__(self, ui, notebook=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): self.config = get_config('quicknote.conf') self.uistate = self.config['QuickNoteDialog'] Dialog.__init__(self, ui, _('Quick Note')) self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments if notebook and not isinstance(notebook, basestring): notebook = notebook.uri self.uistate.setdefault('lastnotebook', None, basestring) if self.uistate['lastnotebook']: notebook = notebook or self.uistate['lastnotebook'] self.config['Namespaces'].setdefault(notebook, None, basestring) namespace = namespace or self.config['Namespaces'][notebook] self.form = InputForm() self.vbox.pack_start(self.form, False) # TODO dropdown could use an option "Other..." label = gtk.Label(_('Notebook')+': ') label.set_alignment(0.0, 0.5) self.form.attach(label, 0,1, 0,1, xoptions=gtk.FILL) # T: Field to select Notebook from drop down list self.notebookcombobox = NotebookComboBox(current=notebook) self.notebookcombobox.connect('changed', self.on_notebook_changed) self.form.attach(self.notebookcombobox, 1,2, 0,1) self._init_inputs(namespace, basename, append, text, template_options) self.uistate['lastnotebook'] = notebook self._set_autocomplete(notebook)
class PropertiesDialog(Dialog): def __init__(self, parent, config, notebook): Dialog.__init__(self, parent, _('Properties'), help='Help:Properties') # T: Dialog title self.notebook = notebook self.config = config stack = Gtk.Stack() sidebar = Gtk.StackSidebar() sidebar.set_stack(stack) hbox = Gtk.Box() hbox.add(sidebar) hbox.add(stack) self.vbox.add(hbox) self.form = InputForm(inputs=notebook_properties, values=notebook.config['Notebook']) self.form.widgets['icon'].set_use_relative_paths(self.notebook) if self.notebook.readonly: for widget in list(self.form.widgets.values()): widget.set_sensitive(False) stack.add_titled(self.form, 'notebook', _('Notebook')) self.plugin_forms = {} plugins = get_window(parent).__pluginmanager__ # XXX for name in plugins: plugin = plugins[name] if plugin.plugin_notebook_properties: key = plugin.config_key form = InputForm(inputs=plugin.form_fields( plugin.plugin_notebook_properties), values=notebook.config[key]) self.plugin_forms[key] = form if self.notebook.readonly: for widget in list(form.widgets.values()): widget.set_sensitive(False) box = Gtk.VBox() box.pack_start(form, False, False, 0) stack.add_titled(box, name, plugin.plugin_info['name']) def do_response_ok(self): if not self.notebook.readonly: properties = self.form.copy() # XXX this should be part of notebook.save_properties # which means notebook should also own a ref to the ConfigManager if 'profile' in properties and properties[ 'profile'] != self.notebook.profile: assert isinstance(properties['profile'], (str, type(None))) self.config.set_profile(properties['profile']) self.notebook.save_properties(**properties) for key, form in self.plugin_forms.items(): self.notebook.config[key].update(form) return True
def __init__(self, window, notebook=None, page=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): assert page is None, 'TODO' manager = ConfigManager() # FIXME should be passed in self.config = manager.get_config_dict('quicknote.conf') self.uistate = self.config['QuickNoteDialog'] Dialog.__init__(self, window, _('Quick Note')) self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments if notebook and not isinstance(notebook, str): notebook = notebook.uri self.uistate.setdefault('lastnotebook', None, str) if self.uistate['lastnotebook']: notebook = notebook or self.uistate['lastnotebook'] self.config['Namespaces'].setdefault(notebook, None, str) namespace = namespace or self.config['Namespaces'][notebook] self.form = InputForm() self.vbox.pack_start(self.form, False, True, 0) # TODO dropdown could use an option "Other..." label = Gtk.Label(label=_('Notebook') + ': ') label.set_alignment(0.0, 0.5) self.form.attach(label, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL) # T: Field to select Notebook from drop down list self.notebookcombobox = NotebookComboBox(current=notebook) self.notebookcombobox.connect('changed', self.on_notebook_changed) self.form.attach(self.notebookcombobox, 1, 2, 0, 1) self._init_inputs(namespace, basename, append, text, template_options) self.uistate['lastnotebook'] = notebook self._set_autocomplete(notebook)
class PropertiesDialog(Dialog): def __init__(self, parent, notebook): Dialog.__init__(self, parent, _('Properties'), help='Help:Properties') # T: Dialog title self.notebook = notebook stack = Gtk.Stack() sidebar = Gtk.StackSidebar() sidebar.set_stack(stack) hbox = Gtk.Box() hbox.add(sidebar) hbox.add(stack) self.vbox.add(hbox) self.form = InputForm(inputs=notebook_properties, values=notebook.config['Notebook']) self.form.widgets['icon'].set_use_relative_paths(self.notebook) if self.notebook.readonly: for widget in list(self.form.widgets.values()): widget.set_sensitive(False) box = Gtk.VBox() box.pack_start(self.form, False, False, 0) stack.add_titled(box, 'notebook', _('Notebook')) self.plugin_forms = {} plugins = PluginManager() for name in plugins: plugin = plugins[name] if plugin.plugin_notebook_properties: key = plugin.config_key form = InputForm(inputs=plugin.form_fields( plugin.plugin_notebook_properties), values=notebook.config[key]) self.plugin_forms[key] = form if self.notebook.readonly: for widget in list(form.widgets.values()): widget.set_sensitive(False) box = Gtk.VBox() box.pack_start(form, False, False, 0) stack.add_titled(box, name, plugin.plugin_info['name']) def do_response_ok(self): if not self.notebook.readonly: properties = self.form.copy() self.notebook.save_properties(**properties) for key, form in self.plugin_forms.items(): self.notebook.config[key].update(form) if hasattr(self.notebook.config, 'write'): # XXX Check needed for tests logger.debug('Write notebook properties') self.notebook.config.write() return True
def __init__(self, ui): Dialog.__init__(self, ui, _('Preferences')) # T: Dialog title gtknotebook = gtk.Notebook() self.vbox.add(gtknotebook) # saves a list of loaded plugins to be used later self.p_save_loaded = [p.__class__ for p in self.ui.plugins] # Dynamic tabs self.forms = {} for category, preferences in ui.preferences_register.items(): vbox = gtk.VBox() gtknotebook.append_page(vbox, gtk.Label(_(category))) fields = [] values = {} sections = {} for p in preferences: if len(p) == 4: section, key, type, label = p fields.append((key, type, label)) else: section, key, type, label, check = p fields.append((key, type, label, check)) values[key] = ui.preferences[section][key] sections[key] = section form = InputForm(fields, values) form.preferences_sections = sections vbox.pack_start(form, False) self.forms[category] = form if category == 'Interface': self._add_font_selection(form) # Styles tab #~ gtknotebook.append_page(StylesTab(self), gtk.Label('Styles')) # Keybindings tab #~ gtknotebook.append_page(KeyBindingsTab(self), gtk.Label('Key bindings')) # Plugins tab gtknotebook.append_page(PluginsTab(self), gtk.Label(_('Plugins')))
def __init__(self, parent, notebook, chosen_plugin=None): Dialog.__init__(self, parent, _('Properties'), help='Help:Properties') # T: Dialog title self.notebook = notebook stack = Gtk.Stack() sidebar = Gtk.StackSidebar() sidebar.set_stack(stack) hbox = Gtk.Box() hbox.add(sidebar) hbox.add(stack) self.vbox.add(hbox) def add_widget(form, name, title): if chosen_plugin and chosen_plugin != name: return if self.notebook.readonly: for widget in list(form.widgets.values()): widget.set_sensitive(False) box = Gtk.VBox() box.pack_start(form, False, False, 0) stack.add_titled(box, name, title) self.form = InputForm( inputs=notebook_properties, values=notebook.config['Notebook'] ) self.form.widgets['icon'].set_use_relative_paths(self.notebook) self.form.widgets['document_root'].set_use_relative_paths(self.notebook) add_widget(self.form, 'notebook', _('Notebook')) self.plugin_forms = {} plugins = PluginManager() for name in plugins: plugin = plugins[name] if plugin.plugin_notebook_properties: key = plugin.config_key form = InputForm( inputs=plugin.form_fields(plugin.plugin_notebook_properties), values=notebook.config[key] ) self.plugin_forms[key] = form add_widget(form, name, plugin.plugin_info['name'])
def __init__(self, ui, page=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): Dialog.__init__(self, ui, _('Quick Note')) self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments self.uistate.setdefault('namespace', None, basestring) namespace = namespace or self.uistate['namespace'] self.form = InputForm(notebook=self.ui.notebook) self.vbox.pack_start(self.form, False) self._init_inputs(namespace, basename, append, text, template_options)
def __init__(self, parent, config, notebook): Dialog.__init__(self, parent, _('Properties'), help='Help:Properties') # T: Dialog title self.notebook = notebook self.config = config stack = Gtk.Stack() sidebar = Gtk.StackSidebar() sidebar.set_stack(stack) hbox = Gtk.Box() hbox.add(sidebar) hbox.add(stack) self.vbox.add(hbox) self.form = InputForm(inputs=notebook_properties, values=notebook.config['Notebook']) self.form.widgets['icon'].set_use_relative_paths(self.notebook) if self.notebook.readonly: for widget in list(self.form.widgets.values()): widget.set_sensitive(False) stack.add_titled(self.form, 'notebook', _('Notebook')) self.plugin_forms = {} plugins = get_window(parent).__pluginmanager__ # XXX for name in plugins: plugin = plugins[name] if plugin.plugin_notebook_properties: key = plugin.config_key form = InputForm(inputs=plugin.form_fields( plugin.plugin_notebook_properties), values=notebook.config[key]) self.plugin_forms[key] = form if self.notebook.readonly: for widget in list(form.widgets.values()): widget.set_sensitive(False) box = Gtk.VBox() box.pack_start(form, False, False, 0) stack.add_titled(box, name, plugin.plugin_info['name'])
def __init__(self, window, notebook, ui, page=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): Dialog.__init__(self, window, _('Quick Note')) self._ui = ui self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments self.uistate.setdefault('namespace', None, basestring) namespace = namespace or self.uistate['namespace'] self.form = InputForm(notebook=notebook) self.vbox.pack_start(self.form, False) self._init_inputs(namespace, basename, append, text, template_options)
def __init__(self, ui, notebook, pageview): self.notebook = notebook self.bt = notebook.bt self.pageview = pageview self.ui = ui Dialog.__init__( self, ui, _('Insert Ticket ID'), # T: Dialog title button=(_('_Insert'), 'gtk-ok'), # T: Button label defaultwindowsize=(245, 120) ) self.form = InputForm(notebook=notebook) self.vbox.pack_start(self.form, False) self.form.add_inputs(( ('ticket', 'string', _('ID')), # T: Ticket ID )) # Register global dielog key-press event, which is called for every input self.add_events(gtk.gdk.KEY_PRESS_MASK) self.connect('key-press-event', self.on_dialog_key_press)
class BoundQuickNoteDialog(Dialog): '''Dialog bound to a specific notebook''' def __init__(self, ui, page=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): Dialog.__init__(self, ui, _('Quick Note')) self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments self.uistate.setdefault('namespace', None, basestring) namespace = namespace or self.uistate['namespace'] self.form = InputForm(notebook=self.ui.notebook) self.vbox.pack_start(self.form, False) self._init_inputs(namespace, basename, append, text, template_options) def _init_inputs(self, namespace, basename, append, text, template_options, custom=None): if template_options is None: template_options = {} else: template_options = template_options.copy() if namespace is not None and basename is not None: page = namespace + ':' + basename else: page = namespace or basename self.form.add_inputs( ( ('page', 'page', _('Page')), ('namespace', 'namespace', _('Namespace')), # T: text entry field ('new_page', 'bool', _('Create a new page for each note')), # T: checkbox in Quick Note dialog ('basename', 'string', _('Title')) # T: text entry field ) ) self.form.update({ 'page': page, 'namespace': namespace, 'new_page': True, 'basename': basename, } ) self.uistate.setdefault('open_page', True) self.uistate.setdefault('new_page', True) if basename: self.uistate['new_page'] = True # Be consistent with input # Set up the inputs and set page/ namespace to switch on # toggling the checkbox self.form.widgets['page'].set_no_show_all(True) self.form.widgets['namespace'].set_no_show_all(True) if append is None: self.form['new_page'] = bool(self.uistate['new_page']) else: self.form['new_page'] = not append def switch_input(*a): if self.form['new_page']: self.form.widgets['page'].hide() self.form.widgets['namespace'].show() self.form.widgets['basename'].set_sensitive(True) else: self.form.widgets['page'].show() self.form.widgets['namespace'].hide() self.form.widgets['basename'].set_sensitive(False) switch_input() self.form.widgets['new_page'].connect('toggled', switch_input) self.open_page = gtk.CheckButton(_('Open _Page')) # T: Option in quicknote dialog # Don't use "O" as accelerator here to avoid conflict with "Ok" self.open_page.set_active(self.uistate['open_page']) self.action_area.pack_start(self.open_page, False) self.action_area.set_child_secondary(self.open_page, True) # Add the main textview and hook up the basename field to # sync with first line of the textview window, textview = ScrolledTextView() self.textview = textview self.textview.set_editable(True) self.vbox.add(window) self.form.widgets['basename'].connect('changed', self.on_title_changed) self.textview.get_buffer().connect('changed', self.on_text_changed) # Initialize text from template file = data_file('templates/plugins/quicknote.txt') template = GenericTemplate(file.readlines(), name=file) template_options.update({ 'text': text or '', 'strftime': StrftimeFunction(), } ) output = template.process(template_options) buffer = self.textview.get_buffer() buffer.set_text(''.join(output)) begin, end = buffer.get_bounds() buffer.place_cursor(begin) buffer.set_modified(False) self.connect('delete-event', self.do_delete_event) def do_response(self, id): if id == gtk.RESPONSE_DELETE_EVENT: if self.textview.get_buffer().get_modified(): ok = QuestionDialog(self, _('Discard note?')).run() # T: confirm closing quick note dialog if ok: Dialog.do_response(self, id) # else pass else: Dialog.do_response(self, id) else: Dialog.do_response(self, id) def do_delete_event(self, *a): # Block deletion if do_response did not yet destroy the dialog return True def run(self): self.textview.grab_focus() Dialog.run(self) def show(self): self.textview.grab_focus() Dialog.show(self) def save_uistate(self): self.uistate['new_page'] = self.form['new_page'] self.uistate['open_page'] = self.open_page.get_active() if self.uistate['new_page']: self.uistate['namespace'] = self.form['namespace'] else: self.uistate['namespace'] = self.form['page'] def on_title_changed(self, o): o.set_input_valid(True) if not self._updating_title: self._title_set_manually = True def on_text_changed(self, buffer): if not self._title_set_manually: # Automatically generate a (valid) page name self._updating_title = True bounds = buffer.get_bounds() title = buffer.get_text(*bounds).strip()[:50] # Cut off at 50 characters to prevent using a whole paragraph title = title.replace(':', '') if '\n' in title: title, _ = title.split('\n', 1) try: title = Notebook.cleanup_pathname(title, purge=True) self.form['basename'] = title except PageNameError: pass self._updating_title = False def do_response_ok(self, get_ui=None): # NOTE: Keep in mind that this method should also work using # a proxy object for the ui. This is why we have the get_ui() # argument to construct a proxy. buffer = self.textview.get_buffer() bounds = buffer.get_bounds() text = buffer.get_text(*bounds) if self.form['new_page']: if not self.form.widgets['namespace'].get_input_valid() \ or not self.form['basename']: if not self.form['basename']: entry = self.form.widgets['basename'] entry.set_input_valid(False, show_empty_invalid=True) return False if get_ui: ui = get_ui() else: ui = self.ui if ui is None: return False path = self.form['namespace'].name + ':' + self.form['basename'] ui.new_page_from_text(text, path, attachments=self.attachments, open_page=self.open_page.get_active() ) else: if not self.form.widgets['page'].get_input_valid() \ or not self.form['page']: return False if get_ui: ui = get_ui() else: ui = self.ui if ui is None: return False path = self.form['page'].name if self.attachments: ui.import_attachments(path, self.attachments) ui.append_text_to_page(path, '\n----\n'+text) if self.open_page.get_active(): ui.present(path) # also works with proxy return True
class QuickNoteDialog(BoundQuickNoteDialog): '''Dialog which includes a notebook chooser''' def __init__(self, ui, notebook=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): self.config = get_config('quicknote.conf') self.uistate = self.config['QuickNoteDialog'] Dialog.__init__(self, ui, _('Quick Note')) self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments if notebook and not isinstance(notebook, basestring): notebook = notebook.uri self.uistate.setdefault('lastnotebook', None, basestring) if self.uistate['lastnotebook']: notebook = notebook or self.uistate['lastnotebook'] self.config['Namespaces'].setdefault(notebook, None, basestring) namespace = namespace or self.config['Namespaces'][notebook] self.form = InputForm() self.vbox.pack_start(self.form, False) # TODO dropdown could use an option "Other..." label = gtk.Label(_('Notebook')+': ') label.set_alignment(0.0, 0.5) self.form.attach(label, 0,1, 0,1, xoptions=gtk.FILL) # T: Field to select Notebook from drop down list self.notebookcombobox = NotebookComboBox(current=notebook) self.notebookcombobox.connect('changed', self.on_notebook_changed) self.form.attach(self.notebookcombobox, 1,2, 0,1) self._init_inputs(namespace, basename, append, text, template_options) self.uistate['lastnotebook'] = notebook self._set_autocomplete(notebook) def save_uistate(self): notebook = self.notebookcombobox.get_notebook() self.uistate['lastnotebook'] = notebook self.uistate['new_page'] = self.form['new_page'] self.uistate['open_page'] = self.open_page.get_active() if notebook is not None: if self.uistate['new_page']: self.config['Namespaces'][notebook] = self.form['namespace'] else: self.config['Namespaces'][notebook] = self.form['page'] self.config.write() def on_notebook_changed(self, o): notebook = self.notebookcombobox.get_notebook() if not notebook or notebook == self.uistate['lastnotebook']: return self.uistate['lastnotebook'] = notebook self.config['Namespaces'].setdefault(notebook, None, basestring) namespace = self.config['Namespaces'][notebook] if namespace: self.form['namespace'] = namespace self._set_autocomplete(notebook) def _set_autocomplete(self, notebook): if notebook: obj = get_notebook(notebook) self.form.widgets['namespace'].notebook = obj self.form.widgets['page'].notebook = obj # Could still be None, e.g. if the notebook folder is not mounted logger.debug('Notebook for autocomplete: %s (%s)', obj, notebook) else: self.form.widgets['namespace'].notebook = None self.form.widgets['page'].notebook = None logger.debug('Notebook for autocomplete unset') def do_response_ok(self): def get_ui(): start_server_if_not_running() notebook = self.notebookcombobox.get_notebook() if notebook: return ServerProxy().get_notebook(notebook) else: return None return BoundQuickNoteDialog.do_response_ok(self, get_ui)
class QuickNoteDialog(Dialog): '''Dialog bound to a specific notebook''' def __init__(self, window, notebook=None, page=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): assert page is None, 'TODO' manager = ConfigManager() # FIXME should be passed in self.config = manager.get_config_dict('quicknote.conf') self.uistate = self.config['QuickNoteDialog'] Dialog.__init__(self, window, _('Quick Note')) self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments if notebook and not isinstance(notebook, str): notebook = notebook.uri self.uistate.setdefault('lastnotebook', None, str) if self.uistate['lastnotebook']: notebook = notebook or self.uistate['lastnotebook'] self.config['Namespaces'].setdefault(notebook, None, str) namespace = namespace or self.config['Namespaces'][notebook] self.form = InputForm() self.vbox.pack_start(self.form, False, True, 0) # TODO dropdown could use an option "Other..." label = Gtk.Label(label=_('Notebook') + ': ') label.set_alignment(0.0, 0.5) self.form.attach(label, 0, 1, 0, 1, xoptions=Gtk.AttachOptions.FILL) # T: Field to select Notebook from drop down list self.notebookcombobox = NotebookComboBox(current=notebook) self.notebookcombobox.connect('changed', self.on_notebook_changed) self.form.attach(self.notebookcombobox, 1, 2, 0, 1) self._init_inputs(namespace, basename, append, text, template_options) self.uistate['lastnotebook'] = notebook self._set_autocomplete(notebook) def _init_inputs(self, namespace, basename, append, text, template_options, custom=None): if template_options is None: template_options = {} else: template_options = template_options.copy() if namespace is not None and basename is not None: page = namespace + ':' + basename else: page = namespace or basename self.form.add_inputs(( ('page', 'page', _('Page')), ('namespace', 'namespace', _('Page section')), # T: text entry field ('new_page', 'bool', _('Create a new page for each note') ), # T: checkbox in Quick Note dialog ('basename', 'string', _('Title')) # T: text entry field )) self.form.update({ 'page': page, 'namespace': namespace, 'new_page': True, 'basename': basename, }) self.uistate.setdefault('open_page', True) self.uistate.setdefault('new_page', True) if basename: self.uistate['new_page'] = True # Be consistent with input # Set up the inputs and set page/ namespace to switch on # toggling the checkbox self.form.widgets['page'].set_no_show_all(True) self.form.widgets['namespace'].set_no_show_all(True) if append is None: self.form['new_page'] = bool(self.uistate['new_page']) else: self.form['new_page'] = not append def switch_input(*a): if self.form['new_page']: self.form.widgets['page'].hide() self.form.widgets['namespace'].show() self.form.widgets['basename'].set_sensitive(True) else: self.form.widgets['page'].show() self.form.widgets['namespace'].hide() self.form.widgets['basename'].set_sensitive(False) switch_input() self.form.widgets['new_page'].connect('toggled', switch_input) self.open_page_check = Gtk.CheckButton.new_with_mnemonic( _('Open _Page')) # T: Option in quicknote dialog # Don't use "O" as accelerator here to avoid conflict with "Ok" self.open_page_check.set_active(self.uistate['open_page']) self.action_area.pack_start(self.open_page_check, False, True, 0) self.action_area.set_child_secondary(self.open_page_check, True) # Add the main textview and hook up the basename field to # sync with first line of the textview window, textview = ScrolledTextView() self.textview = textview self.textview.set_editable(True) self.vbox.pack_start(window, True, True, 0) self.form.widgets['basename'].connect('changed', self.on_title_changed) self.textview.get_buffer().connect('changed', self.on_text_changed) # Initialize text from template template = get_template('plugins', 'quicknote.txt') template_options['text'] = text or '' template_options.setdefault('url', '') lines = [] template.process(lines, template_options) buffer = self.textview.get_buffer() buffer.set_text(''.join(lines)) begin, end = buffer.get_bounds() buffer.place_cursor(begin) buffer.set_modified(False) self.connect('delete-event', self.do_delete_event) def on_notebook_changed(self, o): notebook = self.notebookcombobox.get_notebook() if not notebook or notebook == self.uistate['lastnotebook']: return self.uistate['lastnotebook'] = notebook self.config['Namespaces'].setdefault(notebook, None, str) namespace = self.config['Namespaces'][notebook] if namespace: self.form['namespace'] = namespace self._set_autocomplete(notebook) def _set_autocomplete(self, notebook): if notebook: try: if isinstance(notebook, str): notebook = NotebookInfo(notebook) obj, x = build_notebook(notebook) self.form.widgets['namespace'].notebook = obj self.form.widgets['page'].notebook = obj logger.debug('Notebook for autocomplete: %s (%s)', obj, notebook) except: logger.exception('Could not set notebook: %s', notebook) else: self.form.widgets['namespace'].notebook = None self.form.widgets['page'].notebook = None logger.debug('Notebook for autocomplete unset') def do_response(self, id): if id == Gtk.ResponseType.DELETE_EVENT: if self.textview.get_buffer().get_modified(): ok = QuestionDialog(self, _('Discard note?')).run() # T: confirm closing quick note dialog if ok: Dialog.do_response(self, id) # else pass else: Dialog.do_response(self, id) else: Dialog.do_response(self, id) def do_delete_event(self, *a): # Block deletion if do_response did not yet destroy the dialog return True def run(self): self.textview.grab_focus() Dialog.run(self) def show(self): self.textview.grab_focus() Dialog.show(self) def save_uistate(self): notebook = self.notebookcombobox.get_notebook() self.uistate['lastnotebook'] = notebook self.uistate['new_page'] = self.form['new_page'] self.uistate['open_page'] = self.open_page_check.get_active() if notebook is not None: if self.uistate['new_page']: self.config['Namespaces'][notebook] = self.form['namespace'] else: self.config['Namespaces'][notebook] = self.form['page'] self.config.write() def on_title_changed(self, o): o.set_input_valid(True) if not self._updating_title: self._title_set_manually = True def on_text_changed(self, buffer): if not self._title_set_manually: # Automatically generate a (valid) page name self._updating_title = True start, end = buffer.get_bounds() title = start.get_text(end).strip()[:50] # Cut off at 50 characters to prevent using a whole paragraph title = title.replace(':', '') if '\n' in title: title, _ = title.split('\n', 1) try: title = Path.makeValidPageName(title.replace(':', '')) self.form['basename'] = title except ValueError: pass self._updating_title = False def do_response_ok(self): buffer = self.textview.get_buffer() start, end = buffer.get_bounds() text = start.get_text(end) # HACK: change "[]" at start of line into "[ ]" so checkboxes get inserted correctly text = re.sub(r'(?m)^(\s*)\[\](\s)', r'\1[ ]\2', text) # Specify "(?m)" instead of re.M since "flags" keyword is not # supported in python 2.6 notebook = self._get_notebook() if notebook is None: return False if self.form['new_page']: if not self.form.widgets['namespace'].get_input_valid() \ or not self.form['basename']: if not self.form['basename']: entry = self.form.widgets['basename'] entry.set_input_valid(False, show_empty_invalid=True) return False path = self.form['namespace'] + self.form['basename'] self.create_new_page(notebook, path, text) else: if not self.form.widgets['page'].get_input_valid() \ or not self.form['page']: return False path = self.form['page'] self.append_to_page(notebook, path, '\n------\n' + text) if self.attachments: self.import_attachments(notebook, path, self.attachments) if self.open_page_check.get_active(): self.hide() ZIM_APPLICATION.present(notebook, path) return True def _get_notebook(self): uri = self.notebookcombobox.get_notebook() notebook, p = build_notebook(Dir(uri)) return notebook def create_new_page(self, notebook, path, text): page = notebook.get_new_page(path) page.parse('wiki', text) # FIXME format hard coded notebook.store_page(page) def append_to_page(self, notebook, path, text): page = notebook.get_page(path) page.parse('wiki', text, append=True) # FIXME format hard coded notebook.store_page(page) def import_attachments(self, notebook, path, dir): attachments = notebook.get_attachments_dir(path) attachments = Dir(attachments.path) # XXX for name in dir.list(): # FIXME could use list objects, or list_files() file = dir.file(name) if not file.isdir(): file.copyto(attachments)
class QuickNoteDialog(BoundQuickNoteDialog): '''Dialog which includes a notebook chooser''' def __init__(self, window, notebook=None, page=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): assert page is None, 'TODO' manager = ConfigManager() # FIXME should be passed in self.config = manager.get_config_dict('quicknote.conf') self.uistate = self.config['QuickNoteDialog'] Dialog.__init__(self, window, _('Quick Note')) self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments if notebook and not isinstance(notebook, basestring): notebook = notebook.uri self.uistate.setdefault('lastnotebook', None, basestring) if self.uistate['lastnotebook']: notebook = notebook or self.uistate['lastnotebook'] self.config['Namespaces'].setdefault(notebook, None, basestring) namespace = namespace or self.config['Namespaces'][notebook] self.form = InputForm() self.vbox.pack_start(self.form, False) # TODO dropdown could use an option "Other..." label = gtk.Label(_('Notebook') + ': ') label.set_alignment(0.0, 0.5) self.form.attach(label, 0, 1, 0, 1, xoptions=gtk.FILL) # T: Field to select Notebook from drop down list self.notebookcombobox = NotebookComboBox(current=notebook) self.notebookcombobox.connect('changed', self.on_notebook_changed) self.form.attach(self.notebookcombobox, 1, 2, 0, 1) self._init_inputs(namespace, basename, append, text, template_options) self.uistate['lastnotebook'] = notebook self._set_autocomplete(notebook) def save_uistate(self): notebook = self.notebookcombobox.get_notebook() self.uistate['lastnotebook'] = notebook self.uistate['new_page'] = self.form['new_page'] self.uistate['open_page'] = self.open_page.get_active() if notebook is not None: if self.uistate['new_page']: self.config['Namespaces'][notebook] = self.form['namespace'] else: self.config['Namespaces'][notebook] = self.form['page'] self.config.write() def on_notebook_changed(self, o): notebook = self.notebookcombobox.get_notebook() if not notebook or notebook == self.uistate['lastnotebook']: return self.uistate['lastnotebook'] = notebook self.config['Namespaces'].setdefault(notebook, None, basestring) namespace = self.config['Namespaces'][notebook] if namespace: self.form['namespace'] = namespace self._set_autocomplete(notebook) def _set_autocomplete(self, notebook): if notebook: if isinstance(notebook, basestring): notebook = NotebookInfo(notebook) obj, x = build_notebook(notebook) self.form.widgets['namespace'].notebook = obj self.form.widgets['page'].notebook = obj logger.debug('Notebook for autocomplete: %s (%s)', obj, notebook) else: self.form.widgets['namespace'].notebook = None self.form.widgets['page'].notebook = None logger.debug('Notebook for autocomplete unset') def _get_ui(self): start_server_if_not_running() notebook = self.notebookcombobox.get_notebook() if notebook: return ServerProxy().get_notebook(notebook) else: return None
class BoundQuickNoteDialog(Dialog): '''Dialog bound to a specific notebook''' def __init__(self, window, notebook, ui, page=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): Dialog.__init__(self, window, _('Quick Note')) self._ui = ui self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments self.uistate.setdefault('namespace', None, basestring) namespace = namespace or self.uistate['namespace'] self.form = InputForm(notebook=notebook) self.vbox.pack_start(self.form, False) self._init_inputs(namespace, basename, append, text, template_options) def _init_inputs(self, namespace, basename, append, text, template_options, custom=None): if template_options is None: template_options = {} else: template_options = template_options.copy() if namespace is not None and basename is not None: page = namespace + ':' + basename else: page = namespace or basename self.form.add_inputs(( ('page', 'page', _('Page')), ('namespace', 'namespace', _('Namespace')), # T: text entry field ('new_page', 'bool', _('Create a new page for each note') ), # T: checkbox in Quick Note dialog ('basename', 'string', _('Title')) # T: text entry field )) self.form.update({ 'page': page, 'namespace': namespace, 'new_page': True, 'basename': basename, }) self.uistate.setdefault('open_page', True) self.uistate.setdefault('new_page', True) if basename: self.uistate['new_page'] = True # Be consistent with input # Set up the inputs and set page/ namespace to switch on # toggling the checkbox self.form.widgets['page'].set_no_show_all(True) self.form.widgets['namespace'].set_no_show_all(True) if append is None: self.form['new_page'] = bool(self.uistate['new_page']) else: self.form['new_page'] = not append def switch_input(*a): if self.form['new_page']: self.form.widgets['page'].hide() self.form.widgets['namespace'].show() self.form.widgets['basename'].set_sensitive(True) else: self.form.widgets['page'].show() self.form.widgets['namespace'].hide() self.form.widgets['basename'].set_sensitive(False) switch_input() self.form.widgets['new_page'].connect('toggled', switch_input) self.open_page = gtk.CheckButton( _('Open _Page')) # T: Option in quicknote dialog # Don't use "O" as accelerator here to avoid conflict with "Ok" self.open_page.set_active(self.uistate['open_page']) self.action_area.pack_start(self.open_page, False) self.action_area.set_child_secondary(self.open_page, True) # Add the main textview and hook up the basename field to # sync with first line of the textview window, textview = ScrolledTextView() self.textview = textview self.textview.set_editable(True) self.vbox.add(window) self.form.widgets['basename'].connect('changed', self.on_title_changed) self.textview.get_buffer().connect('changed', self.on_text_changed) # Initialize text from template file = data_file('templates/plugins/quicknote.txt') template = GenericTemplate(file.readlines(), name=file) template_options.update({ 'text': text or '', 'strftime': StrftimeFunction(), }) output = template.process(template_options) buffer = self.textview.get_buffer() buffer.set_text(''.join(output)) begin, end = buffer.get_bounds() buffer.place_cursor(begin) buffer.set_modified(False) self.connect('delete-event', self.do_delete_event) def do_response(self, id): if id == gtk.RESPONSE_DELETE_EVENT: if self.textview.get_buffer().get_modified(): ok = QuestionDialog(self, _('Discard note?')).run() # T: confirm closing quick note dialog if ok: Dialog.do_response(self, id) # else pass else: Dialog.do_response(self, id) else: Dialog.do_response(self, id) def do_delete_event(self, *a): # Block deletion if do_response did not yet destroy the dialog return True def run(self): self.textview.grab_focus() Dialog.run(self) def show(self): self.textview.grab_focus() Dialog.show(self) def save_uistate(self): self.uistate['new_page'] = self.form['new_page'] self.uistate['open_page'] = self.open_page.get_active() if self.uistate['new_page']: self.uistate['namespace'] = self.form['namespace'] else: self.uistate['namespace'] = self.form['page'] def on_title_changed(self, o): o.set_input_valid(True) if not self._updating_title: self._title_set_manually = True def on_text_changed(self, buffer): if not self._title_set_manually: # Automatically generate a (valid) page name self._updating_title = True bounds = buffer.get_bounds() title = buffer.get_text(*bounds).strip()[:50] # Cut off at 50 characters to prevent using a whole paragraph title = title.replace(':', '') if '\n' in title: title, _ = title.split('\n', 1) try: title = Notebook.cleanup_pathname(title, purge=True) self.form['basename'] = title except PageNameError: pass self._updating_title = False def _get_ui(self): return self._ui def do_response_ok(self): # NOTE: Keep in mind that this method should also work using # a proxy object for the ui. This is why we have the get_ui() # argument to construct a proxy. buffer = self.textview.get_buffer() bounds = buffer.get_bounds() text = buffer.get_text(*bounds) # HACK: change "[]" at start of line into "[ ]" so checkboxes get inserted correctly text = re.sub(r'(?m)^(\s*)\[\](\s)', r'\1[ ]\2', text) # Specify "(?m)" instead of re.M since "flags" keyword is not # supported in python 2.6 ui = self._get_ui() if ui is None: return False if self.form['new_page']: if not self.form.widgets['namespace'].get_input_valid() \ or not self.form['basename']: if not self.form['basename']: entry = self.form.widgets['basename'] entry.set_input_valid(False, show_empty_invalid=True) return False path = self.form['namespace'].name + ':' + self.form['basename'] ui.new_page_from_text(text, path, attachments=self.attachments, open_page=self.open_page.get_active()) else: if not self.form.widgets['page'].get_input_valid() \ or not self.form['page']: return False path = self.form['page'].name if self.attachments: ui.import_attachments(path, self.attachments) ui.append_text_to_page(path, '\n----\n' + text) if self.open_page.get_active(): ui.present(path) # also works with proxy return True
def __init__(self, widget, config, default_tab=None, select_plugin=None): Dialog.__init__(self, widget, _('Preferences')) # T: Dialog title self.config = config self.preferences = self.config.get_config_dict( '<profile>/preferences.conf') # saves a list of loaded plugins to be used later self.plugins = get_window(widget).__pluginmanager__ # XXX self.p_save_loaded = list(self.plugins) # Dynamic tabs gtknotebook = Gtk.Notebook() self.vbox.pack_start(gtknotebook, True, True, 0) self.forms = {} ############################### needs rewrite to make defintion more robust for category in ('Interface', 'Editing'): vbox = Gtk.VBox() index = gtknotebook.append_page(vbox, Gtk.Label(label=_(category))) # From GTK Doc: Note that due to historical reasons, GtkNotebook refuses # to switch to a page unless the child widget is visible. vbox.show() if category == default_tab: gtknotebook.set_current_page(index) fields = [] values = {} sections = {} for section, preferences in (('GtkInterface', interface_preferences), ('PageView', pageview_preferences)): for p in [p for p in preferences if p[2] == category]: # key, type, category, label, default, (check) if len(p) == 5: key, type, cat, label, default = p self.preferences[section].setdefault(key, default) fields.append((key, type, label)) else: key, type, cat, label, default, check = p self.preferences[section].setdefault( key, default, check) fields.append((key, type, label, check)) values[key] = self.preferences[section][key] sections[key] = section form = InputForm(fields, values) form.preferences_sections = sections vbox.pack_start(form, False, True, 0) self.forms[category] = form if category == 'Interface': self._add_font_selection(form) # Styles tab #~ gtknotebook.append_page(StylesTab(self), Gtk.Label(label=_('Styles'))) # Keybindings tab #~ gtknotebook.append_page(KeyBindingsTab(self), Gtk.Label(label=_('Key bindings'))) # Plugins tab self.plugins_tab = PluginsTab(self, self.plugins) plugins_tab_index = gtknotebook.append_page( self.plugins_tab, Gtk.Label(label=_('Plugins'))) # T: Heading in preferences dialog self.plugins_tab.show() #~ print default_tab, index if default_tab == "Plugins": gtknotebook.set_current_page(plugins_tab_index) if not select_plugin is None: self.plugins_tab.select_plugin(select_plugin) # Applications tab gtknotebook.append_page(ApplicationsTab(self), Gtk.Label(label=_('Applications')))
class BoundQuickNoteDialog(Dialog): '''Dialog bound to a specific notebook''' def __init__(self, window, notebook, ui, page=None, namespace=None, basename=None, append=None, text=None, template_options=None, attachments=None): Dialog.__init__(self, window, _('Quick Note')) self._ui = ui self._updating_title = False self._title_set_manually = not basename is None self.attachments = attachments self.uistate.setdefault('namespace', None, basestring) namespace = namespace or self.uistate['namespace'] self.form = InputForm(notebook=notebook) self.vbox.pack_start(self.form, False) self._init_inputs(namespace, basename, append, text, template_options) def _init_inputs(self, namespace, basename, append, text, template_options, custom=None): if template_options is None: template_options = {} else: template_options = template_options.copy() if namespace is not None and basename is not None: page = namespace + ':' + basename else: page = namespace or basename self.form.add_inputs(( ('page', 'page', _('Page')), ('namespace', 'namespace', _('Page section')), # T: text entry field ('new_page', 'bool', _('Create a new page for each note') ), # T: checkbox in Quick Note dialog ('basename', 'string', _('Title')) # T: text entry field )) self.form.update({ 'page': page, 'namespace': namespace, 'new_page': True, 'basename': basename, }) self.uistate.setdefault('open_page', True) self.uistate.setdefault('new_page', True) if basename: self.uistate['new_page'] = True # Be consistent with input # Set up the inputs and set page/ namespace to switch on # toggling the checkbox self.form.widgets['page'].set_no_show_all(True) self.form.widgets['namespace'].set_no_show_all(True) if append is None: self.form['new_page'] = bool(self.uistate['new_page']) else: self.form['new_page'] = not append def switch_input(*a): if self.form['new_page']: self.form.widgets['page'].hide() self.form.widgets['namespace'].show() self.form.widgets['basename'].set_sensitive(True) else: self.form.widgets['page'].show() self.form.widgets['namespace'].hide() self.form.widgets['basename'].set_sensitive(False) switch_input() self.form.widgets['new_page'].connect('toggled', switch_input) self.open_page_check = gtk.CheckButton( _('Open _Page')) # T: Option in quicknote dialog # Don't use "O" as accelerator here to avoid conflict with "Ok" self.open_page_check.set_active(self.uistate['open_page']) self.action_area.pack_start(self.open_page_check, False) self.action_area.set_child_secondary(self.open_page_check, True) # Add the main textview and hook up the basename field to # sync with first line of the textview window, textview = ScrolledTextView() self.textview = textview self.textview.set_editable(True) self.vbox.add(window) self.form.widgets['basename'].connect('changed', self.on_title_changed) self.textview.get_buffer().connect('changed', self.on_text_changed) # Initialize text from template template = get_template('plugins', 'quicknote.txt') template_options['text'] = text or '' template_options.setdefault('url', '') lines = [] template.process(lines, template_options) buffer = self.textview.get_buffer() buffer.set_text(''.join(lines)) begin, end = buffer.get_bounds() buffer.place_cursor(begin) buffer.set_modified(False) self.connect('delete-event', self.do_delete_event) def do_response(self, id): if id == gtk.RESPONSE_DELETE_EVENT: if self.textview.get_buffer().get_modified(): ok = QuestionDialog(self, _('Discard note?')).run() # T: confirm closing quick note dialog if ok: Dialog.do_response(self, id) # else pass else: Dialog.do_response(self, id) else: Dialog.do_response(self, id) def do_delete_event(self, *a): # Block deletion if do_response did not yet destroy the dialog return True def run(self): self.textview.grab_focus() Dialog.run(self) def show(self): self.textview.grab_focus() Dialog.show(self) def save_uistate(self): self.uistate['new_page'] = self.form['new_page'] self.uistate['open_page'] = self.open_page_check.get_active() if self.uistate['new_page']: self.uistate['namespace'] = self.form['namespace'] else: self.uistate['namespace'] = self.form['page'] def on_title_changed(self, o): o.set_input_valid(True) if not self._updating_title: self._title_set_manually = True def on_text_changed(self, buffer): if not self._title_set_manually: # Automatically generate a (valid) page name self._updating_title = True bounds = buffer.get_bounds() title = buffer.get_text(*bounds).strip()[:50] # Cut off at 50 characters to prevent using a whole paragraph title = title.replace(':', '') if '\n' in title: title, _ = title.split('\n', 1) try: title = Path.makeValidPageName(title.replace(':', '')) self.form['basename'] = title except ValueError: pass self._updating_title = False def do_response_ok(self): buffer = self.textview.get_buffer() bounds = buffer.get_bounds() text = buffer.get_text(*bounds) # HACK: change "[]" at start of line into "[ ]" so checkboxes get inserted correctly text = re.sub(r'(?m)^(\s*)\[\](\s)', r'\1[ ]\2', text) # Specify "(?m)" instead of re.M since "flags" keyword is not # supported in python 2.6 notebook = self._get_notebook() if notebook is None: return False if self.form['new_page']: if not self.form.widgets['namespace'].get_input_valid() \ or not self.form['basename']: if not self.form['basename']: entry = self.form.widgets['basename'] entry.set_input_valid(False, show_empty_invalid=True) return False path = self.form['namespace'] + self.form['basename'] self.create_new_page(notebook, path, text) else: if not self.form.widgets['page'].get_input_valid() \ or not self.form['page']: return False path = self.form['page'] self.append_to_page(notebook, path, '\n------\n' + text) if self.attachments: self.import_attachments(notebook, path, self.attachments) if self.open_page_check.get_active(): self.hide() self.open_page(notebook, path) return True def _get_notebook(self): # Overloaded below return self._ui.notebook def create_new_page(self, notebook, path, text): page = notebook.get_new_page(path) page.parse('wiki', text) # FIXME format hard coded notebook.store_page(page) def append_to_page(self, notebook, path, text): page = notebook.get_page(path) page.parse('wiki', text, append=True) # FIXME format hard coded notebook.store_page(page) def import_attachments(self, notebook, path, dir): attachments = notebook.get_attachments_dir(path) attachments = Dir(attachments.path) # XXX for name in dir.list(): # FIXME could use list objects, or list_files() file = dir.file(name) if not file.isdir(): file.copyto(attachments) def open_page(self, notebook, path): assert notebook == self._ui.notebook self._ui.present(path)