def __init__(self, parent, logging_context, output): self.logging_context = logging_context self.output = output n_error = logging_context.handler.n_error n_warning = logging_context.handler.n_warning if n_error and n_warning: text = _('%(n_error)i errors and %(n_warning)i warnings occurred, see log') % {'n_error': n_error, 'n_warning': n_warning} # T: label in export dialog elif n_error: text = _('%i errors occurred, see log') % n_error # T: label in export dialog elif n_warning: text = _('%i warnings occurred, see log') % n_warning # T: label in export dialog else: text = None MessageDialog.__init__(self, parent, (_('Export completed'), text)) # T: label in export dialog log_button = Button(_('View _Log'), stock='gtk-file') # T: button in export dialog log_button.set_sensitive(logging_context.file.exists()) log_button.connect_object( 'clicked', self.__class__.on_show_log, self) #~ open_button = #~ self.add_extra_button(open_button) self.add_extra_button(log_button)
def __init__(self, dialog): gtk.HBox.__init__(self, spacing=12) self.set_border_width(5) self.dialog = dialog treeview = PluginsTreeView(self.dialog.ui) treeview.connect('row-activated', self.do_row_activated) swindow = ScrolledWindow(treeview, hpolicy=gtk.POLICY_NEVER) self.pack_start(swindow, False) vbox = gtk.VBox() self.add(vbox) # Textview with scrollbars to show plugins info. Required by small screen devices swindow, textview = ScrolledTextView() textview.set_cursor_visible(False) self.textbuffer = textview.get_buffer() self.textbuffer.create_tag('bold', weight=pango.WEIGHT_BOLD) self.textbuffer.create_tag('red', foreground='#FF0000') vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) self.do_row_activated(treeview, (0,), 0)
def __init__(self, dialog, plugins): gtk.VBox.__init__(self, spacing=5) self.dialog = dialog self.plugins = plugins self.hbox = gtk.HBox(self, spacing=12) self.hbox.set_border_width(5) self.add(self.hbox) #~ logger.debug('Plugins that are loaded: %s' % list(plugins)) self.treeview = PluginsTreeView(self.plugins) self.treeview.connect('row-activated', self.do_row_activated) swindow = ScrolledWindow(self.treeview, hpolicy=gtk.POLICY_NEVER) self.hbox.pack_start(swindow, False) vbox = gtk.VBox() self.hbox.add(vbox) # Textview with scrollbars to show plugins info. Required by small screen devices swindow, textview = ScrolledTextView() textview.set_cursor_visible(False) self.textbuffer = textview.get_buffer() self.textbuffer.create_tag('bold', weight=pango.WEIGHT_BOLD) self.textbuffer.create_tag('red', foreground='#FF0000') vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) try: self.do_row_activated(self.treeview, (0, ), 0) except: pass # maybe loading plugins failed if gtk.gtk_version >= (2, 10) \ and gtk.pygtk_version >= (2, 10): url_button = gtk.LinkButton( 'https://github.com/jaap-karssenberg/zim-wiki/wiki/Plugins', _('Get more plugins online') # T: label for button with URL ) self.pack_start(url_button, False)
def __init__(self, ui, title, generator, image=None, **opt): Dialog.__init__(self, ui, title, defaultwindowsize=(450, 300), **opt) self.generator = generator self.imagefile = None self.logfile = None self._existing_file = None self.vpane = gtk.VPaned() self.vpane.set_position(100) self.vbox.add(self.vpane) self.imageview = ImageView(bgcolor='#FFF', checkboard=False) # TODO scrolled window self.vpane.add1(self.imageview) self.textview = gtk.TextView() # TODO scrolled window # TODO supply at least an Undo stack for this textview # or optionally subclass from gtksourceview self.textview.set_left_margin(5) self.textview.set_right_margin(5) self.vpane.add2(self.textview) hbox = gtk.HBox(spacing=5) self.vbox.pack_start(hbox, False) self.previewbutton = Button(_('_Preview'), stock='gtk-refresh') # T: button in e.g. equation editor dialog self.previewbutton.set_sensitive(False) self.previewbutton.connect_object( 'clicked', self.__class__.preview, self) hbox.pack_start(self.previewbutton, False) self.textview.get_buffer().connect('modified-changed', lambda b: self.previewbutton.set_sensitive(b.get_modified())) self.logbutton = Button(_('View _Log'), stock='gtk-file') # T: button in e.g. equation editor dialog self.logbutton.set_sensitive(False) self.logbutton.connect_object( 'clicked', self.__class__.show_log, self) hbox.pack_start(self.logbutton, False) if image: file = image['_src_file'] # FIXME ? textfile = self._stitch_fileextension(file, self.generator.basename) if file.exists() and textfile.exists(): self._existing_file = textfile self.imageview.set_file(file) self.set_text(textfile.read()) self.textview.grab_focus()
def __init__(self, dialog, plugins): gtk.VBox.__init__(self, spacing=5) self.dialog = dialog self.plugins = plugins self.hbox = gtk.HBox(self, spacing=12) self.hbox.set_border_width(5) self.add(self.hbox) #~ logger.debug('Plugins that are loaded: %s' % list(plugins)) self.treeview = PluginsTreeView(self.plugins) self.treeview.connect('row-activated', self.do_row_activated) swindow = ScrolledWindow(self.treeview, hpolicy=gtk.POLICY_NEVER) self.hbox.pack_start(swindow, False) vbox = gtk.VBox() self.hbox.add(vbox) # Textview with scrollbars to show plugins info. Required by small screen devices swindow, textview = ScrolledTextView() textview.set_cursor_visible(False) self.textbuffer = textview.get_buffer() self.textbuffer.create_tag('bold', weight=pango.WEIGHT_BOLD) self.textbuffer.create_tag('red', foreground='#FF0000') vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) try: self.do_row_activated(self.treeview, (0,), 0) except: pass # maybe loading plugins failed if gtk.gtk_version >= (2, 10) \ and gtk.pygtk_version >= (2, 10): url_button = gtk.LinkButton( 'https://github.com/jaap-karssenberg/zim-wiki/wiki/Plugins', _('Get more plugins online') # T: label for button with URL ) self.pack_start(url_button, False)
def __init__(self, dialog): gtk.HBox.__init__(self, spacing=12) self.set_border_width(5) self.dialog = dialog treeview = PluginsTreeView(self.dialog.ui) treeview.connect('row-activated', self.do_row_activated) swindow = gtk.ScrolledWindow() swindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) swindow.set_shadow_type(gtk.SHADOW_IN) self.pack_start(swindow, False) swindow.add(treeview) vbox = gtk.VBox() self.add(vbox) def heading(text): label = gtk.Label() label.set_markup('<b>%s</b>' % text) label.set_alignment(0.0, 0.5) return label vbox.pack_start(heading(_('Name')), False) # T: Heading in plugins tab of preferences dialog self.name_label = gtk.Label() self.name_label.set_alignment(0.0, 0.5) vbox.pack_start(self.name_label, False) vbox.pack_start(heading('\n'+_('Description')), False) # T: Heading in plugins tab of preferences dialog self.description_label = gtk.Label() self.description_label.set_alignment(0.0, 0.5) vbox.pack_start(self.description_label, False) # FIXME run through plain format to make links vbox.pack_start(heading('\n'+_('Author')), False) # T: Heading in plugins tab of preferences dialog self.author_label= gtk.Label() self.author_label.set_alignment(0.0, 0.5) vbox.pack_start(self.author_label, False) # FIXME idem hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) self.do_row_activated(treeview, (0,), 0)
def __init__(self, plugin): Dialog.__init__(self, plugin.ui, _('Calendar'), buttons=None) # T: dialog title self.set_resizable(False) self.plugin = plugin self.calendar_widget = CalendarPluginWidget(plugin) self.vbox.add(self.calendar_widget) hbox = gtk.HBox() self.vbox.add(hbox) button = Button(_('_Today'), gtk.STOCK_JUMP_TO) # T: button label button.connect('clicked', lambda o: self.calendar_widget.select_date(dateclass.today())) hbox.pack_end(button, False)
def __init__(self, plugin): Dialog.__init__(self, plugin.ui, _('Calendar'), buttons=gtk.BUTTONS_CLOSE) # T: dialog title self.set_resizable(False) self.plugin = plugin self.calendar_widget = CalendarPluginWidget(plugin) self.calendar_widget.set_select_date_callback(self.on_select_date) self.vbox.add(self.calendar_widget) button = Button(_('_Today'), gtk.STOCK_JUMP_TO) # T: button label button.connect('clicked', self.do_today ) self.action_area.add(button) self.action_area.reorder_child(button, 0) self.dateshown = datetime.date.today() self.connectto(self.plugin.ui, 'open-page')
def __init__(self, plugin, window): Dialog.__init__(self, window, _('Calendar'), buttons=gtk.BUTTONS_CLOSE) # T: dialog title self.set_resizable(False) self.plugin = plugin self.opener = window.get_resource_opener() notebook = window.ui.notebook # XXX model = CalendarWidgetModel(self.plugin, notebook) self.calendar_widget = CalendarWidget(model) self.vbox.add(self.calendar_widget) button = Button(_('_Today'), gtk.STOCK_JUMP_TO) # T: button label button.connect('clicked', self.do_today ) self.action_area.add(button) self.action_area.reorder_child(button, 0) self.dateshown = datetime.date.today() self.connectto(self.calendar_widget, 'date-activated') self.connectto(window.ui, 'open-page') # XXX
def __init__(self, parent, logging_context, output): self.logging_context = logging_context self.output = output n_error = logging_context.handler.n_error n_warning = logging_context.handler.n_warning if n_error and n_warning: text = _( '%(n_error)i errors and %(n_warning)i warnings occurred, see log' ) % { 'n_error': n_error, 'n_warning': n_warning } # T: label in export dialog elif n_error: text = _('%i errors occurred, see log') % n_error # T: label in export dialog elif n_warning: text = _('%i warnings occurred, see log') % n_warning # T: label in export dialog else: text = None MessageDialog.__init__(self, parent, (_('Export completed'), text)) # T: label in export dialog log_button = Button(_('View _Log'), stock='gtk-file') # T: button in export dialog log_button.set_sensitive(logging_context.file.exists()) log_button.connect_object('clicked', self.__class__.on_show_log, self) #~ open_button = #~ self.add_extra_button(open_button) self.add_extra_button(log_button)
def __init__(self, dialog, plugins): gtk.HBox.__init__(self, spacing=12) self.set_border_width(5) self.dialog = dialog self.plugins = plugins #~ logger.debug('Plugins that are loaded: %s' % list(plugins)) self.treeview = PluginsTreeView(self.plugins) self.treeview.connect('row-activated', self.do_row_activated) swindow = ScrolledWindow(self.treeview, hpolicy=gtk.POLICY_NEVER) self.pack_start(swindow, False) vbox = gtk.VBox() self.add(vbox) # Textview with scrollbars to show plugins info. Required by small screen devices swindow, textview = ScrolledTextView() textview.set_cursor_visible(False) self.textbuffer = textview.get_buffer() self.textbuffer.create_tag('bold', weight=pango.WEIGHT_BOLD) self.textbuffer.create_tag('red', foreground='#FF0000') vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) self.do_row_activated(self.treeview, (0, ), 0)
class PluginsTab(gtk.HBox): # TODO defined checks for plugin dependencies and grey them out here if # the check fails - or give an error popup with the result of the check def __init__(self, dialog): gtk.HBox.__init__(self, spacing=12) self.set_border_width(5) self.dialog = dialog treeview = PluginsTreeView(self.dialog.ui) treeview.connect('row-activated', self.do_row_activated) swindow = gtk.ScrolledWindow() swindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC) swindow.set_shadow_type(gtk.SHADOW_IN) self.pack_start(swindow, False) swindow.add(treeview) vbox = gtk.VBox() self.add(vbox) def heading(text): label = gtk.Label() label.set_markup('<b>%s</b>' % text) label.set_alignment(0.0, 0.5) return label vbox.pack_start(heading(_('Name')), False) # T: Heading in plugins tab of preferences dialog self.name_label = gtk.Label() self.name_label.set_alignment(0.0, 0.5) vbox.pack_start(self.name_label, False) vbox.pack_start(heading('\n'+_('Description')), False) # T: Heading in plugins tab of preferences dialog self.description_label = gtk.Label() self.description_label.set_alignment(0.0, 0.5) vbox.pack_start(self.description_label, False) # FIXME run through plain format to make links vbox.pack_start(heading('\n'+_('Author')), False) # T: Heading in plugins tab of preferences dialog self.author_label= gtk.Label() self.author_label.set_alignment(0.0, 0.5) vbox.pack_start(self.author_label, False) # FIXME idem hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) self.do_row_activated(treeview, (0,), 0) def do_row_activated(self, treeview, path, col): active = treeview.get_model()[path][0] klass = treeview.get_model()[path][2] self._klass = klass self.name_label.set_text(klass.plugin_info['name'].strip()) self.description_label.set_text(klass.plugin_info['description'].strip()) self.author_label.set_text(klass.plugin_info['author'].strip() + '\n') self.configure_button.set_sensitive(active and bool(klass.plugin_preferences)) self.plugin_help_button.set_sensitive('help' in klass.plugin_info) def on_help_button_clicked(self, button): self.dialog.ui.show_help(self._klass.plugin_info['help']) def on_configure_button_clicked(self, button): PluginConfigureDialog(self.dialog, self._klass).run()
class PluginsTab(gtk.VBox): def __init__(self, dialog, plugins): gtk.VBox.__init__(self, spacing=5) self.dialog = dialog self.plugins = plugins self.hbox = gtk.HBox(self, spacing=12) self.hbox.set_border_width(5) self.add(self.hbox) #~ logger.debug('Plugins that are loaded: %s' % list(plugins)) self.treeview = PluginsTreeView(self.plugins) self.treeview.connect('row-activated', self.do_row_activated) swindow = ScrolledWindow(self.treeview, hpolicy=gtk.POLICY_NEVER) self.hbox.pack_start(swindow, False) vbox = gtk.VBox() self.hbox.add(vbox) # Textview with scrollbars to show plugins info. Required by small screen devices swindow, textview = ScrolledTextView() textview.set_cursor_visible(False) self.textbuffer = textview.get_buffer() self.textbuffer.create_tag('bold', weight=pango.WEIGHT_BOLD) self.textbuffer.create_tag('red', foreground='#FF0000') vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) try: self.do_row_activated(self.treeview, (0,), 0) except: pass # maybe loading plugins failed if gtk.gtk_version >= (2, 10) \ and gtk.pygtk_version >= (2, 10): url_button = gtk.LinkButton( 'https://github.com/jaap-karssenberg/zim-wiki/wiki/Plugins', _('Get more plugins online') # T: label for button with URL ) self.pack_start(url_button, False) def do_row_activated(self, treeview, path, col): key, active, activatable, name, klass = treeview.get_model()[path] self._current_plugin = key logger.debug('Loading description for plugin: %s', key) # Insert plugin info into textview with proper formatting # TODO use our own widget with formatted text here... buffer = self.textbuffer def insert(text, style=None): if style: buffer.insert_with_tags_by_name( buffer.get_end_iter(), text, style) else: buffer.insert_at_cursor(text) buffer.delete(*buffer.get_bounds()) # clear insert(_('Name') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog insert(klass.plugin_info['name'].strip() + '\n\n') insert(_('Description') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog insert(klass.plugin_info['description'].strip() + '\n\n') insert(_('Dependencies') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog check, dependencies = klass.check_dependencies() if not(dependencies): insert(_('No dependencies') + '\n') # T: label in plugin info in preferences dialog else: # Construct dependency list, missing dependencies are marked red for dependency in dependencies: text, ok, required = dependency if ok: insert(u'\u2022 %s - %s\n' % (text, _('OK'))) # T: dependency is OK elif required: insert(u'\u2022 %s - %s\n' % (text, _('Failed')), 'red') # T: dependency failed else: insert(u'\u2022 %s - %s (%s)\n' % (text, _('Failed'), # T: dependency failed _('Optional') # T: optional dependency ) ) insert('\n') insert(_('Author') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog insert(klass.plugin_info['author'].strip()) self.configure_button.set_sensitive(active and bool(klass.plugin_preferences)) self.plugin_help_button.set_sensitive('help' in klass.plugin_info) def on_help_button_clicked(self, button): klass = self.plugins.get_plugin_class(self._current_plugin) self.dialog.ui.show_help(klass.plugin_info['help']) # XXX def on_configure_button_clicked(self, button): plugin = self.plugins[self._current_plugin] PluginConfigureDialog(self.dialog, plugin).run() def select_plugin(self, name): model = self.treeview.get_model() def find(model, path, iter): if model[iter][2] == name: self.treeview.scroll_to_cell(path) self.treeview.set_cursor(path) self.do_row_activated(self.treeview, path, 0) return True; return False # keep the foreach going model.foreach(find)
def __init__(self, ui, title, generator, image=None, syntax=None, **opt): '''Constructor @param ui: L{GtkInterface} object or parent window @param title: the dialog title @param generator: an L{ImageGeneratorClass} object @param image: image data for an image in the L{TextBuffer<zim.gui.pageview.TextBuffer>} @param syntax: optional syntax name (as understood by gtksourceview) @param opt: any other arguments to pass to the L{Dialog} constructor ''' if ui_environment['platform'] == 'maemo': defaultsize = (450, 480) # Use maximum available vertical space because decorations take # too much real state else: defaultsize = (450, 300) Dialog.__init__(self, ui, title, defaultwindowsize=defaultsize, **opt) if ui_environment['platform'] == 'maemo': self.resize(450, 480) # Force maximum dialog size under maemo, otherwise # we'll end with a too small dialog and no way to resize it self.generator = generator self.imagefile = None self.logfile = None self.vpane = VPaned() self.vpane.set_position(150) self.vbox.add(self.vpane) self.imageview = ImageView(bgcolor='#FFF', checkerboard=False) self.vpane.pack1(self.imageview, resize=True) # TODO scrolled window and option to zoom in / real size window, textview = ScrolledSourceView(syntax=syntax) self.textview = textview self.textview.set_editable(True) self.vpane.pack2(window, resize=False) hbox = gtk.HBox(spacing=5) self.vbox.pack_start(hbox, False) self.previewbutton = Button(_('_Preview'), stock='gtk-refresh') # T: button in e.g. equation editor dialog self.previewbutton.set_sensitive(False) self.previewbutton.connect_object('clicked', self.__class__.preview, self) hbox.pack_start(self.previewbutton, False) self.textview.get_buffer().connect( 'modified-changed', lambda b: self.previewbutton.set_sensitive(b.get_modified())) self.logbutton = Button(_('View _Log'), stock='gtk-file') # T: button in e.g. equation editor dialog self.logbutton.set_sensitive(False) self.logbutton.connect_object('clicked', self.__class__.show_log, self) if generator.uses_log_file: hbox.pack_start(self.logbutton, False) # else keep hidden self._existing_file = None if image: file = image['_src_file'] # FIXME ? textfile = self._stitch_fileextension(file, self.generator.scriptname) self._existing_file = textfile self.imageview.set_file(file) self.set_text(self.generator.filter_input(textfile.read())) self.textview.grab_focus()
class ImageGeneratorDialog(Dialog): '''Base class for use by plugins that generate and insert an image based on textual user input. This is used e.g. by the equation editor and similar plugins. The dialog provides text input and an image view for showing previews. ''' # TODO: use uistate to remember pane position def __init__(self, ui, title, generator, image=None, syntax=None, **opt): '''Constructor @param ui: L{GtkInterface} object or parent window @param title: the dialog title @param generator: an L{ImageGeneratorClass} object @param image: image data for an image in the L{TextBuffer<zim.gui.pageview.TextBuffer>} @param syntax: optional syntax name (as understood by gtksourceview) @param opt: any other arguments to pass to the L{Dialog} constructor ''' if ui_environment['platform'] == 'maemo': defaultsize = (450,480) # Use maximum available vertical space because decorations take # too much real state else: defaultsize = (450,300) Dialog.__init__(self, ui, title, defaultwindowsize=defaultsize, **opt) if ui_environment['platform'] == 'maemo': self.resize(450,480) # Force maximum dialog size under maemo, otherwise # we'll end with a too small dialog and no way to resize it self.generator = generator self.imagefile = None self.logfile = None self.vpane = VPaned() self.vpane.set_position(150) self.vbox.add(self.vpane) self.imageview = ImageView(bgcolor='#FFF', checkerboard=False) self.vpane.pack1(self.imageview, resize=True) # TODO scrolled window and option to zoom in / real size window, textview = ScrolledSourceView(syntax=syntax) self.textview = textview self.textview.set_editable(True) self.vpane.pack2(window, resize=False) hbox = gtk.HBox(spacing=5) self.vbox.pack_start(hbox, False) self.previewbutton = Button(_('_Preview'), stock='gtk-refresh') # T: button in e.g. equation editor dialog self.previewbutton.set_sensitive(False) self.previewbutton.connect_object( 'clicked', self.__class__.preview, self) hbox.pack_start(self.previewbutton, False) self.textview.get_buffer().connect('modified-changed', lambda b: self.previewbutton.set_sensitive(b.get_modified())) self.logbutton = Button(_('View _Log'), stock='gtk-file') # T: button in e.g. equation editor dialog self.logbutton.set_sensitive(False) self.logbutton.connect_object( 'clicked', self.__class__.show_log, self) if generator.uses_log_file: hbox.pack_start(self.logbutton, False) # else keep hidden self._existing_file = None if image: file = image['_src_file'] # FIXME ? textfile = self._stitch_fileextension(file, self.generator.scriptname) self._existing_file = textfile self.imageview.set_file(file) self.set_text(self.generator.filter_input(textfile.read())) self.textview.grab_focus() def _stitch_fileextension(self, file, basename): '''Stitches the file extension from 'basename' to the path of 'file' and returns a File object. ''' i = basename.rfind('.') j = file.path.rfind('.') return File(file.path[:j] + basename[i:]) def set_text(self, text): '''Set text in the buffer''' buffer = self.textview.get_buffer() buffer.set_text(text) buffer.set_modified(False) def get_text(self): '''Get the text from the buffer @returns: text as string ''' buffer = self.textview.get_buffer() bounds = buffer.get_bounds() return buffer.get_text(*bounds) def generate_image(self): '''Update the image based on the text in the text buffer''' self.imagefile = None self.logfile = None text = self.get_text() text = self.generator.process_input(text) try: imagefile, logfile = self.generator.generate_image(text) except: logger.exception('Could not generate image') # TODO set "error" image instead of "broken" image # TODO set exception text as log message else: self.imagefile = imagefile self.logfile = logfile self.textview.get_buffer().set_modified(False) def preview(self): '''Action for the "Preview" button''' self.generate_image() self.imageview.set_file(self.imagefile) # if None sets broken image self.logbutton.set_sensitive(not self.logfile is None) def show_log(self): '''Action for the "View Log" button''' assert self.logfile, 'BUG: no logfile set (yet)' LogFileDialog(self, self.logfile).run() def do_response_ok(self): if not self.imagefile \ or self.textview.get_buffer().get_modified(): self.generate_image() if not (self.imagefile and self.imagefile.exists()): dialog = QuestionDialog(self, _('An error occurred while generating the image.\nDo you want to save the source text anyway?')) # T: Question prompt when e.g. equation editor encountered an error generating the image to insert if not dialog.run(): return False if self._existing_file: textfile = self._existing_file else: page = self.ui.page dir = self.ui.notebook.get_attachments_dir(page) textfile = dir.new_file(self.generator.scriptname) textfile.write( self.generator.process_input(self.get_text()) ) imgfile = self._stitch_fileextension(textfile, self.generator.imagename) if self.imagefile and self.imagefile.exists(): self.imagefile.rename(imgfile) elif imgfile.exists(): imgfile.remove() if self._existing_file: self.ui.reload_page() else: pageview = self.ui.mainwindow.pageview # XXX pageview.insert_image(imgfile, type=self.generator.object_type, interactive=False, force=True) if self.logfile and self.logfile.exists(): self.logfile.remove() return True def destroy(self): self.generator.cleanup() Dialog.destroy(self)
def __init__(self, window, title, generator, image=None, syntax=None, **opt): '''Constructor @param window: the L{MainWindow} @param title: the dialog title @param generator: an L{ImageGeneratorClass} object @param image: image data for an image in the L{TextBuffer<zim.gui.pageview.TextBuffer>} @param syntax: optional syntax name (as understood by gtksourceview) @param opt: any other arguments to pass to the L{Dialog} constructor ''' Dialog.__init__(self, window, title, defaultwindowsize=(450, 300), **opt) self.app_window = window self.generator = generator self.imagefile = None self.logfile = None self.vpane = VPaned() self.vpane.set_position(150) self.vbox.add(self.vpane) self.imageview = ImageView(bgcolor='#FFF', checkerboard=False) self.vpane.pack1(self.imageview, resize=True) # TODO scrolled window and option to zoom in / real size window, textview = ScrolledSourceView(syntax=syntax) self.textview = textview self.textview.set_editable(True) self.vpane.pack2(window, resize=False) hbox = gtk.HBox(spacing=5) self.vbox.pack_start(hbox, False) self.previewbutton = Button(_('_Preview'), stock='gtk-refresh') # T: button in e.g. equation editor dialog self.previewbutton.set_sensitive(False) self.previewbutton.connect_object('clicked', self.__class__.preview, self) hbox.pack_start(self.previewbutton, False) self.textview.get_buffer().connect( 'modified-changed', lambda b: self.previewbutton.set_sensitive(b.get_modified())) self.logbutton = Button(_('View _Log'), stock='gtk-file') # T: button in e.g. equation editor dialog self.logbutton.set_sensitive(False) self.logbutton.connect_object('clicked', self.__class__.show_log, self) if generator.uses_log_file: hbox.pack_start(self.logbutton, False) # else keep hidden if image: file = image['_src_file'] # FIXME ? textfile = self._stitch_fileextension(file, self.generator.scriptname) self._existing_file = textfile self.imageview.set_file(file) self.set_text(self.generator.filter_input(textfile.read())) else: self._existing_file = None self.set_text( self.generator.filter_input(self.generator.get_default_text())) self.textview.grab_focus()
def __init__(self, ui): Dialog.__init__(self, ui, _('Templates'), help='Help:Templates', buttons=gtk.BUTTONS_CLOSE, defaultwindowsize=(400, 450)) # T: Dialog title label = gtk.Label() label.set_markup('<b>'+_('Templates')+'</b>') # T: Section in dialog label.set_alignment(0.0, 0.5) self.vbox.pack_start(label, False) hbox = gtk.HBox() self.vbox.add(hbox) self.view = TemplateListView() self.view.connect('row-activated', self.on_selection_changed) hbox.add(ScrolledWindow(self.view)) vbbox = gtk.VButtonBox() vbbox.set_layout(gtk.BUTTONBOX_START) hbox.pack_start(vbbox, False) view_button = Button(stock='gtk-file', label=_('_View')) # T: button label view_button.connect('clicked', self.on_view) copy_button = Button(stock='gtk-copy') copy_button.connect('clicked', self.on_copy) edit_button = Button(stock='gtk-edit') edit_button.connect('clicked', self.on_edit) delete_button = gtk.Button(stock='gtk-remove') delete_button.connect('clicked', self.on_delete) for b in (view_button, copy_button, edit_button, delete_button): b.set_alignment(0.0, 0.5) vbbox.add(b) browse_button = Button(_('Browse')) # T: button label browse_button.connect('clicked', self.on_browse) self.add_extra_button(browse_button) self._buttonbox = vbbox self._delete_button = delete_button self.on_selection_changed() ## Same button appears in export dialog if gtk.gtk_version >= (2, 10) \ and gtk.pygtk_version >= (2, 10): url_button = gtk.LinkButton( 'https://github.com/jaap-karssenberg/zim-wiki/wiki/Templates', _('Get more templates online') # T: label for button with URL ) self.vbox.pack_start(url_button, False)
class ImageGeneratorDialog(Dialog): '''Base class for use by plugins that generate and insert an image based on textual user input. This is used e.g. by the equation editor and similar plugins. The dialog provides text input and an image view for showing previes. ''' # TODO: use uistate to remember pane position def __init__(self, ui, title, generator, image=None, **opt): Dialog.__init__(self, ui, title, defaultwindowsize=(450, 300), **opt) self.generator = generator self.imagefile = None self.logfile = None self._existing_file = None self.vpane = gtk.VPaned() self.vpane.set_position(100) self.vbox.add(self.vpane) self.imageview = ImageView(bgcolor='#FFF', checkboard=False) # TODO scrolled window self.vpane.add1(self.imageview) self.textview = gtk.TextView() # TODO scrolled window # TODO supply at least an Undo stack for this textview # or optionally subclass from gtksourceview self.textview.set_left_margin(5) self.textview.set_right_margin(5) self.vpane.add2(self.textview) hbox = gtk.HBox(spacing=5) self.vbox.pack_start(hbox, False) self.previewbutton = Button(_('_Preview'), stock='gtk-refresh') # T: button in e.g. equation editor dialog self.previewbutton.set_sensitive(False) self.previewbutton.connect_object( 'clicked', self.__class__.preview, self) hbox.pack_start(self.previewbutton, False) self.textview.get_buffer().connect('modified-changed', lambda b: self.previewbutton.set_sensitive(b.get_modified())) self.logbutton = Button(_('View _Log'), stock='gtk-file') # T: button in e.g. equation editor dialog self.logbutton.set_sensitive(False) self.logbutton.connect_object( 'clicked', self.__class__.show_log, self) hbox.pack_start(self.logbutton, False) if image: file = image['_src_file'] # FIXME ? textfile = self._stitch_fileextension(file, self.generator.basename) if file.exists() and textfile.exists(): self._existing_file = textfile self.imageview.set_file(file) self.set_text(textfile.read()) self.textview.grab_focus() def _stitch_fileextension(self, file, basename): '''Stitches the file extension from 'basename' to the path of 'file' and returns a File object. ''' i = basename.rfind('.') j = file.path.rfind('.') return File(file.path[:j] + basename[i:]) def set_text(self, text): buffer = self.textview.get_buffer() buffer.set_text(text) buffer.set_modified(False) def get_text(self): buffer = self.textview.get_buffer() bounds = buffer.get_bounds() return buffer.get_text(*bounds) def generate_image(self): self.imagefile = None self.logfile = None text = self.get_text() try: imagefile, logfile = self.generator.generate_image(text) except: logger.exception('Could not generate image') # TODO set "error" image instead of "broken" image # TODO set exception text as log message else: self.imagefile = imagefile self.logfile = logfile self.textview.get_buffer().set_modified(False) def preview(self): self.generate_image() self.imageview.set_file(self.imagefile) # if None sets broken image self.logbutton.set_sensitive(not self.logfile is None) def show_log(self): assert self.logfile, 'BUG: no logfile set (yet)' LogFileDialog(self, self.logfile).run() def do_response_ok(self): if not self.imagefile \ or self.textview.get_buffer().get_modified(): self.generate_image() if not (self.imagefile and self.imagefile.exists()): dialog = QuestionDialog(self, _('An error occured while generating the image.\nDo you want to save the source text anyway?')) # T: Question prompt when e.g. equation editor encountered an error genrating the image to insert if not dialog.run(): return False if self._existing_file: textfile = self._existing_file else: page = self.ui.page dir = self.ui.notebook.get_attachments_dir(page) textfile = dir.new_file(self.generator.basename) imgfile = self._stitch_fileextension(textfile, self.imagefile.basename) textfile.write( self.get_text() ) self.imagefile.rename(imgfile) if self._existing_file: self.ui.reload_page() else: pageview = self.ui.mainwindow.pageview pageview.insert_image(imgfile, type=self.generator.type, interactive=False) if self.logfile and self.logfile.exists(): self.logfile.remove() return True def destroy(self): self.generator.cleanup() Dialog.destroy(self)
class PluginsTab(gtk.VBox): def __init__(self, dialog, plugins): gtk.VBox.__init__(self, spacing=5) self.dialog = dialog self.plugins = plugins self.hbox = gtk.HBox(self, spacing=12) self.hbox.set_border_width(5) self.add(self.hbox) #~ logger.debug('Plugins that are loaded: %s' % list(plugins)) self.treeview = PluginsTreeView(self.plugins) self.treeselection = self.treeview.get_selection() self.treeselection.connect('changed', self.do_selection_changed) swindow = ScrolledWindow(self.treeview, hpolicy=gtk.POLICY_NEVER) self.hbox.pack_start(swindow, False) vbox = gtk.VBox() self.hbox.add(vbox) # Textview with scrollbars to show plugins info. Required by small screen devices swindow, textview = ScrolledTextView() textview.set_cursor_visible(False) self.textbuffer = textview.get_buffer() self.textbuffer.create_tag('bold', weight=pango.WEIGHT_BOLD) self.textbuffer.create_tag('red', foreground='#FF0000') vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) try: self.treeselection.select_path(0) except: pass # maybe loading plugins failed ## Add buttons to get and install new plugins hbox = gtk.HButtonBox() hbox.set_border_width(5) hbox.set_layout(gtk.BUTTONBOX_START) self.pack_start(hbox, False) assert hasattr(self.dialog, 'ui') open_button = gtk.Button(label=_('Open plugins folder')) open_button.connect('clicked', lambda o: self.dialog.ui.open_dir(PLUGIN_FOLDER)) hbox.pack_start(open_button, False) if gtk.gtk_version >= (2, 10) \ and gtk.pygtk_version >= (2, 10): url_button = gtk.LinkButton( 'http://zim-wiki.org/more_plugins.html', _('Get more plugins online') # T: label for button with URL ) hbox.pack_start(url_button, False) def do_selection_changed(self, selection): treeview = selection.get_tree_view() selected = selection.get_selected() path = selected[0].get_path(selected[1]) key, active, activatable, name, klass = treeview.get_model()[path] self._current_plugin = key logger.debug('Loading description for plugin: %s', key) # Insert plugin info into textview with proper formatting # TODO use our own widget with formatted text here... buffer = self.textbuffer def insert(text, style=None): if style: buffer.insert_with_tags_by_name(buffer.get_end_iter(), text, style) else: buffer.insert_at_cursor(text) buffer.delete(*buffer.get_bounds()) # clear insert(_('Name') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog insert(klass.plugin_info['name'].strip() + '\n\n') insert(_('Description') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog insert(klass.plugin_info['description'].strip() + '\n\n') insert(_('Dependencies') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog check, dependencies = klass.check_dependencies() if not (dependencies): insert(_('No dependencies') + '\n') # T: label in plugin info in preferences dialog else: # Construct dependency list, missing dependencies are marked red for dependency in dependencies: text, ok, required = dependency if ok: insert(u'\u2022 %s - %s\n' % (text, _('OK'))) # T: dependency is OK elif required: insert(u'\u2022 %s - %s\n' % (text, _('Failed')), 'red') # T: dependency failed else: insert(u'\u2022 %s - %s (%s)\n' % ( text, _('Failed'), # T: dependency failed _('Optional') # T: optional dependency )) insert('\n') insert(_('Author') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog insert(klass.plugin_info['author'].strip()) self.configure_button.set_sensitive(active and bool(klass.plugin_preferences)) self.plugin_help_button.set_sensitive('help' in klass.plugin_info) def on_help_button_clicked(self, button): klass = self.plugins.get_plugin_class(self._current_plugin) self.dialog.ui.show_help(klass.plugin_info['help']) # XXX def on_configure_button_clicked(self, button): plugin = self.plugins[self._current_plugin] PluginConfigureDialog(self.dialog, plugin).run() def select_plugin(self, name): model = self.treeview.get_model() def find(model, path, iter): if model[iter][2] == name: self.treeview.scroll_to_cell(path) self.treeview.set_cursor(path) self.do_selection_changed(self.treeselection, 0) return True return False # keep the foreach going model.foreach(find)
class ImageGeneratorDialog(Dialog): '''Dialog that provides text input and an image view for showing previews for an L{ImageGeneratorClass} implementation. ''' # TODO: use uistate to remember pane position def __init__(self, window, title, generator, image=None, syntax=None, **opt): '''Constructor @param window: the L{MainWindow} @param title: the dialog title @param generator: an L{ImageGeneratorClass} object @param image: image data for an image in the L{TextBuffer<zim.gui.pageview.TextBuffer>} @param syntax: optional syntax name (as understood by gtksourceview) @param opt: any other arguments to pass to the L{Dialog} constructor ''' Dialog.__init__(self, window, title, defaultwindowsize=(450, 300), **opt) self.app_window = window self.generator = generator self.imagefile = None self.logfile = None self.vpane = VPaned() self.vpane.set_position(150) self.vbox.add(self.vpane) self.imageview = ImageView(bgcolor='#FFF', checkerboard=False) self.vpane.pack1(self.imageview, resize=True) # TODO scrolled window and option to zoom in / real size window, textview = ScrolledSourceView(syntax=syntax) self.textview = textview self.textview.set_editable(True) self.vpane.pack2(window, resize=False) hbox = gtk.HBox(spacing=5) self.vbox.pack_start(hbox, False) self.previewbutton = Button(_('_Preview'), stock='gtk-refresh') # T: button in e.g. equation editor dialog self.previewbutton.set_sensitive(False) self.previewbutton.connect_object('clicked', self.__class__.preview, self) hbox.pack_start(self.previewbutton, False) self.textview.get_buffer().connect( 'modified-changed', lambda b: self.previewbutton.set_sensitive(b.get_modified())) self.logbutton = Button(_('View _Log'), stock='gtk-file') # T: button in e.g. equation editor dialog self.logbutton.set_sensitive(False) self.logbutton.connect_object('clicked', self.__class__.show_log, self) if generator.uses_log_file: hbox.pack_start(self.logbutton, False) # else keep hidden if image: file = image['_src_file'] # FIXME ? textfile = self._stitch_fileextension(file, self.generator.scriptname) self._existing_file = textfile self.imageview.set_file(file) self.set_text(self.generator.filter_input(textfile.read())) else: self._existing_file = None self.set_text( self.generator.filter_input(self.generator.get_default_text())) self.textview.grab_focus() def _stitch_fileextension(self, file, basename): '''Stitches the file extension from 'basename' to the path of 'file' and returns a File object. ''' i = basename.rfind('.') j = file.path.rfind('.') return File(file.path[:j] + basename[i:]) def set_text(self, text): '''Set text in the buffer''' buffer = self.textview.get_buffer() buffer.set_text(text) buffer.set_modified(False) def get_text(self): '''Get the text from the buffer @returns: text as string ''' buffer = self.textview.get_buffer() bounds = buffer.get_bounds() return buffer.get_text(*bounds) def generate_image(self): '''Update the image based on the text in the text buffer''' self.imagefile = None self.logfile = None text = self.get_text() text = self.generator.process_input(text) try: imagefile, logfile = self.generator.generate_image(text) except: logger.exception('Could not generate image') # TODO set "error" image instead of "broken" image # TODO set exception text as log message else: self.imagefile = imagefile self.logfile = logfile self.textview.get_buffer().set_modified(False) def preview(self): '''Action for the "Preview" button''' self.generate_image() self.imageview.set_file(self.imagefile) # if None sets broken image self.logbutton.set_sensitive(not self.logfile is None) def show_log(self): '''Action for the "View Log" button''' assert self.logfile, 'BUG: no logfile set (yet)' LogFileDialog(self, self.logfile).run() def do_response_ok(self): if not self.imagefile \ or self.textview.get_buffer().get_modified(): self.generate_image() if not (self.imagefile and self.imagefile.exists()): dialog = QuestionDialog( self, _('An error occurred while generating the image.\nDo you want to save the source text anyway?' )) # T: Question prompt when e.g. equation editor encountered an error generating the image to insert if not dialog.run(): return False if self._existing_file: textfile = self._existing_file else: page = self.app_window.ui.page # XXX dir = self.app_window.ui.notebook.get_attachments_dir(page) # XXX textfile = dir.new_file(self.generator.scriptname) textfile.write(self.generator.process_input(self.get_text())) imgfile = self._stitch_fileextension(textfile, self.generator.imagename) if self.imagefile and self.imagefile.exists(): self.imagefile.rename(imgfile) elif imgfile.exists(): imgfile.remove() if self._existing_file: self.app_window.ui.reload_page() # XXX else: pageview = self.app_window.pageview pageview.insert_image(imgfile, type=self.generator.object_type, interactive=False, force=True) if self.logfile and self.logfile.exists(): self.logfile.remove() return True def destroy(self): self.generator.cleanup() Dialog.destroy(self)
def __init__(self, ui): Dialog.__init__(self, ui, _('Templates'), help='Help:Templates', buttons=gtk.BUTTONS_CLOSE, defaultwindowsize=(400, 450)) # T: Dialog title label = gtk.Label() label.set_markup('<b>'+_('Templates')+'</b>') # T: Section in dialog label.set_alignment(0.0, 0.5) self.vbox.pack_start(label, False) hbox = gtk.HBox() self.vbox.add(hbox) self.view = TemplateListView() self.view.connect('row-activated', self.on_selection_changed) hbox.add(ScrolledWindow(self.view)) vbbox = gtk.VButtonBox() vbbox.set_layout(gtk.BUTTONBOX_START) hbox.pack_start(vbbox, False) view_button = Button(stock='gtk-file', label=_('_View')) # T: button label view_button.connect('clicked', self.on_view) copy_button = Button(stock='gtk-copy') copy_button.connect('clicked', self.on_copy) edit_button = Button(stock='gtk-edit') edit_button.connect('clicked', self.on_edit) delete_button = gtk.Button(stock='gtk-remove') delete_button.connect('clicked', self.on_delete) for b in (view_button, copy_button, edit_button, delete_button): b.set_alignment(0.0, 0.5) vbbox.add(b) browse_button = Button(_('Browse')) # T: button label browse_button.connect('clicked', self.on_browse) self.add_extra_button(browse_button) self._buttonbox = vbbox self._delete_button = delete_button self.on_selection_changed()
def __init__(self, ui): Dialog.__init__(self, ui, _('Templates'), help='Help:Templates', buttons=gtk.BUTTONS_CLOSE, defaultwindowsize=(400, 450)) # T: Dialog title label = gtk.Label() label.set_markup('<b>' + _('Templates') + '</b>') # T: Section in dialog label.set_alignment(0.0, 0.5) self.vbox.pack_start(label, False) hbox = gtk.HBox() self.vbox.add(hbox) self.view = TemplateListView() self.view.connect('row-activated', self.on_selection_changed) hbox.add(ScrolledWindow(self.view)) vbbox = gtk.VButtonBox() vbbox.set_layout(gtk.BUTTONBOX_START) hbox.pack_start(vbbox, False) view_button = Button(stock='gtk-file', label=_('_View')) # T: button label view_button.connect('clicked', self.on_view) copy_button = Button(stock='gtk-copy') copy_button.connect('clicked', self.on_copy) edit_button = Button(stock='gtk-edit') edit_button.connect('clicked', self.on_edit) delete_button = gtk.Button(stock='gtk-remove') delete_button.connect('clicked', self.on_delete) for b in (view_button, copy_button, edit_button, delete_button): b.set_alignment(0.0, 0.5) vbbox.add(b) browse_button = Button(_('Browse')) # T: button label browse_button.connect('clicked', self.on_browse) self.add_extra_button(browse_button) self._buttonbox = vbbox self._delete_button = delete_button self.on_selection_changed()
def __init__(self, ui): Dialog.__init__(self, ui, _('Templates'), help='Help:Templates', buttons=gtk.BUTTONS_CLOSE, defaultwindowsize=(400, 450)) # T: Dialog title label = gtk.Label() label.set_markup('<b>' + _('Templates') + '</b>') # T: Section in dialog label.set_alignment(0.0, 0.5) self.vbox.pack_start(label, False) hbox = gtk.HBox() self.vbox.add(hbox) self.view = TemplateListView() self.view.connect('row-activated', self.on_selection_changed) hbox.add(ScrolledWindow(self.view)) vbbox = gtk.VButtonBox() vbbox.set_layout(gtk.BUTTONBOX_START) hbox.pack_start(vbbox, False) view_button = Button(stock='gtk-file', label=_('_View')) # T: button label view_button.connect('clicked', self.on_view) copy_button = Button(stock='gtk-copy') copy_button.connect('clicked', self.on_copy) edit_button = Button(stock='gtk-edit') edit_button.connect('clicked', self.on_edit) delete_button = gtk.Button(stock='gtk-remove') delete_button.connect('clicked', self.on_delete) for b in (view_button, copy_button, edit_button, delete_button): b.set_alignment(0.0, 0.5) vbbox.add(b) browse_button = Button(_('Browse')) # T: button label browse_button.connect('clicked', self.on_browse) self.add_extra_button(browse_button) self._buttonbox = vbbox self._delete_button = delete_button self.on_selection_changed() ## Same button appears in export dialog if gtk.gtk_version >= (2, 10): url_button = gtk.LinkButton( 'https://github.com/jaap-karssenberg/zim-wiki/wiki/Templates', _('Get more templates online') # T: label for button with URL ) self.vbox.pack_start(url_button, False)
def __init__(self, ui, title, generator, image=None, syntax=None, **opt): '''Constructor @param ui: L{GtkInterface} object or parent window @param title: the dialog title @param generator: an L{ImageGeneratorClass} object @param image: image data for an image in the L{TextBuffer<zim.gui.pageview.TextBuffer>} @param syntax: optional syntax name (as understood by gtksourceview) @param opt: any other arguments to pass to the L{Dialog} constructor ''' if ui_environment['platform'] == 'maemo': defaultsize = (450,480) # Use maximum available vertical space because decorations take # too much real state else: defaultsize = (450,300) Dialog.__init__(self, ui, title, defaultwindowsize=defaultsize, **opt) if ui_environment['platform'] == 'maemo': self.resize(450,480) # Force maximum dialog size under maemo, otherwise # we'll end with a too small dialog and no way to resize it self.generator = generator self.imagefile = None self.logfile = None self.vpane = VPaned() self.vpane.set_position(150) self.vbox.add(self.vpane) self.imageview = ImageView(bgcolor='#FFF', checkerboard=False) self.vpane.pack1(self.imageview, resize=True) # TODO scrolled window and option to zoom in / real size window, textview = ScrolledSourceView(syntax=syntax) self.textview = textview self.textview.set_editable(True) self.vpane.pack2(window, resize=False) hbox = gtk.HBox(spacing=5) self.vbox.pack_start(hbox, False) self.previewbutton = Button(_('_Preview'), stock='gtk-refresh') # T: button in e.g. equation editor dialog self.previewbutton.set_sensitive(False) self.previewbutton.connect_object( 'clicked', self.__class__.preview, self) hbox.pack_start(self.previewbutton, False) self.textview.get_buffer().connect('modified-changed', lambda b: self.previewbutton.set_sensitive(b.get_modified())) self.logbutton = Button(_('View _Log'), stock='gtk-file') # T: button in e.g. equation editor dialog self.logbutton.set_sensitive(False) self.logbutton.connect_object( 'clicked', self.__class__.show_log, self) if generator.uses_log_file: hbox.pack_start(self.logbutton, False) # else keep hidden self._existing_file = None if image: file = image['_src_file'] # FIXME ? textfile = self._stitch_fileextension(file, self.generator.scriptname) self._existing_file = textfile self.imageview.set_file(file) self.set_text(self.generator.filter_input(textfile.read())) self.textview.grab_focus()
class PluginsTab(gtk.HBox): def __init__(self, dialog): gtk.HBox.__init__(self, spacing=12) self.set_border_width(5) self.dialog = dialog treeview = PluginsTreeView(self.dialog.ui) treeview.connect('row-activated', self.do_row_activated) swindow = ScrolledWindow(treeview, hpolicy=gtk.POLICY_NEVER) self.pack_start(swindow, False) vbox = gtk.VBox() self.add(vbox) # Textview with scrollbars to show plugins info. Required by small screen devices swindow, textview = ScrolledTextView() textview.set_cursor_visible(False) self.textbuffer = textview.get_buffer() self.textbuffer.create_tag('bold', weight=pango.WEIGHT_BOLD) self.textbuffer.create_tag('red', foreground='#FF0000') vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) self.do_row_activated(treeview, (0,), 0) def do_row_activated(self, treeview, path, col): active = treeview.get_model()[path][0] name = treeview.get_model()[path][2] klass = treeview.get_model()[path][3] self._klass = klass logger.debug('Loading description for "%s"', name) # Insert plugin info into textview with proper formatting self.textbuffer.delete(*self.textbuffer.get_bounds()) # clear self.textbuffer.insert_with_tags_by_name( self.textbuffer.get_end_iter(), _('Name') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog self.textbuffer.insert( self.textbuffer.get_end_iter(), klass.plugin_info['name'].strip() + '\n\n') self.textbuffer.insert_with_tags_by_name( self.textbuffer.get_end_iter(), _('Description') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog self.textbuffer.insert( self.textbuffer.get_end_iter(), klass.plugin_info['description'].strip() + '\n\n') self.textbuffer.insert_with_tags_by_name( self.textbuffer.get_end_iter(), _('Dependencies') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog # Construct dependency list, missing dependencies are marked red check, dependencies = klass.check_dependencies() if not(dependencies): self.textbuffer.insert( self.textbuffer.get_end_iter(), _('No dependencies') + '\n') # T: label in plugin info in preferences dialog else: for dependency in dependencies: text, ok, required = dependency if ok: self.textbuffer.insert( self.textbuffer.get_end_iter(), u'\u2022 ' + text + ' - ' + _('OK') + '\n') # T: dependency is OK elif required: self.textbuffer.insert_with_tags_by_name( self.textbuffer.get_end_iter(), u'\u2022 ' + text +' - ' + _('Failed') + '\n', 'red') # T: dependency failed else: self.textbuffer.insert( self.textbuffer.get_end_iter(), u'\u2022 ' + text +' - ' + _('Failed') # T: dependency failed + ' ' + _('Optional') + '\n') # T: optional dependency self.textbuffer.insert_with_tags_by_name( self.textbuffer.get_end_iter(), '\n' + _('Author') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog self.textbuffer.insert( self.textbuffer.get_end_iter(), klass.plugin_info['author'].strip()) self.configure_button.set_sensitive(active and bool(klass.plugin_preferences)) self.plugin_help_button.set_sensitive('help' in klass.plugin_info) def on_help_button_clicked(self, button): self.dialog.ui.show_help(self._klass.plugin_info['help']) def on_configure_button_clicked(self, button): PluginConfigureDialog(self.dialog, self._klass).run()
def __init__(self, dialog, plugins): gtk.VBox.__init__(self, spacing=5) self.dialog = dialog self.plugins = plugins self.hbox = gtk.HBox(self, spacing=12) self.hbox.set_border_width(5) self.add(self.hbox) #~ logger.debug('Plugins that are loaded: %s' % list(plugins)) self.treeview = PluginsTreeView(self.plugins) self.treeselection = self.treeview.get_selection() self.treeselection.connect('changed', self.do_selection_changed) swindow = ScrolledWindow(self.treeview, hpolicy=gtk.POLICY_NEVER) self.hbox.pack_start(swindow, False) vbox = gtk.VBox() self.hbox.add(vbox) # Textview with scrollbars to show plugins info. Required by small screen devices swindow, textview = ScrolledTextView() textview.set_cursor_visible(False) self.textbuffer = textview.get_buffer() self.textbuffer.create_tag('bold', weight=pango.WEIGHT_BOLD) self.textbuffer.create_tag('red', foreground='#FF0000') vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) try: self.treeselection.select_path(0) except: pass # maybe loading plugins failed ## Add buttons to get and install new plugins hbox = gtk.HButtonBox() hbox.set_border_width(5) hbox.set_layout(gtk.BUTTONBOX_START) self.pack_start(hbox, False) assert hasattr(self.dialog, 'ui') open_button = gtk.Button(label=_('Open plugins folder')) open_button.connect('clicked', lambda o: self.dialog.ui.open_dir(PLUGIN_FOLDER)) hbox.pack_start(open_button, False) if gtk.gtk_version >= (2, 10) \ and gtk.pygtk_version >= (2, 10): url_button = gtk.LinkButton( 'http://zim-wiki.org/more_plugins.html', _('Get more plugins online') # T: label for button with URL ) hbox.pack_start(url_button, False)
class PluginsTab(gtk.HBox): def __init__(self, dialog, plugins): gtk.HBox.__init__(self, spacing=12) self.set_border_width(5) self.dialog = dialog self.plugins = plugins #~ logger.debug('Plugins that are loaded: %s' % list(plugins)) self.treeview = PluginsTreeView(self.plugins) self.treeview.connect('row-activated', self.do_row_activated) swindow = ScrolledWindow(self.treeview, hpolicy=gtk.POLICY_NEVER) self.pack_start(swindow, False) vbox = gtk.VBox() self.add(vbox) # Textview with scrollbars to show plugins info. Required by small screen devices swindow, textview = ScrolledTextView() textview.set_cursor_visible(False) self.textbuffer = textview.get_buffer() self.textbuffer.create_tag('bold', weight=pango.WEIGHT_BOLD) self.textbuffer.create_tag('red', foreground='#FF0000') vbox.pack_start(swindow, True) hbox = gtk.HBox(spacing=5) vbox.pack_end(hbox, False) self.plugin_help_button = \ Button(stock=gtk.STOCK_HELP, label=_('_More')) # T: Button in plugin tab self.plugin_help_button.connect('clicked', self.on_help_button_clicked) hbox.pack_start(self.plugin_help_button, False) self.configure_button = \ Button(stock=gtk.STOCK_PREFERENCES, label=_('C_onfigure')) # T: Button in plugin tab self.configure_button.connect('clicked', self.on_configure_button_clicked) hbox.pack_start(self.configure_button, False) self.do_row_activated(self.treeview, (0, ), 0) def do_row_activated(self, treeview, path, col): key, active, activatable, name, klass = treeview.get_model()[path] self._current_plugin = key logger.debug('Loading description for plugin: %s', key) # Insert plugin info into textview with proper formatting # TODO use our own widget with formatted text here... buffer = self.textbuffer def insert(text, style=None): if style: buffer.insert_with_tags_by_name(buffer.get_end_iter(), text, style) else: buffer.insert_at_cursor(text) buffer.delete(*buffer.get_bounds()) # clear insert(_('Name') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog insert(klass.plugin_info['name'].strip() + '\n\n') insert(_('Description') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog insert(klass.plugin_info['description'].strip() + '\n\n') insert(_('Dependencies') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog check, dependencies = klass.check_dependencies() if not (dependencies): insert(_('No dependencies') + '\n') # T: label in plugin info in preferences dialog else: # Construct dependency list, missing dependencies are marked red for dependency in dependencies: text, ok, required = dependency if ok: insert(u'\u2022 %s - %s\n' % (text, _('OK'))) # T: dependency is OK elif required: insert(u'\u2022 %s - %s\n' % (text, _('Failed')), 'red') # T: dependency failed else: insert(u'\u2022 %s - %s (%s)' % ( text, _('Failed'), # T: dependency failed _('Optional') # T: optional dependency )) insert('\n') insert(_('Author') + '\n', 'bold') # T: Heading in plugins tab of preferences dialog insert(klass.plugin_info['author'].strip()) self.configure_button.set_sensitive(active and bool(klass.plugin_preferences)) self.plugin_help_button.set_sensitive('help' in klass.plugin_info) def on_help_button_clicked(self, button): klass = zim.plugins.get_plugin_class(self._current_plugin) self.dialog.ui.show_help(klass.plugin_info['help']) # XXX def on_configure_button_clicked(self, button): plugin = self.plugins[self._current_plugin] PluginConfigureDialog(self.dialog, plugin).run() def select_plugin(self, name): model = self.treeview.get_model() def find(model, path, iter): if model[iter][2] == name: self.treeview.scroll_to_cell(path) self.treeview.set_cursor(path) self.do_row_activated(self.treeview, path, 0) return True return False # keep the foreach going model.foreach(find)