• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/samba-3.0.25b/source/python/
1#!/usr/bin/python
2#
3# Browse a Python dictionary in a two pane graphical interface written
4# in GTK.
5#
6# The GtkDictBrowser class is supposed to be generic enough to allow
7# applications to override enough methods and produce a
8# domain-specific browser provided the information is presented as a
9# Python dictionary.
10#
11# Possible applications:
12#
13#   - Windows registry browser
14#   - SPOOLSS printerdata browser
15#   - tdb file browser
16#
17
18from gtk import *
19import string, re
20
21class GtkDictBrowser:
22
23    def __init__(self, dict):
24        self.dict = dict
25
26        # This variable stores a list of (regexp, function) used to
27        # convert the raw value data to a displayable string.
28
29        self.get_value_text_fns = []
30        self.get_key_text = lambda x: x
31
32        # We can filter the list of keys displayed using a regex
33
34        self.filter_regex = ""
35
36    # Create and configure user interface widgets.  A string argument is
37    # used to set the window title.
38
39    def build_ui(self, title):
40        win = GtkWindow()
41        win.set_title(title)
42
43        win.connect("destroy", mainquit)
44
45        hpaned = GtkHPaned()
46        win.add(hpaned)
47        hpaned.set_border_width(5)
48        hpaned.show()
49
50        vbox = GtkVBox()
51        hpaned.add1(vbox)
52        vbox.show()
53
54        scrolled_win = GtkScrolledWindow()
55        scrolled_win.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
56        vbox.pack_start(scrolled_win)
57        scrolled_win.show()
58
59        hbox = GtkHBox()
60        vbox.pack_end(hbox, expand = 0, padding = 5)
61        hbox.show()
62
63        label = GtkLabel("Filter:")
64        hbox.pack_start(label, expand = 0, padding = 5)
65        label.show()
66
67        self.entry = GtkEntry()
68        hbox.pack_end(self.entry, padding = 5)
69        self.entry.show()
70
71        self.entry.connect("activate", self.filter_activated)
72
73        self.list = GtkList()
74        self.list.set_selection_mode(SELECTION_MULTIPLE)
75        self.list.set_selection_mode(SELECTION_BROWSE)
76        scrolled_win.add_with_viewport(self.list)
77        self.list.show()
78
79        self.list.connect("select_child", self.key_selected)
80
81        scrolled_win = GtkScrolledWindow()
82        scrolled_win.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
83        hpaned.add2(scrolled_win)
84        scrolled_win.set_usize(500,400)
85        scrolled_win.show()
86
87        self.text = GtkText()
88        self.text.set_editable(FALSE)
89        scrolled_win.add_with_viewport(self.text)
90        self.text.show()
91
92        self.text.connect("event", self.event_handler)
93
94        self.menu = GtkMenu()
95        self.menu.show()
96
97        self.font = load_font("fixed")
98
99        self.update_keylist()
100
101        win.show()
102
103    # Add a key to the left hand side of the user interface
104
105    def add_key(self, key):
106        display_key = self.get_key_text(key)
107        list_item = GtkListItem(display_key)
108        list_item.set_data("raw_key", key) # Store raw key in item data
109        self.list.add(list_item)
110        list_item.show()
111
112    # Event handler registered by build_ui()
113
114    def event_handler(self, event, menu):
115        return FALSE
116
117    # Set the text to appear in the right hand side of the user interface
118
119    def set_value_text(self, item):
120
121        # Clear old old value in text window
122
123        self.text.delete_text(0, self.text.get_length())
124
125        if type(item) == str:
126
127            # The text widget has trouble inserting text containing NULL
128            # characters.
129
130            item = string.replace(item, "\x00", ".")
131
132            self.text.insert(self.font, None, None, item)
133
134        else:
135
136            # A non-text item
137
138            self.text.insert(self.font, None, None, repr(item))
139
140    # This function is called when a key is selected in the left hand side
141    # of the user interface.
142
143    def key_selected(self, list, list_item):
144        key = list_item.children()[0].get()
145
146        # Look for a match in the value display function list
147
148        text = self.dict[list_item.get_data("raw_key")]
149
150        for entry in self.get_value_text_fns:
151            if re.match(entry[0], key):
152                text = entry[1](text)
153                break
154
155        self.set_value_text(text)
156
157    # Refresh the key list by removing all items and re-inserting them.
158    # Items are only inserted if they pass through the filter regexp.
159
160    def update_keylist(self):
161        self.list.remove_items(self.list.children())
162        self.set_value_text("")
163        for k in self.dict.keys():
164            if re.match(self.filter_regex, k):
165                self.add_key(k)
166
167    # Invoked when the user hits return in the filter text entry widget.
168
169    def filter_activated(self, entry):
170        self.filter_regex = entry.get_text()
171        self.update_keylist()
172
173    # Register a key display function
174
175    def register_get_key_text_fn(self, fn):
176        self.get_key_text = fn
177
178    # Register a value display function
179
180    def register_get_value_text_fn(self, regexp, fn):
181        self.get_value_text_fns.append((regexp, fn))
182
183#
184# A utility function to convert a string to the standard hex + ascii format.
185# To display all values in hex do:
186#   register_get_value_text_fn("", gtkdictbrowser.hex_string)
187#
188
189def hex_string(data):
190    """Return a hex dump of a string as a string.
191
192    The output produced is in the standard 16 characters per line hex +
193    ascii format:
194
195    00000000: 40 00 00 00 00 00 00 00  40 00 00 00 01 00 04 80  @....... @.......
196    00000010: 01 01 00 00 00 00 00 01  00 00 00 00              ........ ....
197    """
198
199    pos = 0                             # Position in data
200    line = 0                            # Line of data
201
202    hex = ""                            # Hex display
203    ascii = ""                          # ASCII display
204
205    result = ""
206
207    while pos < len(data):
208
209	# Start with header
210
211	if pos % 16 == 0:
212            hex = "%08x: " % (line * 16)
213            ascii = ""
214
215        # Add character
216
217	hex = hex + "%02x " % (ord(data[pos]))
218
219        if ord(data[pos]) < 32 or ord(data[pos]) > 176:
220            ascii = ascii + '.'
221        else:
222            ascii = ascii + data[pos]
223
224        pos = pos + 1
225
226        # Add separator if half way
227
228	if pos % 16 == 8:
229            hex = hex + " "
230            ascii = ascii + " "
231
232        # End of line
233
234	if pos % 16 == 0:
235            result = result + "%s %s\n" % (hex, ascii)
236            line = line + 1
237
238    # Leftover bits
239
240    if pos % 16 != 0:
241
242        # Pad hex string
243
244        for i in range(0, (16 - (pos % 16))):
245            hex = hex + "   "
246
247        # Half way separator
248
249        if (pos % 16) < 8:
250            hex = hex + " "
251
252        result = result + "%s %s\n" % (hex, ascii)
253
254    return result
255
256# For testing purposes, create a fixed dictionary to browse with
257
258if __name__ == "__main__":
259
260    dict = {"chicken": "ham", "spam": "fun", "subdict": {"a": "b", "c": "d"}}
261
262    db = GtkDictBrowser(dict)
263
264    db.build_ui("GtkDictBrowser")
265
266    # Override Python's handling of ctrl-c so we can break out of the
267    # gui from the command line.
268
269    import signal
270    signal.signal(signal.SIGINT, signal.SIG_DFL)
271
272    mainloop()
273