root/hodgestar/PythonCode/TabStripCommonPrefix/tabs-strip-common-prefix.py

Revision 373, 4.4 kB (checked in by simon, 4 years ago)

Epiphany plugin for stripping common tab prefixes.

  • Property svn:mime-type set to text/python-source
  • Property svn:eol-style set to native
Line 
1#!/usr/bin/env python
2
3#  Copyright (C) 2008 Simon Cross
4#
5#  This program is free software; you can redistribute it and/or modify
6#  it under the terms of the GNU General Public License as published by
7#  the Free Software Foundation; either version 2, or (at your option)
8#  any later version.
9#
10#  This program is distributed in the hope that it will be useful,
11#  but WITHOUT ANY WARRANTY; without even the implied warranty of
12#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#  GNU General Public License for more details.
14#
15#  You should have received a copy of the GNU General Public License
16#  along with this program; if not, write to the Free Software
17#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19"""A simple extension to strip common prefixes from tab titles."""
20
21import string
22import gtk
23
24def find_longest_prefix(titles):
25    """Find longest prefix from list of titles. Return "" if not common prefix."""
26    if not titles:
27        return ""
28
29    remaining_titles = list(titles)
30    length = 0
31
32    while True:
33        length += 1
34        prefix_map = {}
35
36        for title in remaining_titles:
37            if len(title) < length:
38                continue
39            prefix = title[:length]
40            prefix_map.setdefault(prefix,[])
41            prefix_map[prefix].append(title)
42
43        for prefix, title_list in prefix_map.items():
44            if len(title_list) <= 1:
45                del prefix_map[prefix]
46
47        if len(prefix_map) == 0:
48            length -= 1
49            break
50
51        remaining_titles = list()
52        for title_list in prefix_map.values():
53            remaining_titles.extend(title_list)
54
55        assert remaining_titles
56
57    return remaining_titles[0][:length]
58
59def find_common_prefixes(tabs_to_titles, strip_chars):
60    """Modify values to remove common prefixes containing end_chars."""
61    tabs_to_titles = tabs_to_titles.copy()
62    unprocessed = set(tabs_to_titles.keys())
63
64    while True:
65        prefix = find_longest_prefix([tabs_to_titles[x] for x in unprocessed])
66        if prefix == "":
67            break
68        stripped_prefix = prefix.rstrip(strip_chars)
69        for tab in list(unprocessed):
70            title = tabs_to_titles[tab]
71            if title.startswith(prefix):
72                unprocessed.remove(tab)
73                if title != prefix:
74                    tabs_to_titles[tab] = title[len(stripped_prefix):]
75
76    return tabs_to_titles
77
78class TabStripExtension(object):
79    def __init__(self):
80        self.handler_ids = {}
81
82    def set_tab_title(self, notebook, tab, title):
83        """Set notebook tab title -- is there a better way?"""
84        tab_label = notebook.get_tab_label(tab)
85        labels = [x for x in tab_label.get_children() if isinstance(x, gtk.Label)]
86        if labels:
87            labels[0].set_label(title)
88
89    def handler(self, notebook, page, page_numargs):
90        """When an event occurs, check to see if there are new common prefixes."""
91        tabs = notebook.get_children()
92        strip_chars = string.letters + string.digits
93
94        tabs_to_titles = dict([(t, t.props.title) for t in tabs])
95        tabs_to_titles = find_common_prefixes(tabs_to_titles, strip_chars)
96
97        for tab, title in tabs_to_titles.items():
98            self.set_tab_title(notebook, tab, title)
99
100    def attach_window(self, window):
101        """Attach to a window."""
102        notebook = window.get_notebook()
103        self.handler_ids[notebook] = notebook.connect_after("switch-page", self.handler)
104
105    def detach_window(self, window):
106        """Detach from a window."""
107        notebook = window.get_notebook()
108        notebook.disconnect(self.handler_ids[notebook])
109        del self.handler_ids[notebook]
110
111def test_prefix_finding():
112    """Test prefix finding code."""
113    assert find_longest_prefix(["", "abc", "abab"]) == "ab"
114    assert find_longest_prefix(["abcd", "abcd"]) == "abcd"
115    assert find_longest_prefix(["foo - bar", "foo - eep", "other"]) == "foo - "
116
117    s = string.letters + string.digits
118    assert find_common_prefixes({ 1: "abcd", 2: "abcd" }, s) == { 1: "abcd", 2: "abcd" }
119    assert find_common_prefixes({ 1: "foo - bar", 2: "foo - eep" }, s) == { 1: "bar", 2: "eep" }
120    assert find_common_prefixes({ 1: "foo - bar", 2: "foo - eep", 3: "fop" }, s) == { 1: "bar", 2: "eep", 3: "fop" }
121
122if __name__ == "__main__":
123    test_prefix_finding()
124else:
125    import epiphany
126    ext = TabStripExtension()
127    attach_window = ext.attach_window
128    detach_window = ext.detach_window
Note: See TracBrowser for help on using the browser.