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)
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)
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)
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)