Esempio n. 1
0
    def __init__(self, ui, vcs):
        Dialog.__init__(self, ui, _('Save Version'), # T: dialog title
            button=(None, 'gtk-save'), help='Plugins:Version Control')
        self.vcs = vcs

        self.vbox.pack_start(
            gtk.Label(_("Please enter a comment for this version")), False)  # T: Dialog text

        vpaned = VPaned()
        self.vbox.add(vpaned)

        window, self.textview = ScrolledTextView(_('Saved version from zim'))
            # T: default version comment in the "save version" dialog
        self.textview.set_editable(True)
        vpaned.add1(window)

        vbox = gtk.VBox()
        vpaned.add2(vbox)

        label = gtk.Label('<b>'+_('Details')+'</b>')
            # T: section for version details in "save version" dialog
        label.set_use_markup(True)
        label.set_alignment(0, 0.5)
        vbox.pack_start(label, False)

        status = self.vcs.get_status()
        window, textview = ScrolledTextView(text=''.join(status), monospace=True)
        vbox.add(window)
Esempio n. 2
0
    def __init__(self,
                 widget,
                 label,
                 generator,
                 image_file=None,
                 text='',
                 syntax=None):
        title = _(
            'Edit %s'
        ) % label  # T: dialog title, %s is the object name like "Equation"
        Dialog.__init__(self, widget, title, defaultwindowsize=(450, 300))
        self.generator = generator
        self.log_file = None
        self.image_file = image_file
        self.result = None, None

        self.vpane = VPaned()
        self.vpane.set_position(150)
        self.vbox.pack_start(self.vpane, True, True, 0)

        self.imageview = ImageView(bgcolor='#FFF')
        swin = ScrolledWindow(self.imageview)
        swin.set_size_request(200, 50)
        self.vpane.pack1(swin, 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, True, 0)

        self.previewbutton = Gtk.Button.new_with_mnemonic(_('_Preview'))
        # T: button in e.g. equation editor dialog
        self.previewbutton.set_sensitive(False)
        self.previewbutton.connect('clicked', lambda o: self.update_image())
        hbox.pack_start(self.previewbutton, False, True, 0)

        self.textview.get_buffer().connect(
            'modified-changed',
            lambda b: self.previewbutton.set_sensitive(b.get_modified()))

        self.logbutton = Gtk.Button.new_with_mnemonic(_('View _Log'))
        # T: button in e.g. equation editor dialog
        self.logbutton.set_sensitive(False)
        self.logbutton.connect('clicked', lambda o: self.show_log())
        hbox.pack_start(self.logbutton, False, True, 0)

        self.set_text(text)
        self.imageview.set_file(self.image_file)  # if None sets broken image
        self.textview.grab_focus()
Esempio n. 3
0
	def __init__(self, ui, window_ext, vcs):
		Dialog.__init__(self, ui, _('Save Version'), # T: dialog title
			button=(None, 'gtk-save'), help='Plugins:Version Control')
		self.window_ext = window_ext
		self.vcs = vcs

		self.vbox.pack_start(
			gtk.Label(_("Please enter a comment for this version")), False)  # T: Dialog text

		vpaned = VPaned()
		self.vbox.add(vpaned)

		window, self.textview = ScrolledTextView(_('Saved version from zim'))
			# T: default version comment in the "save version" dialog
		self.textview.set_editable(True)
		vpaned.add1(window)

		vbox = gtk.VBox()
		vpaned.add2(vbox)

		label = gtk.Label('<b>'+_('Details')+'</b>')
			# T: section for version details in "save version" dialog
		label.set_use_markup(True)
		label.set_alignment(0, 0.5)
		vbox.pack_start(label, False)

		status = self.vcs.get_status()
		window, textview = ScrolledTextView(text=''.join(status), monospace=True)
		vbox.add(window)
Esempio n. 4
0
	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()
Esempio n. 5
0
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)
Esempio n. 6
0
    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()
Esempio n. 7
0
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, parent, vcs, notebook, page=None):
        Dialog.__init__(
            self,
            parent,
            _('Versions'),  # T: dialog title
            buttons=Gtk.ButtonsType.CLOSE,
            help='Plugins:Version Control')
        self.notebook = notebook
        self.vcs = vcs
        self._side_by_side_app = get_side_by_side_app()

        self.uistate.setdefault('windowsize', (600, 500), check=value_is_coord)
        self.uistate.setdefault('vpanepos', 300)

        self.vpaned = VPaned()
        self.vpaned.set_position(self.uistate['vpanepos'])
        self.vbox.pack_start(self.vpaned, True, True, 0)

        vbox = Gtk.VBox(spacing=5)
        self.vpaned.pack1(vbox, resize=True)

        # Choice between whole notebook or page
        label = Gtk.Label(label='<b>' + _('Versions') +
                          ':</b>')  # section label
        label.set_use_markup(True)
        label.set_alignment(0, 0.5)
        vbox.pack_start(label, False, True, 0)

        self.notebook_radio = Gtk.RadioButton.new_with_mnemonic_from_widget(
            None, _('Complete _notebook'))
        # T: Option in versions dialog to show version for complete notebook
        self.page_radio = Gtk.RadioButton.new_with_mnemonic_from_widget(
            self.notebook_radio,
            _('_Page') + ':')
        # T: Option in versions dialog to show version for single page
        #~ recursive_box = Gtk.CheckButton.new_with_mnemonic('Recursive')
        vbox.pack_start(self.notebook_radio, False, True, 0)

        # Page entry
        hbox = Gtk.HBox(spacing=5)
        vbox.pack_start(hbox, False, True, 0)
        hbox.pack_start(self.page_radio, False, True, 0)
        self.page_entry = PageEntry(self.notebook)
        if page:
            self.page_entry.set_path(page)
        hbox.pack_start(self.page_entry, False, True, 0)

        # View annotated button
        ann_button = Gtk.Button.new_with_mnemonic(
            _('View _Annotated'))  # T: Button label
        ann_button.connect('clicked', lambda o: self.show_annotated())
        hbox.pack_start(ann_button, False, True, 0)

        # Help text
        label = Gtk.Label(label='<i>\n' + _('''\
Select a version to see changes between that version and the current
state. Or select multiple versions to see changes between those versions.
''').strip() + '</i>')  # T: Help text in versions dialog
        label.set_use_markup(True)
        #~ label.set_alignment(0, 0.5)
        vbox.pack_start(label, False, True, 0)

        # Version list
        self.versionlist = VersionsTreeView()
        self.versionlist.load_versions(vcs.list_versions())
        scrolled = ScrolledWindow(self.versionlist)
        vbox.add(scrolled)

        col = self.uistate.setdefault('sortcol', self.versionlist.REV_SORT_COL)
        order = self.uistate.setdefault('sortorder', Gtk.SortType.DESCENDING)
        try:
            self.versionlist.get_model().set_sort_column_id(col, order)
        except:
            logger.exception('Invalid sort column: %s %s', col, order)

        # -----
        vbox = Gtk.VBox(spacing=5)
        self.vpaned.pack2(vbox, resize=False)

        label = Gtk.Label(label='<b>' + _('Comment') +
                          '</b>')  # T: version details
        label.set_use_markup(True)
        label.set_alignment(0.0, 0.5)
        vbox.pack_start(label, False, True, 0)

        # Comment text
        window, textview = ScrolledTextView()
        self.comment_textview = textview
        vbox.add(window)

        buttonbox = Gtk.HButtonBox()
        buttonbox.set_layout(Gtk.ButtonBoxStyle.END)
        vbox.pack_start(buttonbox, False, True, 0)

        # Restore version button
        revert_button = Gtk.Button.new_with_mnemonic(
            _('_Restore Version'))  # T: Button label
        revert_button.connect('clicked', lambda o: self.restore_version())
        buttonbox.add(revert_button)

        # Notebook Changes button
        diff_button = Gtk.Button.new_with_mnemonic(_('Show _Changes'))
        # T: button in versions dialog for diff
        diff_button.connect('clicked', lambda o: self.show_changes())
        buttonbox.add(diff_button)

        # Compare page button
        comp_button = Gtk.Button.new_with_mnemonic(_('_Side by Side'))
        # T: button in versions dialog for side by side comparison
        comp_button.connect('clicked', lambda o: self.show_side_by_side())
        buttonbox.add(comp_button)

        # UI interaction between selections and buttons

        def on_row_activated(o, iter, path):
            model = self.versionlist.get_model()
            comment = model[iter][VersionsTreeView.MSG_COL]
            buffer = textview.get_buffer()
            buffer.set_text(comment)

        self.versionlist.connect('row-activated', on_row_activated)

        def on_ui_change(o):
            usepage = self.page_radio.get_active()
            self.page_entry.set_sensitive(usepage)
            ann_button.set_sensitive(usepage)

            # side by side comparison can only be done for one page
            # revert can only be done to one version, not multiple
            selection = self.versionlist.get_selection()
            model, rows = selection.get_selected_rows()
            if not rows:
                revert_button.set_sensitive(False)
                diff_button.set_sensitive(False)
                comp_button.set_sensitive(False)
            elif len(rows) == 1:
                revert_button.set_sensitive(usepage)
                diff_button.set_sensitive(True)
                comp_button.set_sensitive(
                    bool(usepage and self._side_by_side_app))
            else:
                revert_button.set_sensitive(False)
                diff_button.set_sensitive(True)
                comp_button.set_sensitive(
                    bool(usepage and self._side_by_side_app))

        def on_page_change(o):
            pagesource = self._get_file()
            if pagesource:
                self.versionlist.load_versions(
                    vcs.list_versions(self._get_file()))

        def on_book_change(o):
            self.versionlist.load_versions(vcs.list_versions())

        self.page_radio.connect('toggled', on_ui_change)
        self.notebook_radio.connect('toggled', on_book_change)
        self.page_radio.connect('toggled', on_page_change)
        self.page_entry.connect('changed', on_page_change)
        selection = self.versionlist.get_selection()
        selection.connect('changed', on_ui_change)

        # select last version
        self.versionlist.get_selection().select_path((0, ))
        col = self.versionlist.get_column(0)
        self.versionlist.row_activated(Gtk.TreePath((0, )), col)
class VersionsDialog(Dialog):
    def __init__(self, parent, vcs, notebook, page=None):
        Dialog.__init__(
            self,
            parent,
            _('Versions'),  # T: dialog title
            buttons=Gtk.ButtonsType.CLOSE,
            help='Plugins:Version Control')
        self.notebook = notebook
        self.vcs = vcs
        self._side_by_side_app = get_side_by_side_app()

        self.uistate.setdefault('windowsize', (600, 500), check=value_is_coord)
        self.uistate.setdefault('vpanepos', 300)

        self.vpaned = VPaned()
        self.vpaned.set_position(self.uistate['vpanepos'])
        self.vbox.pack_start(self.vpaned, True, True, 0)

        vbox = Gtk.VBox(spacing=5)
        self.vpaned.pack1(vbox, resize=True)

        # Choice between whole notebook or page
        label = Gtk.Label(label='<b>' + _('Versions') +
                          ':</b>')  # section label
        label.set_use_markup(True)
        label.set_alignment(0, 0.5)
        vbox.pack_start(label, False, True, 0)

        self.notebook_radio = Gtk.RadioButton.new_with_mnemonic_from_widget(
            None, _('Complete _notebook'))
        # T: Option in versions dialog to show version for complete notebook
        self.page_radio = Gtk.RadioButton.new_with_mnemonic_from_widget(
            self.notebook_radio,
            _('_Page') + ':')
        # T: Option in versions dialog to show version for single page
        #~ recursive_box = Gtk.CheckButton.new_with_mnemonic('Recursive')
        vbox.pack_start(self.notebook_radio, False, True, 0)

        # Page entry
        hbox = Gtk.HBox(spacing=5)
        vbox.pack_start(hbox, False, True, 0)
        hbox.pack_start(self.page_radio, False, True, 0)
        self.page_entry = PageEntry(self.notebook)
        if page:
            self.page_entry.set_path(page)
        hbox.pack_start(self.page_entry, False, True, 0)

        # View annotated button
        ann_button = Gtk.Button.new_with_mnemonic(
            _('View _Annotated'))  # T: Button label
        ann_button.connect('clicked', lambda o: self.show_annotated())
        hbox.pack_start(ann_button, False, True, 0)

        # Help text
        label = Gtk.Label(label='<i>\n' + _('''\
Select a version to see changes between that version and the current
state. Or select multiple versions to see changes between those versions.
''').strip() + '</i>')  # T: Help text in versions dialog
        label.set_use_markup(True)
        #~ label.set_alignment(0, 0.5)
        vbox.pack_start(label, False, True, 0)

        # Version list
        self.versionlist = VersionsTreeView()
        self.versionlist.load_versions(vcs.list_versions())
        scrolled = ScrolledWindow(self.versionlist)
        vbox.add(scrolled)

        col = self.uistate.setdefault('sortcol', self.versionlist.REV_SORT_COL)
        order = self.uistate.setdefault('sortorder', Gtk.SortType.DESCENDING)
        try:
            self.versionlist.get_model().set_sort_column_id(col, order)
        except:
            logger.exception('Invalid sort column: %s %s', col, order)

        # -----
        vbox = Gtk.VBox(spacing=5)
        self.vpaned.pack2(vbox, resize=False)

        label = Gtk.Label(label='<b>' + _('Comment') +
                          '</b>')  # T: version details
        label.set_use_markup(True)
        label.set_alignment(0.0, 0.5)
        vbox.pack_start(label, False, True, 0)

        # Comment text
        window, textview = ScrolledTextView()
        self.comment_textview = textview
        vbox.add(window)

        buttonbox = Gtk.HButtonBox()
        buttonbox.set_layout(Gtk.ButtonBoxStyle.END)
        vbox.pack_start(buttonbox, False, True, 0)

        # Restore version button
        revert_button = Gtk.Button.new_with_mnemonic(
            _('_Restore Version'))  # T: Button label
        revert_button.connect('clicked', lambda o: self.restore_version())
        buttonbox.add(revert_button)

        # Notebook Changes button
        diff_button = Gtk.Button.new_with_mnemonic(_('Show _Changes'))
        # T: button in versions dialog for diff
        diff_button.connect('clicked', lambda o: self.show_changes())
        buttonbox.add(diff_button)

        # Compare page button
        comp_button = Gtk.Button.new_with_mnemonic(_('_Side by Side'))
        # T: button in versions dialog for side by side comparison
        comp_button.connect('clicked', lambda o: self.show_side_by_side())
        buttonbox.add(comp_button)

        # UI interaction between selections and buttons

        def on_row_activated(o, iter, path):
            model = self.versionlist.get_model()
            comment = model[iter][VersionsTreeView.MSG_COL]
            buffer = textview.get_buffer()
            buffer.set_text(comment)

        self.versionlist.connect('row-activated', on_row_activated)

        def on_ui_change(o):
            usepage = self.page_radio.get_active()
            self.page_entry.set_sensitive(usepage)
            ann_button.set_sensitive(usepage)

            # side by side comparison can only be done for one page
            # revert can only be done to one version, not multiple
            selection = self.versionlist.get_selection()
            model, rows = selection.get_selected_rows()
            if not rows:
                revert_button.set_sensitive(False)
                diff_button.set_sensitive(False)
                comp_button.set_sensitive(False)
            elif len(rows) == 1:
                revert_button.set_sensitive(usepage)
                diff_button.set_sensitive(True)
                comp_button.set_sensitive(
                    bool(usepage and self._side_by_side_app))
            else:
                revert_button.set_sensitive(False)
                diff_button.set_sensitive(True)
                comp_button.set_sensitive(
                    bool(usepage and self._side_by_side_app))

        def on_page_change(o):
            pagesource = self._get_file()
            if pagesource:
                self.versionlist.load_versions(
                    vcs.list_versions(self._get_file()))

        def on_book_change(o):
            self.versionlist.load_versions(vcs.list_versions())

        self.page_radio.connect('toggled', on_ui_change)
        self.notebook_radio.connect('toggled', on_book_change)
        self.page_radio.connect('toggled', on_page_change)
        self.page_entry.connect('changed', on_page_change)
        selection = self.versionlist.get_selection()
        selection.connect('changed', on_ui_change)

        # select last version
        self.versionlist.get_selection().select_path((0, ))
        col = self.versionlist.get_column(0)
        self.versionlist.row_activated(Gtk.TreePath((0, )), col)

    def save_uistate(self):
        self.uistate['vpanepos'] = self.vpaned.get_position()

        col, order = self.versionlist.get_model().get_sort_column_id()
        self.uistate['sortcol'] = col
        self.uistate['sortorder'] = order

    def _get_file(self):
        if self.notebook_radio.get_active():
            return None
        else:
            path = self.page_entry.get_path()
            if path:
                page = self.notebook.get_page(path)
            else:
                return None  # TODO error message valid page name?

            if page \
            and page.source_file is not None \
            and page.source_file.ischild(self.vcs.root):
                return page.source
            else:
                return None  # TODO error message ?

    def show_annotated(self):
        # TODO check for gannotated
        file = self._get_file()
        assert not file is None
        annotated = self.vcs.annotated(file)
        TextDialog(self, _('Annotated Page Source'), annotated).run()
        # T: dialog title

    def restore_version(self):
        file = self._get_file()
        path = self.page_entry.get_path()
        version = self.versionlist.get_versions()[0]
        assert not file is None
        if QuestionDialog(
                self,
            (
                _('Restore page to saved version?'
                  ),  # T: Confirmation question
                _('Do you want to restore page: %(page)s\n'
                  'to saved version: %(version)s ?\n\n'
                  'All changes since the last saved version will be lost !') %
                {
                    'page': path.name,
                    'version': str(version)
                }
                # T: Detailed question, "%(page)s" is replaced by the page, "%(version)s" by the version id
            )).run():
            self.vcs.revert(file, version)
            page = self.notebook.get_page(path)
            page.check_source_changed()

    def show_changes(self):
        # TODO check for gdiff
        file = self._get_file()
        versions = self.versionlist.get_versions()
        diff = self.vcs.diff(file=file,
                             versions=versions) or ['=== No Changes\n']
        TextDialog(self, _('Changes'), diff).run()
        # T: dialog title

    def show_side_by_side(self):
        file = self._get_file()
        versions = self.versionlist.get_versions()
        if not (file and versions):
            raise AssertionError

        files = [self._get_tmp_file(file, v) for v in versions]
        if len(files) == 1:
            tmp = TmpFile(file.basename + '--CURRENT', persistent=True)
            # need to be persistent, else it is cleaned up before application spawned
            tmp.writelines(file.readlines())
            files.insert(0, tmp)

        self._side_by_side_app.spawn(files)

    def _get_tmp_file(self, file, version):
        text = self.vcs.cat(file, version)
        tmp = TmpFile(file.basename + '--REV%s' % version, persistent=True)
        # need to be persistent, else it is cleaned up before application spawned
        tmp.writelines(text)
        return tmp
Esempio n. 10
0
class ImageGeneratorDialog(Dialog):
    '''Dialog that provides text input and an image view
	for showing previews for an L{ImageGeneratorClass} implementation.
	'''
    @classmethod
    def run_dialog_for_model(cls, widget, model, label, syntax):
        text, image_file = cls(widget, label,
                               model.generator, model.image_file,
                               model.get_text(), syntax).run()
        if text is not None:
            model.set_from_generator(text, image_file)
        model.generator.cleanup()

    def __init__(self,
                 widget,
                 label,
                 generator,
                 image_file=None,
                 text='',
                 syntax=None):
        title = _(
            'Edit %s'
        ) % label  # T: dialog title, %s is the object name like "Equation"
        Dialog.__init__(self, widget, title, defaultwindowsize=(450, 300))
        self.generator = generator
        self.log_file = None
        self.image_file = image_file
        self.result = None, None

        self.vpane = VPaned()
        self.vpane.set_position(150)
        self.vbox.pack_start(self.vpane, True, True, 0)

        self.imageview = ImageView(bgcolor='#FFF')
        swin = ScrolledWindow(self.imageview)
        swin.set_size_request(200, 50)
        self.vpane.pack1(swin, 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, True, 0)

        self.previewbutton = Gtk.Button.new_with_mnemonic(_('_Preview'))
        # T: button in e.g. equation editor dialog
        self.previewbutton.set_sensitive(False)
        self.previewbutton.connect('clicked', lambda o: self.update_image())
        hbox.pack_start(self.previewbutton, False, True, 0)

        self.textview.get_buffer().connect(
            'modified-changed',
            lambda b: self.previewbutton.set_sensitive(b.get_modified()))

        self.logbutton = Gtk.Button.new_with_mnemonic(_('View _Log'))
        # T: button in e.g. equation editor dialog
        self.logbutton.set_sensitive(False)
        self.logbutton.connect('clicked', lambda o: self.show_log())
        hbox.pack_start(self.logbutton, False, True, 0)

        self.set_text(text)
        self.imageview.set_file(self.image_file)  # if None sets broken image
        self.textview.grab_focus()

    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()
        start, end = buffer.get_bounds()
        text = start.get_text(end)
        return self.generator.check_user_input(text)

    def update_image(self):
        text = self.get_text()

        try:
            self.image_file, self.log_file = self.generator.generate_image(
                text)
        except Error as error:
            self.image_file, self.log_file = None, None
            show_error(error)

        self.textview.get_buffer().set_modified(False)
        self.imageview.set_file(self.image_file)  # if None sets broken image
        self.logbutton.set_sensitive(self.log_file is not None)

    def show_log(self):
        assert self.logfile, 'BUG: no logfile set (yet)'
        LogFileDialog(self, self.logfile).run()

    def do_response_ok(self):
        buffer = self.textview.get_buffer()
        if buffer.get_modified():
            self.update_image()

        if not (self.image_file and self.image_file.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

        self.result = (self.get_text(), self.image_file)

        return True
Esempio n. 11
0
    def __init__(self, ui, vcs):
        Dialog.__init__(self, ui, _('Versions'), # T: dialog title
            buttons=gtk.BUTTONS_CLOSE, help='Plugins:Version Control')
        self.vcs = vcs

        self.uistate.setdefault('windowsize', (600, 500), check=value_is_coord)
        self.uistate.setdefault('vpanepos', 300)

        self.vpaned = VPaned()
        self.vpaned.set_position(self.uistate['vpanepos'])
        self.vbox.add(self.vpaned)

        vbox = gtk.VBox(spacing=5)
        self.vpaned.pack1(vbox, resize=True)

        # Choice between whole notebook or page
        label = gtk.Label('<b>'+_('Versions')+':</b>') # section label
        label.set_use_markup(True)
        label.set_alignment(0, 0.5)
        vbox.pack_start(label, False)

        self.notebook_radio = gtk.RadioButton(None, _('Complete _notebook'))
            # T: Option in versions dialog to show version for complete notebook
        self.page_radio = gtk.RadioButton(self.notebook_radio, _('_Page')+':')
            # T: Option in versions dialog to show version for single page
        #~ recursive_box = gtk.CheckButton('Recursive')
        vbox.pack_start(self.notebook_radio, False)

        # Page entry
        hbox = gtk.HBox(spacing=5)
        vbox.pack_start(hbox, False)
        hbox.pack_start(self.page_radio, False)
        self.page_entry = PageEntry(self.ui.notebook)
        self.page_entry.set_path(ui.page)
        hbox.pack_start(self.page_entry, False)

        # View annotated button
        ann_button = gtk.Button(_('View _Annotated')) # T: Button label
        ann_button.connect('clicked', lambda o: self.show_annotated())
        hbox.pack_start(ann_button, False)

        # Help text
        label = gtk.Label('<i>\n'+_( '''\
Select a version to see changes between that version and the current
state. Or select multiple versions to see changes between those versions.
''' ).strip()+'</i>') # T: Help text in versions dialog
        label.set_use_markup(True)
        #~ label.set_alignment(0, 0.5)
        vbox.pack_start(label, False)

        # Version list
        self.versionlist = VersionsTreeView()
        self.versionlist.load_versions(vcs.list_versions())
        scrolled = ScrolledWindow(self.versionlist)
        vbox.add(scrolled)

        # -----
        vbox = gtk.VBox(spacing=5)
        self.vpaned.pack2(vbox, resize=False)

        label = gtk.Label('<b>'+_('Comment')+'</b>') # T: version details
        label.set_use_markup(True)
        label.set_alignment(0.0, 0.5)
        vbox.pack_start(label, False)

        # Comment text
        window, textview = ScrolledTextView()
        self.comment_textview = textview
        vbox.add(window)

        buttonbox = gtk.HButtonBox()
        buttonbox.set_layout(gtk.BUTTONBOX_END)
        vbox.pack_start(buttonbox, False)

        # Restore version button
        revert_button = gtk.Button(_('_Restore Version')) # T: Button label
        revert_button.connect('clicked', lambda o: self.restore_version())
        buttonbox.add(revert_button)

        # Notebook Changes button
        diff_button = gtk.Button(_('Show _Changes'))
            # T: button in versions dialog for diff
        diff_button.connect('clicked', lambda o: self.show_changes())
        buttonbox.add(diff_button)

        # Compare page button
        comp_button = gtk.Button(_('_Side by Side'))
            # T: button in versions dialog for side by side comparison
        comp_button.connect('clicked', lambda o: self.show_side_by_side())
        buttonbox.add(comp_button)


        # UI interaction between selections and buttons

        def on_row_activated(o, iter, path):
            model = self.versionlist.get_model()
            comment = model[iter][VersionsTreeView.MSG_COL]
            buffer = textview.get_buffer()
            buffer.set_text(comment)

        self.versionlist.connect('row-activated', on_row_activated)


        def on_ui_change(o):
            usepage = self.page_radio.get_active()
            self.page_entry.set_sensitive(usepage)
            ann_button.set_sensitive(usepage)

            # side by side comparison can only be done for one page
            # revert can only be done to one version, not multiple
            selection = self.versionlist.get_selection()
            model, rows = selection.get_selected_rows()
            if not rows:
                revert_button.set_sensitive(False)
                diff_button.set_sensitive(False)
                comp_button.set_sensitive(False)
            elif len(rows) == 1:
                revert_button.set_sensitive(usepage)
                diff_button.set_sensitive(True)
                comp_button.set_sensitive(usepage)
            else:
                revert_button.set_sensitive(False)
                diff_button.set_sensitive(True)
                comp_button.set_sensitive(usepage)

        def on_page_change(o):
            pagesource = self._get_file()
            if pagesource:
                self.versionlist.load_versions(vcs.list_versions(self._get_file()))

        def on_book_change(o):
            self.versionlist.load_versions(vcs.list_versions())

        self.page_radio.connect('toggled', on_ui_change)
        self.notebook_radio.connect('toggled', on_book_change)
        self.page_radio.connect('toggled', on_page_change)
        self.page_entry.connect('changed', on_page_change)
        selection = self.versionlist.get_selection()
        selection.connect('changed', on_ui_change)

        # select last version
        self.versionlist.get_selection().select_path((0,))
        col = self.versionlist.get_column(0)
        self.versionlist.row_activated(0, col)
Esempio n. 12
0
class VersionsDialog(Dialog):

    # TODO put state in uistate ..

    def __init__(self, ui, vcs):
        Dialog.__init__(self, ui, _('Versions'), # T: dialog title
            buttons=gtk.BUTTONS_CLOSE, help='Plugins:Version Control')
        self.vcs = vcs

        self.uistate.setdefault('windowsize', (600, 500), check=value_is_coord)
        self.uistate.setdefault('vpanepos', 300)

        self.vpaned = VPaned()
        self.vpaned.set_position(self.uistate['vpanepos'])
        self.vbox.add(self.vpaned)

        vbox = gtk.VBox(spacing=5)
        self.vpaned.pack1(vbox, resize=True)

        # Choice between whole notebook or page
        label = gtk.Label('<b>'+_('Versions')+':</b>') # section label
        label.set_use_markup(True)
        label.set_alignment(0, 0.5)
        vbox.pack_start(label, False)

        self.notebook_radio = gtk.RadioButton(None, _('Complete _notebook'))
            # T: Option in versions dialog to show version for complete notebook
        self.page_radio = gtk.RadioButton(self.notebook_radio, _('_Page')+':')
            # T: Option in versions dialog to show version for single page
        #~ recursive_box = gtk.CheckButton('Recursive')
        vbox.pack_start(self.notebook_radio, False)

        # Page entry
        hbox = gtk.HBox(spacing=5)
        vbox.pack_start(hbox, False)
        hbox.pack_start(self.page_radio, False)
        self.page_entry = PageEntry(self.ui.notebook)
        self.page_entry.set_path(ui.page)
        hbox.pack_start(self.page_entry, False)

        # View annotated button
        ann_button = gtk.Button(_('View _Annotated')) # T: Button label
        ann_button.connect('clicked', lambda o: self.show_annotated())
        hbox.pack_start(ann_button, False)

        # Help text
        label = gtk.Label('<i>\n'+_( '''\
Select a version to see changes between that version and the current
state. Or select multiple versions to see changes between those versions.
''' ).strip()+'</i>') # T: Help text in versions dialog
        label.set_use_markup(True)
        #~ label.set_alignment(0, 0.5)
        vbox.pack_start(label, False)

        # Version list
        self.versionlist = VersionsTreeView()
        self.versionlist.load_versions(vcs.list_versions())
        scrolled = ScrolledWindow(self.versionlist)
        vbox.add(scrolled)

        # -----
        vbox = gtk.VBox(spacing=5)
        self.vpaned.pack2(vbox, resize=False)

        label = gtk.Label('<b>'+_('Comment')+'</b>') # T: version details
        label.set_use_markup(True)
        label.set_alignment(0.0, 0.5)
        vbox.pack_start(label, False)

        # Comment text
        window, textview = ScrolledTextView()
        self.comment_textview = textview
        vbox.add(window)

        buttonbox = gtk.HButtonBox()
        buttonbox.set_layout(gtk.BUTTONBOX_END)
        vbox.pack_start(buttonbox, False)

        # Restore version button
        revert_button = gtk.Button(_('_Restore Version')) # T: Button label
        revert_button.connect('clicked', lambda o: self.restore_version())
        buttonbox.add(revert_button)

        # Notebook Changes button
        diff_button = gtk.Button(_('Show _Changes'))
            # T: button in versions dialog for diff
        diff_button.connect('clicked', lambda o: self.show_changes())
        buttonbox.add(diff_button)

        # Compare page button
        comp_button = gtk.Button(_('_Side by Side'))
            # T: button in versions dialog for side by side comparison
        comp_button.connect('clicked', lambda o: self.show_side_by_side())
        buttonbox.add(comp_button)


        # UI interaction between selections and buttons

        def on_row_activated(o, iter, path):
            model = self.versionlist.get_model()
            comment = model[iter][VersionsTreeView.MSG_COL]
            buffer = textview.get_buffer()
            buffer.set_text(comment)

        self.versionlist.connect('row-activated', on_row_activated)


        def on_ui_change(o):
            usepage = self.page_radio.get_active()
            self.page_entry.set_sensitive(usepage)
            ann_button.set_sensitive(usepage)

            # side by side comparison can only be done for one page
            # revert can only be done to one version, not multiple
            selection = self.versionlist.get_selection()
            model, rows = selection.get_selected_rows()
            if not rows:
                revert_button.set_sensitive(False)
                diff_button.set_sensitive(False)
                comp_button.set_sensitive(False)
            elif len(rows) == 1:
                revert_button.set_sensitive(usepage)
                diff_button.set_sensitive(True)
                comp_button.set_sensitive(usepage)
            else:
                revert_button.set_sensitive(False)
                diff_button.set_sensitive(True)
                comp_button.set_sensitive(usepage)

        def on_page_change(o):
            pagesource = self._get_file()
            if pagesource:
                self.versionlist.load_versions(vcs.list_versions(self._get_file()))

        def on_book_change(o):
            self.versionlist.load_versions(vcs.list_versions())

        self.page_radio.connect('toggled', on_ui_change)
        self.notebook_radio.connect('toggled', on_book_change)
        self.page_radio.connect('toggled', on_page_change)
        self.page_entry.connect('changed', on_page_change)
        selection = self.versionlist.get_selection()
        selection.connect('changed', on_ui_change)

        # select last version
        self.versionlist.get_selection().select_path((0,))
        col = self.versionlist.get_column(0)
        self.versionlist.row_activated(0, col)

    def save_uistate(self):
        self.uistate['vpanepos'] = self.vpaned.get_position()

    def _get_file(self):
        if self.notebook_radio.get_active():
            if self.ui.page.modified:
                self.ui.save_page()

            return None
        else:
            path = self.page_entry.get_path()
            if path:
                page = self.ui.notebook.get_page(path)
                if page == self.ui.page and page.modified:
                    self.ui.save_page()
            else:
                return None # TODO error message valid page name?

            if page \
            and hasattr(page, 'source') \
            and isinstance(page.source, File) \
            and page.source.ischild(self.vcs.root):
                return page.source
            else:
                return None # TODO error message ?

    def show_annotated(self):
        # TODO check for gannotated
        file = self._get_file()
        assert not file is None
        annotated = self.vcs.get_annotated(file)
        TextDialog(self, _('Annotated Page Source'), annotated).run()
            # T: dialog title

    def restore_version(self):
        file = self._get_file()
        path = self.page_entry.get_path()
        version = self.versionlist.get_versions()[0]
        assert not file is None
        if QuestionDialog(self, (
            _('Restore page to saved version?'), # T: Confirmation question
            _('Do you want to restore page: %(page)s\n'
              'to saved version: %(version)s ?\n\n'
              'All changes since the last saved version will be lost !')
              % {'page': path.name, 'version': str(version)}
              # T: Detailed question, "%(page)s" is replaced by the page, "%(version)s" by the version id
        ) ).run():
            self.vcs.revert(file=file, version=version)
            self.ui.reload_page()
            # TODO trigger vcs autosave here?

    def show_changes(self):
        # TODO check for gdiff
        file = self._get_file()
        versions = self.versionlist.get_versions()
        diff = self.vcs.get_diff(file=file, versions=versions)
        TextDialog(self, _('Changes'), diff).run()
            # T: dialog title

    def show_side_by_side(self):
        print 'TODO - need config for an application like meld'
Esempio n. 13
0
    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()