Example #1
0
    def do_activate(self):
        icon = Gtk.Image.new_from_stock(Gtk.STOCK_YES, Gtk.IconSize.MENU)
        self.widget = TodoPanel(self.window, self.matches, self.allowed_types, self.settings)
        self.widget.show_all()

        if self.settings["side-panel"].lower() == "true":
            panel = self.window.get_side_panel()
        else:
            panel = self.window.get_bottom_panel()
        panel.add_item(self.widget, "TodoBottomPanel", _("TODO List"), icon)
        panel.activate_item(self.widget)
        self.do_update_state()
Example #2
0
class TodoPlugin(GObject.Object, Gedit.WindowActivatable):
    __gtype_name__ = "TodoPanel"
    window = GObject.property(type=Gedit.Window)
    dir_hash = {}
    dirs = []
    files = []
    matches = {}
    settings = {}

    def __init__(self):
        GObject.Object.__init__(self)
        self.load_settings()
        self.allowed_extensions = re.split("[\\s\\.;\\|:]", self.settings["extensions"])
        self.allowed_types = re.split("[\\s\\.;\\|:]", self.settings["types"])
        for i in self.allowed_types:
            self.matches[i] = {}
        self.widget = None

    def do_activate(self):
        icon = Gtk.Image.new_from_stock(Gtk.STOCK_YES, Gtk.IconSize.MENU)
        self.widget = TodoPanel(self.window, self.matches, self.allowed_types, self.settings)
        self.widget.show_all()

        if self.settings["side-panel"].lower() == "true":
            panel = self.window.get_side_panel()
        else:
            panel = self.window.get_bottom_panel()
        panel.add_item(self.widget, "TodoBottomPanel", _("TODO List"), icon)
        panel.activate_item(self.widget)
        self.do_update_state()

    def do_deactivate(self):
        if self.settings["side-panel"].lower() == "true":
            panel = self.window.get_side_panel()
        else:
            panel = self.window.get_bottom_panel()
        panel.remove_item(self.widget)

    def do_update_state(self):
        if self.widget:
            # get dirs that need to be checked
            self.update_dirs()
            # get files that need to be checked
            self.update_files()
            # scan files
            self.walk()
            # update panel
            self.widget.update()
        if self.settings["side-panel"].lower() == "true":
            panel = self.window.get_side_panel()
        else:
            panel = self.window.get_bottom_panel()
        panel.activate_item(self.widget)

    def on_tab_removed(self, window, tab, data=None):
        self.do_update_state()

    def do_create_configure_widget(self):
        widget = ConfigurationWidget(self.settings)
        return widget

    def save_settings(self):
        config = os.path.join(os.path.dirname(__file__), "config.xml")
        root = cElementTree.Element("settings")

        with open(config, "rt") as f:
            tree = ElementTree.parse(f)

        for node in tree.iter():
            name = node.attrib.get("name")
            default = node.attrib.get("default")
            cElementTree.SubElement(root, "setting", name=name, value=self.settings[name], default=default)
        tree = cElementTree.ElementTree(root)
        tree.write(config)

    def load_settings(self):
        self.settings = {}
        config = os.path.join(os.path.dirname(__file__), "config.xml")
        with open(config, "rt") as f:
            tree = ElementTree.parse(f)
        for node in tree.iter():
            name = str(node.attrib.get("name"))
            value = str(node.attrib.get("value"))
            default = str(node.attrib.get("default"))
            if re.search("\\d+", value):
                value = int(value)
            if re.search("\\d+", default):
                default = int(default)
            self.settings[name] = value if value else default

    def update_dirs(self):
        self.files = [
            doc.get_uri_for_display()
            for doc in self.window.get_documents()
            if os.path.exists(doc.get_uri_for_display())
        ]
        self.dirs = [f.rpartition("/")[0] for f in self.files]
        self.dirs = list(set([i for i in self.dirs if i]))

        def matches(dirs, name):
            for d in dirs:
                if name.startswith(d):
                    return True
            return False

        remove = []
        for tag in self.matches.keys():
            for f in self.matches[tag]:
                name = f.partition("file://")[2]
                if not matches(self.dirs, name):
                    remove.append(f)
            self.matches[tag] = {key: value for key, value in self.matches[tag].items() if key not in remove}

    def update_files(self):
        check = []
        for d in self.dirs:
            tmp = compute_dir_index(d, self.files, self.allowed_extensions)
            if d in self.dir_hash.keys():
                diff = compute_diff(tmp, self.dir_hash[d])
            else:
                diff = compute_diff(tmp, {"files": [], "subdirs": [], "index": []})
            self.dir_hash[d] = tmp
            check += [i for i in diff["check"] if i.rpartition(".")[2] in self.allowed_extensions]
            for tag in self.matches.keys():
                self.matches[tag] = {
                    key: value
                    for key, value in self.matches[tag].items()
                    if key.partition("file://")[2] not in diff["remove"]
                }
        self.files = list(set(check))

    def walk(self):
        match_re = "^(.*?)({})(:|[ \t]*-)?[ \t]*([^\n]*?)(\n|$)".format("|".join(self.allowed_types))
        for fi in self.files:
            with open(fi, "r") as f:
                fi = "file://" + fi
                for i in self.allowed_types:
                    self.matches[i][fi] = []
                line = 0
                for i in re.findall(match_re, f.read(), re.DOTALL | re.MULTILINE):
                    line += len(i[0].split("\n"))
                    if fi in self.matches[i[1]].keys():
                        self.matches[i[1]][fi].append((line, i[3]))
                    else:
                        self.matches[i[1]][fi] = [(line, i[3])]