Esempio n. 1
0
class IssueView(BottomView, IPreferencesMonitor):
    """
	"""

    _log = getLogger("IssueView")

    label = "Issues"
    icon = gtk.STOCK_DIALOG_INFO
    scope = View.SCOPE_EDITOR

    def __init__(self, context, editor):
        BottomView.__init__(self, context)
        self._editor = editor
        self._handlers = {}

    def init(self, context):
        self._log.debug("init")

        self._preferences = Preferences()
        self._show_tasks = self._preferences.get_bool("IssuesShowTasks", True)
        self._show_warnings = self._preferences.get_bool(
            "IssuesShowWarnings", True)

        self._context = context

        self._icons = {
            Issue.SEVERITY_WARNING:
            pixbuf_new_from_file(find_resource("icons/warning.png")),
            Issue.SEVERITY_ERROR:
            pixbuf_new_from_file(find_resource("icons/error.png")),
            Issue.SEVERITY_INFO:
            None,
            Issue.SEVERITY_TASK:
            pixbuf_new_from_file(find_resource("icons/task.png"))
        }

        self._store = gtk.ListStore(Pixbuf, str, str, object)

        self._view = gtk.TreeView(self._store)

        column = gtk.TreeViewColumn()
        column.set_title("Message")

        pixbuf_renderer = gtk.CellRendererPixbuf()
        column.pack_start(pixbuf_renderer, False)
        column.add_attribute(pixbuf_renderer, "pixbuf", 0)

        text_renderer = gtk.CellRendererText()
        column.pack_start(text_renderer, True)
        column.add_attribute(text_renderer, "markup", 1)

        self._view.append_column(column)
        self._view.insert_column_with_attributes(-1,
                                                 "File",
                                                 gtk.CellRendererText(),
                                                 markup=2)
        self._handlers[self._view] = self._view.connect(
            "row-activated", self._on_row_activated)

        self._scr = gtk.ScrolledWindow()

        self._scr.add(self._view)
        self._scr.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self._scr.set_shadow_type(gtk.SHADOW_IN)

        self.pack_start(self._scr, True)

        # toolbar

        self._button_warnings = gtk.ToggleToolButton()
        self._button_warnings.set_tooltip_text("Show/Hide Warnings")
        image = gtk.Image()
        image.set_from_file(find_resource("icons/warning.png"))
        self._button_warnings.set_icon_widget(image)
        self._button_warnings.set_active(self._show_warnings)
        self._handlers[self._button_warnings] = self._button_warnings.connect(
            "toggled", self.__on_warnings_toggled)

        self._button_tasks = gtk.ToggleToolButton()
        self._button_tasks.set_tooltip_text("Show/Hide Tasks")
        imageTask = gtk.Image()
        imageTask.set_from_file(find_resource("icons/task.png"))
        self._button_tasks.set_icon_widget(imageTask)
        self._button_tasks.set_active(self._show_tasks)
        self._handlers[self._button_tasks] = self._button_tasks.connect(
            "toggled", self.__on_tasks_toggled)

        toolbar = gtk.Toolbar()
        toolbar.set_orientation(gtk.ORIENTATION_VERTICAL)
        toolbar.set_style(gtk.TOOLBAR_ICONS)
        toolbar.set_icon_size(gtk.ICON_SIZE_MENU)
        toolbar.insert(self._button_warnings, -1)
        toolbar.insert(self._button_tasks, -1)

        self.pack_start(toolbar, False)

        self._issues = []
        self._preferences.register_monitor(self)

        self._log.debug("init finished")

    def _on_row_activated(self, view, path, column):
        """
		A row has been double-clicked on
		"""
        issue = self._store.get(self._store.get_iter(path), 3)[0]

        self._context.activate_editor(issue.file)

        #~ # FIXME: this doesn't work correctly
        #~ if not self._context.active_editor is None:
        #~ self._context.active_editor.select(issue.start, issue.end)
        self._editor.select(issue.start, issue.end)

    def _on_value_changed(self, key, value):
        if key == "IssuesShowWarnings" or key == "IssuesShowTasks":
            # update filter
            self._store.clear()
            for issue, local in self._issues:
                self.__append_issue_filtered(issue, local)

    def __on_tasks_toggled(self, togglebutton):
        self._show_tasks = togglebutton.get_active()
        self._preferences.set("IssuesShowTasks", self._show_tasks)

    def __on_warnings_toggled(self, togglebutton):
        self._show_warnings = togglebutton.get_active()
        self._preferences.set("IssuesShowWarnings", self._show_warnings)

    def clear(self):
        """
		Remove all issues from the view
		"""
        self.assure_init()
        self._store.clear()
        self._issues = []

    def append_issue(self, issue, local=True):
        """
		Append a new Issue to the view

		@param issue: the Issue object
		@param local: indicates whether the Issue occured in the edited file or not
		"""
        self.assure_init()
        self._issues.append((issue, local))
        self.__append_issue_filtered(issue, local)

    def __append_issue_filtered(self, issue, local):
        if issue.severity == Issue.SEVERITY_WARNING:
            if self._show_warnings:
                self.__do_append_issue(issue, local)
        elif issue.severity == Issue.SEVERITY_TASK:
            if self._show_tasks:
                self.__do_append_issue(issue, local)
        else:
            self.__do_append_issue(issue, local)

    def __do_append_issue(self, issue, local):
        if local:
            message = issue.message
            filename = escape(issue.file.basename)
        else:
            message = "<span color='%s'>%s</span>" % (self._preferences.get(
                "LightForeground", "#7f7f7f"), issue.message)
            filename = "<span color='%s'>%s</span>" % (self._preferences.get(
                "LightForeground", "#7f7f7f"), issue.file.basename)
        self._store.append(
            [self._icons[issue.severity], message, filename, issue])

    def destroy(self):
        del self._editor
        self._preferences.remove_monitor(self)
        for obj in self._handlers:
            obj.disconnect(self._handlers[obj])
        BottomView.destroy(self)
Esempio n. 2
0
class BaseOutlineView(SideView):
	"""
	Base class for the BibTeX and LaTeX outline views
	"""

	__log = getLogger("BaseOutlineView")

	label = "Outline"
	scope = View.SCOPE_EDITOR

	def __init__(self, context, editor):
		SideView.__init__(self, context)
		self._editor = editor
		self._base_handlers = {}

	@property
	def icon(self):
		image = gtk.Image()
		image.set_from_file(find_resource("icons/outline.png"))
		return image

	def init(self, context):
		self._log.debug("init")

		self._context = context

		self._preferences = Preferences()

		# toolbar

		btn_follow = gtk.ToggleToolButton(gtk.STOCK_CONNECT)
		btn_follow.set_tooltip_text("Follow Editor")
		btn_follow.set_active(self._preferences.get_bool("ConnectOutlineToEditor", True))
		self._base_handlers[btn_follow] = btn_follow.connect("toggled", self._on_follow_toggled)

		btn_expand = gtk.ToolButton(gtk.STOCK_ZOOM_IN)
		btn_expand.set_tooltip_text("Expand All")
		self._base_handlers[btn_expand] = btn_expand.connect("clicked", self._on_expand_clicked)

		btn_collapse = gtk.ToolButton(gtk.STOCK_ZOOM_OUT)
		btn_collapse.set_tooltip_text("Collapse All")
		self._base_handlers[btn_collapse] = btn_collapse.connect("clicked", self._on_collapse_clicked)

		self._toolbar = gtk.Toolbar()
		self._toolbar.set_style(gtk.TOOLBAR_ICONS)
		# TODO: why is this deprecated?
		self._toolbar.set_icon_size(gtk.ICON_SIZE_MENU)
		self._toolbar.insert(btn_follow, -1)
		self._toolbar.insert(gtk.SeparatorToolItem(), -1)
		self._toolbar.insert(btn_expand, -1)
		self._toolbar.insert(btn_collapse, -1)
		self._toolbar.insert(gtk.SeparatorToolItem(), -1)

		self.pack_start(self._toolbar, False)

		# tree view

		column = gtk.TreeViewColumn()

		pixbuf_renderer = gtk.CellRendererPixbuf()
		column.pack_start(pixbuf_renderer, False)
		column.add_attribute(pixbuf_renderer, "pixbuf", 1)

		text_renderer = gtk.CellRendererText()
		column.pack_start(text_renderer, True)
		column.add_attribute(text_renderer, "markup", 0)

		self._offset_map = OutlineOffsetMap()

		self._store = gtk.TreeStore(str, gtk.gdk.Pixbuf, object)	# label, icon, node object

		self._view = gtk.TreeView(self._store)
		self._view.append_column(column)
		self._view.set_headers_visible(False)
		self._cursor_changed_id = self._view.connect("cursor-changed", self._on_cursor_changed)
		self._base_handlers[self._view] = self._view.connect("row-activated", self._on_row_activated)

		scrolled = gtk.ScrolledWindow()
		scrolled.add(self._view)
		scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)

		self.pack_start(scrolled, True)

		# this holds a list of the currently expanded paths
		self._expandedPaths = None

		self.show_all()

	def _on_follow_toggled(self, toggle_button):
		value = toggle_button.get_active()
		self._preferences.set("ConnectOutlineToEditor", value)

	def _on_expand_clicked(self, button):
		self._view.expand_all()

	def _on_collapse_clicked(self, button):
		self._view.collapse_all()

	def select_path_by_offset(self, offset):
		"""
		Select the path corresponding to a given offset in the source

		Called by the Editor
		"""
		self.assure_init()

		try:
			path = self._offset_map.lookup(offset)
			self._select_path(path)
		except KeyError:
			pass

	def _save_state(self):
		"""
		Save the current expand state
		"""
		self._expanded_paths = []
		self._view.map_expanded_rows(self._save_state_map_function)

	def _save_state_map_function(self, view, path):
		"""
		Mapping function for saving the current expand state
		"""
		self._expanded_paths.append(path)

	def _restore_state(self):
		"""
		Restore the last expand state
		"""
		self._view.collapse_all()

		if self._expanded_paths:
			for path in self._expanded_paths:
				self._view.expand_to_path(path)
		else:
			self._view.expand_to_path((0,))

	def _on_cursor_changed(self, view):
		store, it = view.get_selection().get_selected()
		if not it:
			return

		outline_node = store.get_value(it, 2)

		self._on_node_selected(outline_node)

	def _on_row_activated(self, view, path, column):
		it = self._store.get_iter(path)
		node = self._store.get(it, 2)[0]

		self._on_node_activated(node)

	def _select_path(self, path):
		"""
		Expand a path and select the last node
		"""
		# disconnect from 'cursor-changed'
		self._view.disconnect(self._cursor_changed_id)

		# select path
		self._view.expand_to_path(path)
		self._view.set_cursor(path)

		# connect to 'cursor-changed' again
		self._cursor_changed_id = self._view.connect("cursor-changed", self._on_cursor_changed)

	#
	# methods to be overridden by the subclass
	#

	def _on_node_selected(self, node):
		"""
		To be overridden
		"""

	def _on_node_activated(self, node):
		"""
		To be overridden
		"""

	def set_outline(self, outline):
		"""
		Load a new outline model

		To be overridden
		"""

	def destroy(self):
		self._view.disconnect(self._cursor_changed_id)
		for obj in self._base_handlers:
			obj.disconnect(self._base_handlers[obj])
		del self._editor
		SideView.destroy(self)
Esempio n. 3
0
class BaseOutlineView(SideView):
    """
	Base class for the BibTeX and LaTeX outline views
	"""

    __log = getLogger("BaseOutlineView")

    label = "Outline"
    scope = View.SCOPE_EDITOR

    def __init__(self, context, editor):
        SideView.__init__(self, context)
        self._editor = editor
        self._base_handlers = {}

    @property
    def icon(self):
        image = gtk.Image()
        image.set_from_file(find_resource("icons/outline.png"))
        return image

    def init(self, context):
        self._log.debug("init")

        self._context = context

        self._preferences = Preferences()

        # toolbar

        btn_follow = gtk.ToggleToolButton(gtk.STOCK_CONNECT)
        btn_follow.set_tooltip_text("Follow Editor")
        btn_follow.set_active(
            self._preferences.get_bool("ConnectOutlineToEditor", True))
        self._base_handlers[btn_follow] = btn_follow.connect(
            "toggled", self._on_follow_toggled)

        btn_expand = gtk.ToolButton(gtk.STOCK_ZOOM_IN)
        btn_expand.set_tooltip_text("Expand All")
        self._base_handlers[btn_expand] = btn_expand.connect(
            "clicked", self._on_expand_clicked)

        btn_collapse = gtk.ToolButton(gtk.STOCK_ZOOM_OUT)
        btn_collapse.set_tooltip_text("Collapse All")
        self._base_handlers[btn_collapse] = btn_collapse.connect(
            "clicked", self._on_collapse_clicked)

        self._toolbar = gtk.Toolbar()
        self._toolbar.set_style(gtk.TOOLBAR_ICONS)
        # TODO: why is this deprecated?
        self._toolbar.set_icon_size(gtk.ICON_SIZE_MENU)
        self._toolbar.insert(btn_follow, -1)
        self._toolbar.insert(gtk.SeparatorToolItem(), -1)
        self._toolbar.insert(btn_expand, -1)
        self._toolbar.insert(btn_collapse, -1)
        self._toolbar.insert(gtk.SeparatorToolItem(), -1)

        self.pack_start(self._toolbar, False)

        # tree view

        column = gtk.TreeViewColumn()

        pixbuf_renderer = gtk.CellRendererPixbuf()
        column.pack_start(pixbuf_renderer, False)
        column.add_attribute(pixbuf_renderer, "pixbuf", 1)

        text_renderer = gtk.CellRendererText()
        column.pack_start(text_renderer, True)
        column.add_attribute(text_renderer, "markup", 0)

        self._offset_map = OutlineOffsetMap()

        self._store = gtk.TreeStore(str, gtk.gdk.Pixbuf,
                                    object)  # label, icon, node object

        self._view = gtk.TreeView(self._store)
        self._view.append_column(column)
        self._view.set_headers_visible(False)
        self._cursor_changed_id = self._view.connect("cursor-changed",
                                                     self._on_cursor_changed)
        self._base_handlers[self._view] = self._view.connect(
            "row-activated", self._on_row_activated)

        scrolled = gtk.ScrolledWindow()
        scrolled.add(self._view)
        scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)

        self.pack_start(scrolled, True)

        # this holds a list of the currently expanded paths
        self._expandedPaths = None

        self.show_all()

    def _on_follow_toggled(self, toggle_button):
        value = toggle_button.get_active()
        self._preferences.set("ConnectOutlineToEditor", value)

    def _on_expand_clicked(self, button):
        self._view.expand_all()

    def _on_collapse_clicked(self, button):
        self._view.collapse_all()

    def select_path_by_offset(self, offset):
        """
		Select the path corresponding to a given offset in the source
		
		Called by the Editor
		"""
        self.assure_init()

        try:
            path = self._offset_map.lookup(offset)
            self._select_path(path)
        except KeyError:
            pass

    def _save_state(self):
        """
		Save the current expand state
		"""
        self._expanded_paths = []
        self._view.map_expanded_rows(self._save_state_map_function)

    def _save_state_map_function(self, view, path):
        """
		Mapping function for saving the current expand state
		"""
        self._expanded_paths.append(path)

    def _restore_state(self):
        """
		Restore the last expand state
		"""
        self._view.collapse_all()

        if self._expanded_paths:
            for path in self._expanded_paths:
                self._view.expand_to_path(path)
        else:
            self._view.expand_to_path((0, ))

    def _on_cursor_changed(self, view):
        store, it = view.get_selection().get_selected()
        if not it:
            return

        outline_node = store.get_value(it, 2)

        self._on_node_selected(outline_node)

    def _on_row_activated(self, view, path, column):
        it = self._store.get_iter(path)
        node = self._store.get(it, 2)[0]

        self._on_node_activated(node)

    def _select_path(self, path):
        """
		Expand a path and select the last node
		"""
        # disconnect from 'cursor-changed'
        self._view.disconnect(self._cursor_changed_id)

        # select path
        self._view.expand_to_path(path)
        self._view.set_cursor(path)

        # connect to 'cursor-changed' again
        self._cursor_changed_id = self._view.connect("cursor-changed",
                                                     self._on_cursor_changed)

    #
    # methods to be overridden by the subclass
    #

    def _on_node_selected(self, node):
        """
		To be overridden
		"""

    def _on_node_activated(self, node):
        """
		To be overridden
		"""

    def set_outline(self, outline):
        """
		Load a new outline model
		
		To be overridden
		"""

    def destroy(self):
        self._view.disconnect(self._cursor_changed_id)
        for obj in self._base_handlers:
            obj.disconnect(self._base_handlers[obj])
        del self._editor
        SideView.destroy(self)
Esempio n. 4
0
class IssueView(BottomView, IPreferencesMonitor):
	"""
	"""

	_log = getLogger("IssueView")

	label = "Issues"
	icon = gtk.STOCK_DIALOG_INFO
	scope = View.SCOPE_EDITOR

	def __init__(self, context, editor):
		BottomView.__init__(self, context)
		self._editor = editor
		self._handlers = {}

	def init(self, context):
		self._log.debug("init")

		self._preferences = Preferences()
		self._show_tasks = self._preferences.get_bool("IssuesShowTasks", True)
		self._show_warnings = self._preferences.get_bool("IssuesShowWarnings", True)

		self._context = context

		self._icons = { Issue.SEVERITY_WARNING : pixbuf_new_from_file(find_resource("icons/warning.png")),
						Issue.SEVERITY_ERROR : pixbuf_new_from_file(find_resource("icons/error.png")),
						Issue.SEVERITY_INFO : None,
						Issue.SEVERITY_TASK : pixbuf_new_from_file(find_resource("icons/task.png")) }

		self._store = gtk.ListStore(Pixbuf, str, str, object)

		self._view = gtk.TreeView(self._store)

		column = gtk.TreeViewColumn()
		column.set_title("Message")

		pixbuf_renderer = gtk.CellRendererPixbuf()
		column.pack_start(pixbuf_renderer, False)
		column.add_attribute(pixbuf_renderer, "pixbuf", 0)

		text_renderer = gtk.CellRendererText()
		column.pack_start(text_renderer, True)
		column.add_attribute(text_renderer, "markup", 1)

		self._view.append_column(column)
		self._view.insert_column_with_attributes(-1, "File", gtk.CellRendererText(), markup=2)
		self._handlers[self._view] = self._view.connect("row-activated", self._on_row_activated)

		self._scr = gtk.ScrolledWindow()

		self._scr.add(self._view)
		self._scr.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
		self._scr.set_shadow_type(gtk.SHADOW_IN)

		self.pack_start(self._scr, True)

		# toolbar

		self._button_warnings = gtk.ToggleToolButton()
		self._button_warnings.set_tooltip_text("Show/Hide Warnings")
		image = gtk.Image()
		image.set_from_file(find_resource("icons/warning.png"))
		self._button_warnings.set_icon_widget(image)
		self._button_warnings.set_active(self._show_warnings)
		self._handlers[self._button_warnings] = self._button_warnings.connect("toggled", self.__on_warnings_toggled)

		self._button_tasks = gtk.ToggleToolButton()
		self._button_tasks.set_tooltip_text("Show/Hide Tasks")
		imageTask = gtk.Image()
		imageTask.set_from_file(find_resource("icons/task.png"))
		self._button_tasks.set_icon_widget(imageTask)
		self._button_tasks.set_active(self._show_tasks)
		self._handlers[self._button_tasks] = self._button_tasks.connect("toggled", self.__on_tasks_toggled)

		toolbar = gtk.Toolbar()
		toolbar.set_orientation(gtk.ORIENTATION_VERTICAL)
		toolbar.set_style(gtk.TOOLBAR_ICONS)
		toolbar.set_icon_size(gtk.ICON_SIZE_MENU)
		toolbar.insert(self._button_warnings, -1)
		toolbar.insert(self._button_tasks, -1)

		self.pack_start(toolbar, False)

		self._issues = []
		self._preferences.register_monitor(self)

		self._log.debug("init finished")

	def _on_row_activated(self, view, path, column):
		"""
		A row has been double-clicked on
		"""
		issue = self._store.get(self._store.get_iter(path), 3)[0]

		self._context.activate_editor(issue.file)

		#~ # FIXME: this doesn't work correctly
		#~ if not self._context.active_editor is None:
			#~ self._context.active_editor.select(issue.start, issue.end)
		self._editor.select(issue.start, issue.end)

	def _on_value_changed(self, key, value):
		if key == "IssuesShowWarnings" or key == "IssuesShowTasks":
			# update filter
			self._store.clear()
			for issue, local in self._issues:
				self.__append_issue_filtered(issue, local)

	def __on_tasks_toggled(self, togglebutton):
		self._show_tasks = togglebutton.get_active()
		self._preferences.set("IssuesShowTasks", self._show_tasks)

	def __on_warnings_toggled(self, togglebutton):
		self._show_warnings = togglebutton.get_active()
		self._preferences.set("IssuesShowWarnings", self._show_warnings)

	def clear(self):
		"""
		Remove all issues from the view
		"""
		self.assure_init()
		self._store.clear()
		self._issues = []

	def append_issue(self, issue, local=True):
		"""
		Append a new Issue to the view

		@param issue: the Issue object
		@param local: indicates whether the Issue occured in the edited file or not
		"""
		self.assure_init()
		self._issues.append((issue, local))
		self.__append_issue_filtered(issue, local)

	def __append_issue_filtered(self, issue, local):
		if issue.severity == Issue.SEVERITY_WARNING:
			if self._show_warnings:
				self.__do_append_issue(issue, local)
		elif issue.severity == Issue.SEVERITY_TASK:
			if self._show_tasks:
				self.__do_append_issue(issue, local)
		else:
			self.__do_append_issue(issue, local)

	def __do_append_issue(self, issue, local):
		if local:
			message = issue.message
			filename = escape(issue.file.basename)
		else:
			message = "<span color='%s'>%s</span>" % (self._preferences.get("LightForeground", "#7f7f7f"), issue.message)
			filename = "<span color='%s'>%s</span>" % (self._preferences.get("LightForeground", "#7f7f7f"), issue.file.basename)
		self._store.append([self._icons[issue.severity], message, filename, issue])

	def destroy(self):
		del self._editor
		self._preferences.remove_monitor(self)
		for obj in self._handlers:
			obj.disconnect(self._handlers[obj])
		BottomView.destroy(self)