* the printing code should now be back to the working state it was
[Samba.git] / source / python / gtdbtool
blob792cdeecc0b1080ab272b99b79de7acc4fbe3592
1 #!/usr/bin/env python
3 from gtk import *
4 import sys
5 import tdb
6 import string
7 import re
10 # The gdbtool user interface. The design here is to keep all the gtk stuff
11 # separate from the tdb stuff so all the user interface magic is stored
12 # here.
15 class gtdbtool:
17 # Initialise the user interface. A dictionary argument is passed
18 # in which is the dictionary to display keys and values on the left
19 # hand and right hand side of the user interface respectively."""
21 def __init__(self, dict):
22 self.dict = dict
23 self.value_display_fns = []
24 self.filter_regex = ""
26 # Create and configure user interface widgets. A string argument is
27 # used to set the window title.
29 def build_ui(self, title):
30 win = GtkWindow()
31 win.set_title(title)
33 win.connect("destroy", mainquit)
35 hpaned = GtkHPaned()
36 win.add(hpaned)
37 hpaned.set_border_width(5)
38 hpaned.show()
40 vbox = GtkVBox()
41 hpaned.add1(vbox)
42 vbox.show()
44 scrolled_win = GtkScrolledWindow()
45 scrolled_win.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
46 vbox.pack_start(scrolled_win)
47 scrolled_win.show()
49 hbox = GtkHBox()
50 vbox.pack_end(hbox, expand = 0, padding = 5)
51 hbox.show()
53 label = GtkLabel("Filter:")
54 hbox.pack_start(label, expand = 0, padding = 5)
55 label.show()
57 self.entry = GtkEntry()
58 hbox.pack_end(self.entry, padding = 5)
59 self.entry.show()
61 self.entry.connect("activate", self.filter_activated)
63 self.list = GtkList()
64 self.list.set_selection_mode(SELECTION_MULTIPLE)
65 self.list.set_selection_mode(SELECTION_BROWSE)
66 scrolled_win.add_with_viewport(self.list)
67 self.list.show()
69 self.list.connect("select_child", self.key_selected)
71 scrolled_win = GtkScrolledWindow()
72 scrolled_win.set_policy(POLICY_AUTOMATIC, POLICY_AUTOMATIC)
73 hpaned.add2(scrolled_win)
74 scrolled_win.set_usize(500,400)
75 scrolled_win.show()
77 self.text = GtkText()
78 self.text.set_editable(FALSE)
79 scrolled_win.add_with_viewport(self.text)
80 self.text.show()
82 self.text.connect("event", self.event_handler)
84 self.menu = GtkMenu()
85 self.menu.show()
87 self.font = load_font("fixed")
89 self.update_keylist()
91 win.show()
93 # Add a key to the left hand side of the user interface
95 def add_key(self, key):
96 display_key = self.display_key(key)
97 list_item = GtkListItem(display_key)
98 list_item.set_data("raw_key", key) # Store raw key in item data
99 self.list.add(list_item)
100 list_item.show()
102 # Event handler registered by build_ui()
104 def event_handler(self, event, menu):
105 return FALSE
107 # Set the text to appear in the right hand side of the user interface
109 def set_value_text(self, text):
110 self.text.delete_text(0, self.text.get_length())
112 # The text widget has trouble inserting text containing NULL
113 # characters.
115 text = string.replace(text, "\x00", ".")
117 self.text.insert(self.font, None, None, text)
119 # This function is called when a key is selected in the left hand side
120 # of the user interface.
122 def key_selected(self, list, list_item):
123 key = list_item.children()[0].get()
125 # Look for a match in the value display function list
127 text = t[list_item.get_data("raw_key")]
129 for entry in self.value_display_fns:
130 if re.match(entry[0], key):
131 text = entry[1](text)
132 break
134 self.set_value_text(text)
136 # Refresh the key list by removing all items and re-inserting them.
137 # Items are only inserted if they pass through the filter regexp.
139 def update_keylist(self):
140 self.list.remove_items(self.list.children())
141 self.set_value_text("")
142 for k in self.dict.keys():
143 if re.match(self.filter_regex, k):
144 self.add_key(k)
146 # Invoked when the user hits return in the filter text entry widget.
148 def filter_activated(self, entry):
149 self.filter_regex = entry.get_text()
150 self.update_keylist()
153 # Public methods
156 # Set a function that translates between how keys look in the user
157 # interface (displayed keys) versus how they are represented in the tdb
158 # (raw keys).
160 def set_display_key_fn(self, fn):
161 self.display_key = fn
163 # Register a value display function for a key. The first argument is a
164 # regex that matches key values, and the second argument is a function
165 # to call to convert the raw value data to a string to display in the
166 # right hand side of the UI.
168 def register_display_value_fn(self, key_regexp, fn):
169 self.value_display_fns.append((key_regexp, fn))
171 def display_value_hex(self, value):
172 return "foo"
174 def convert_to_hex(data):
175 """Return a hex dump of a string as a string.
177 The output produced is in the standard 16 characters per line hex +
178 ascii format:
180 00000000: 40 00 00 00 00 00 00 00 40 00 00 00 01 00 04 80 @....... @.......
181 00000010: 01 01 00 00 00 00 00 01 00 00 00 00 ........ ....
184 pos = 0 # Position in data
185 line = 0 # Line of data
187 hex = "" # Hex display
188 ascii = "" # ASCII display
190 result = ""
192 while pos < len(data):
194 # Start with header
196 if pos % 16 == 0:
197 hex = "%08x: " % (line * 16)
198 ascii = ""
200 # Add character
202 hex = hex + "%02x " % (ord(data[pos]))
204 if ord(data[pos]) < 32 or ord(data[pos]) > 176:
205 ascii = ascii + '.'
206 else:
207 ascii = ascii + data[pos]
209 pos = pos + 1
211 # Add separator if half way
213 if pos % 16 == 8:
214 hex = hex + " "
215 ascii = ascii + " "
217 # End of line
219 if pos % 16 == 0:
220 result = result + "%s %s\n" % (hex, ascii)
221 line = line + 1
223 # Leftover bits
225 if pos % 16 != 0:
227 # Pad hex string
229 for i in range(0, (16 - (pos % 16))):
230 hex = hex + " "
232 # Half way separator
234 if (pos % 16) < 8:
235 hex = hex + " "
237 result = result + "%s %s\n" % (hex, ascii)
239 return result
241 # Open handle on tdb
243 if len(sys.argv) != 2:
244 print "Usage: gdbtool <tdbfile>"
245 sys.exit(1)
247 try:
248 t = tdb.open(sys.argv[1])
249 except tdb.error, t:
250 print "gtdbtool: error opening %s: %s" % (sys.argv[1], t)
251 sys.exit(1)
253 # Create user interface
255 w = gtdbtool(t)
257 # Set up a key display function. A lot of keys have \x00 appended to the
258 # end which mucks up gtk.
260 def display_key_x00(key):
261 return string.replace(key, "\x00", "")
263 w.set_display_key_fn(display_key_x00)
265 def display_value_hex(value):
266 return value;
268 w.register_display_value_fn("DRIVERS/", convert_to_hex)
269 w.register_display_value_fn("SECDESC/", convert_to_hex)
270 w.register_display_value_fn("PRINTERS/", convert_to_hex)
272 # Show user interface
274 w.build_ui("gtdbtool: %s" % sys.argv[1])
276 # Override Python's handling of ctrl-c so we can break out of the gui
277 # from the command line.
279 import signal
280 signal.signal(signal.SIGINT, signal.SIG_DFL)
282 mainloop()