##// END OF EJS Templates
Make a few igrid attributes private....
walter.doerwald -
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,769 +1,752 b''
1 # -*- coding: iso-8859-1 -*-
1 # -*- coding: iso-8859-1 -*-
2
2
3 import ipipe, os, webbrowser, urllib
3 import ipipe, os, webbrowser, urllib
4 import wx
4 import wx
5 import wx.grid, wx.html
5 import wx.grid, wx.html
6
6
7 try:
7 try:
8 sorted
8 sorted
9 except NameError:
9 except NameError:
10 from ipipe import sorted
10 from ipipe import sorted
11
11
12
12
13 __all__ = ["igrid"]
13 __all__ = ["igrid"]
14
14
15
15
16 class IGridRenderer(wx.grid.PyGridCellRenderer):
16 class IGridRenderer(wx.grid.PyGridCellRenderer):
17 """
17 """
18 This is a custom renderer for our IGridGrid
18 This is a custom renderer for our IGridGrid
19 """
19 """
20 def __init__(self, table):
20 def __init__(self, table):
21 self.maxchars = 200
21 self.maxchars = 200
22 self.table = table
22 self.table = table
23 self.colormap = (
23 self.colormap = (
24 ( 0, 0, 0),
24 ( 0, 0, 0),
25 (174, 0, 0),
25 (174, 0, 0),
26 ( 0, 174, 0),
26 ( 0, 174, 0),
27 (174, 174, 0),
27 (174, 174, 0),
28 ( 0, 0, 174),
28 ( 0, 0, 174),
29 (174, 0, 174),
29 (174, 0, 174),
30 ( 0, 174, 174),
30 ( 0, 174, 174),
31 ( 64, 64, 64)
31 ( 64, 64, 64)
32 )
32 )
33
33
34 wx.grid.PyGridCellRenderer.__init__(self)
34 wx.grid.PyGridCellRenderer.__init__(self)
35
35
36 def _getvalue(self, row, col):
36 def _getvalue(self, row, col):
37 try:
37 try:
38 value = self.table.displayattrs[col].value(self.table.items[row])
38 value = self.table._displayattrs[col].value(self.table.items[row])
39 (align, width, text) = ipipe.xformat(value, "cell", self.maxchars)
39 (align, width, text) = ipipe.xformat(value, "cell", self.maxchars)
40 except Exception, exc:
40 except Exception, exc:
41 (align, width, text) = ipipe.xformat(exc, "cell", self.maxchars)
41 (align, width, text) = ipipe.xformat(exc, "cell", self.maxchars)
42 return (align, text)
42 return (align, text)
43
43
44 def GetBestSize(self, grid, attr, dc, row, col):
44 def GetBestSize(self, grid, attr, dc, row, col):
45 text = grid.GetCellValue(row, col)
45 text = grid.GetCellValue(row, col)
46 (align, text) = self._getvalue(row, col)
46 (align, text) = self._getvalue(row, col)
47 dc.SetFont(attr.GetFont())
47 dc.SetFont(attr.GetFont())
48 (w, h) = dc.GetTextExtent(str(text))
48 (w, h) = dc.GetTextExtent(str(text))
49 return wx.Size(min(w+2, 600), h+2) # add border
49 return wx.Size(min(w+2, 600), h+2) # add border
50
50
51 def Draw(self, grid, attr, dc, rect, row, col, isSelected):
51 def Draw(self, grid, attr, dc, rect, row, col, isSelected):
52 """
52 """
53 Takes care of drawing everything in the cell; aligns the text
53 Takes care of drawing everything in the cell; aligns the text
54 """
54 """
55 text = grid.GetCellValue(row, col)
55 text = grid.GetCellValue(row, col)
56 (align, text) = self._getvalue(row, col)
56 (align, text) = self._getvalue(row, col)
57 if isSelected:
57 if isSelected:
58 bg = grid.GetSelectionBackground()
58 bg = grid.GetSelectionBackground()
59 else:
59 else:
60 bg = ["white", (240, 240, 240)][row%2]
60 bg = ["white", (240, 240, 240)][row%2]
61 dc.SetTextBackground(bg)
61 dc.SetTextBackground(bg)
62 dc.SetBrush(wx.Brush(bg, wx.SOLID))
62 dc.SetBrush(wx.Brush(bg, wx.SOLID))
63 dc.SetPen(wx.TRANSPARENT_PEN)
63 dc.SetPen(wx.TRANSPARENT_PEN)
64 dc.SetFont(attr.GetFont())
64 dc.SetFont(attr.GetFont())
65 dc.DrawRectangleRect(rect)
65 dc.DrawRectangleRect(rect)
66 dc.SetClippingRect(rect)
66 dc.SetClippingRect(rect)
67 # Format the text
67 # Format the text
68 if align == -1: # left alignment
68 if align == -1: # left alignment
69 (width, height) = dc.GetTextExtent(str(text))
69 (width, height) = dc.GetTextExtent(str(text))
70 x = rect[0]+1
70 x = rect[0]+1
71 y = rect[1]+0.5*(rect[3]-height)
71 y = rect[1]+0.5*(rect[3]-height)
72
72
73 for (style, part) in text:
73 for (style, part) in text:
74 if isSelected:
74 if isSelected:
75 fg = grid.GetSelectionForeground()
75 fg = grid.GetSelectionForeground()
76 else:
76 else:
77 fg = self.colormap[style.fg]
77 fg = self.colormap[style.fg]
78 dc.SetTextForeground(fg)
78 dc.SetTextForeground(fg)
79 (w, h) = dc.GetTextExtent(part)
79 (w, h) = dc.GetTextExtent(part)
80 dc.DrawText(part, x, y)
80 dc.DrawText(part, x, y)
81 x += w
81 x += w
82 elif align == 0: # center alignment
82 elif align == 0: # center alignment
83 (width, height) = dc.GetTextExtent(str(text))
83 (width, height) = dc.GetTextExtent(str(text))
84 x = rect[0]+0.5*(rect[2]-width)
84 x = rect[0]+0.5*(rect[2]-width)
85 y = rect[1]+0.5*(rect[3]-height)
85 y = rect[1]+0.5*(rect[3]-height)
86 for (style, part) in text:
86 for (style, part) in text:
87 if isSelected:
87 if isSelected:
88 fg = grid.GetSelectionForeground()
88 fg = grid.GetSelectionForeground()
89 else:
89 else:
90 fg = self.colormap[style.fg]
90 fg = self.colormap[style.fg]
91 dc.SetTextForeground(fg)
91 dc.SetTextForeground(fg)
92 (w, h) = dc.GetTextExtent(part)
92 (w, h) = dc.GetTextExtent(part)
93 dc.DrawText(part, x, y)
93 dc.DrawText(part, x, y)
94 x += w
94 x += w
95 else: # right alignment
95 else: # right alignment
96 (width, height) = dc.GetTextExtent(str(text))
96 (width, height) = dc.GetTextExtent(str(text))
97 x = rect[0]+rect[2]-1
97 x = rect[0]+rect[2]-1
98 y = rect[1]+0.5*(rect[3]-height)
98 y = rect[1]+0.5*(rect[3]-height)
99 for (style, part) in reversed(text):
99 for (style, part) in reversed(text):
100 (w, h) = dc.GetTextExtent(part)
100 (w, h) = dc.GetTextExtent(part)
101 x -= w
101 x -= w
102 if isSelected:
102 if isSelected:
103 fg = grid.GetSelectionForeground()
103 fg = grid.GetSelectionForeground()
104 else:
104 else:
105 fg = self.colormap[style.fg]
105 fg = self.colormap[style.fg]
106 dc.SetTextForeground(fg)
106 dc.SetTextForeground(fg)
107 dc.DrawText(part, x, y)
107 dc.DrawText(part, x, y)
108 dc.DestroyClippingRegion()
108 dc.DestroyClippingRegion()
109
109
110 def Clone(self):
110 def Clone(self):
111 return IGridRenderer(self.table)
111 return IGridRenderer(self.table)
112
112
113
113
114 class IGridTable(wx.grid.PyGridTableBase):
114 class IGridTable(wx.grid.PyGridTableBase):
115 # The data table for the ``IGridGrid``. Some dirty tricks were used here:
115 # The data table for the ``IGridGrid``. Some dirty tricks were used here:
116 # ``GetValue()`` does not get any values (or at least it does not return
116 # ``GetValue()`` does not get any values (or at least it does not return
117 # anything, accessing the values is done by the renderer)
117 # anything, accessing the values is done by the renderer)
118 # but rather tries to fetch the objects which were requested into the table.
118 # but rather tries to fetch the objects which were requested into the table.
119 # General behaviour is: Fetch the first X objects. If the user scrolls down
119 # General behaviour is: Fetch the first X objects. If the user scrolls down
120 # to the last object another bunch of X objects is fetched (if possible)
120 # to the last object another bunch of X objects is fetched (if possible)
121 def __init__(self, input, fontsize, *attrs):
121 def __init__(self, input, fontsize, *attrs):
122 wx.grid.PyGridTableBase.__init__(self)
122 wx.grid.PyGridTableBase.__init__(self)
123 self.input = input
123 self.input = input
124 self.iterator = ipipe.xiter(input)
124 self.iterator = ipipe.xiter(input)
125 self.items = []
125 self.items = []
126 self.hiddenattrs = []
126 self.attrs = [ipipe.upgradexattr(attr) for attr in attrs]
127 self.attrs = attrs
127 self._displayattrs = self.attrs[:]
128 self.displayattrs = []
128 self._displayattrset = set(self.attrs)
129 self.fetch(1)
129 self._sizing = False
130 self.sizing = False
131 self.fontsize = fontsize
130 self.fontsize = fontsize
131 self._fetch(1)
132
132
133 def GetAttr(self, *args):
133 def GetAttr(self, *args):
134 attr = wx.grid.GridCellAttr()
134 attr = wx.grid.GridCellAttr()
135 attr.SetFont(wx.Font(self.fontsize, wx.TELETYPE, wx.NORMAL, wx.NORMAL))
135 attr.SetFont(wx.Font(self.fontsize, wx.TELETYPE, wx.NORMAL, wx.NORMAL))
136 return attr
136 return attr
137
137
138 def GetNumberRows(self):
138 def GetNumberRows(self):
139 return len(self.items)
139 return len(self.items)
140
140
141 def GetNumberCols(self):
141 def GetNumberCols(self):
142 return len(self.displayattrs)
142 return len(self._displayattrs)
143
143
144 def GetColLabelValue(self, col):
144 def GetColLabelValue(self, col):
145 if col < len(self.displayattrs):
145 if col < len(self._displayattrs):
146 return self.displayattrs[col].name()
146 return self._displayattrs[col].name()
147 else:
147 else:
148 return ""
148 return ""
149
149
150 def GetRowLabelValue(self, row):
150 def GetRowLabelValue(self, row):
151 return str(row)
151 return str(row)
152
152
153 def IsEmptyCell(self, row, col):
153 def IsEmptyCell(self, row, col):
154 return False
154 return False
155
155
156 def fetch(self, count):
156 def _append(self, item):
157 self.items.append(item)
158 # Nothing to do if the set of attributes has been fixed by the user
159 if not self.attrs:
160 for attr in ipipe.xattrs(item):
161 attr = ipipe.upgradexattr(attr)
162 if attr not in self._displayattrset:
163 self._displayattrs.append(attr)
164 self._displayattrset.add(attr)
165
166 def _fetch(self, count):
157 # Try to fill ``self.items`` with at least ``count`` objects.
167 # Try to fill ``self.items`` with at least ``count`` objects.
158 have = len(self.items)
168 have = len(self.items)
159 work = False
160 while self.iterator is not None and have < count:
169 while self.iterator is not None and have < count:
161 try:
170 try:
162 item = self.iterator.next()
171 item = self.iterator.next()
163 except StopIteration:
172 except StopIteration:
164 self.iterator = None
173 self.iterator = None
165 break
174 break
166 except (KeyboardInterrupt, SystemExit):
175 except (KeyboardInterrupt, SystemExit):
167 raise
176 raise
168 except Exception, exc:
177 except Exception, exc:
169 have += 1
178 have += 1
170 self.items.append(exc)
179 self._append(item)
171 work = True
172 self.iterator = None
180 self.iterator = None
173 break
181 break
174 else:
182 else:
175 have += 1
183 have += 1
176 self.items.append(item)
184 self._append(item)
177 work = True
178 if work:
179 self.calcdisplayattrs()
180
181 def calcdisplayattrs(self):
182 # Calculate which attributes are available from the objects that are
183 # currently visible on screen (and store it in ``self.displayattrs``)
184 attrs = set()
185 self.displayattrs = []
186 if self.attrs:
187 # If the browser object specifies a fixed list of attributes,
188 # simply use it (removing hidden attributes).
189 for attr in self.attrs:
190 attr = ipipe.upgradexattr(attr)
191 if attr not in attrs and attr not in self.hiddenattrs:
192 self.displayattrs.append(attr)
193 attrs.add(attr)
194 else:
195 endy = len(self.items)
196 for i in xrange(endy):
197 for attr in ipipe.xattrs(self.items[i]):
198 attr = ipipe.upgradexattr(attr)
199 if attr not in attrs and attr not in self.hiddenattrs:
200 self.displayattrs.append(attr)
201 attrs.add(attr)
202
185
203 def GetValue(self, row, col):
186 def GetValue(self, row, col):
204 # some kind of dummy-function: does not return anything but "";
187 # some kind of dummy-function: does not return anything but "";
205 # (The value isn't use anyway)
188 # (The value isn't use anyway)
206 # its main task is to trigger the fetch of new objects
189 # its main task is to trigger the fetch of new objects
207 had_cols = self.displayattrs[:]
190 had_cols = self._displayattrs[:]
208 had_rows = len(self.items)
191 had_rows = len(self.items)
209 if row == had_rows - 1 and self.iterator is not None and not self.sizing:
192 if row == had_rows - 1 and self.iterator is not None and not self._sizing:
210 self.fetch(row + 20)
193 self._fetch(row + 20)
211 have_rows = len(self.items)
194 have_rows = len(self.items)
212 have_cols = len(self.displayattrs)
195 have_cols = len(self._displayattrs)
213 if have_rows > had_rows:
196 if have_rows > had_rows:
214 msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED, have_rows - had_rows)
197 msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED, have_rows - had_rows)
215 self.GetView().ProcessTableMessage(msg)
198 self.GetView().ProcessTableMessage(msg)
216 self.sizing = True
199 self._sizing = True
217 self.GetView().AutoSizeColumns(False)
200 self.GetView().AutoSizeColumns(False)
218 self.sizing = False
201 self._sizing = False
219 if row >= have_rows:
202 if row >= have_rows:
220 return ""
203 return ""
221 if self.displayattrs != had_cols:
204 if self._displayattrs != had_cols:
222 msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED, have_cols - len(had_cols))
205 msg = wx.grid.GridTableMessage(self, wx.grid.GRIDTABLE_NOTIFY_COLS_APPENDED, have_cols - len(had_cols))
223 self.GetView().ProcessTableMessage(msg)
206 self.GetView().ProcessTableMessage(msg)
224 return ""
207 return ""
225
208
226 def SetValue(self, row, col, value):
209 def SetValue(self, row, col, value):
227 pass
210 pass
228
211
229
212
230 class IGridGrid(wx.grid.Grid):
213 class IGridGrid(wx.grid.Grid):
231 # The actual grid
214 # The actual grid
232 # all methods for selecting/sorting/picking/... data are implemented here
215 # all methods for selecting/sorting/picking/... data are implemented here
233 def __init__(self, panel, input, *attrs):
216 def __init__(self, panel, input, *attrs):
234 wx.grid.Grid.__init__(self, panel)
217 wx.grid.Grid.__init__(self, panel)
235 fontsize = 9
218 fontsize = 9
236 self.input = input
219 self.input = input
237 self.table = IGridTable(self.input, fontsize, *attrs)
220 self.table = IGridTable(self.input, fontsize, *attrs)
238 self.SetTable(self.table, True)
221 self.SetTable(self.table, True)
239 self.SetSelectionMode(wx.grid.Grid.wxGridSelectRows)
222 self.SetSelectionMode(wx.grid.Grid.wxGridSelectRows)
240 self.SetDefaultRenderer(IGridRenderer(self.table))
223 self.SetDefaultRenderer(IGridRenderer(self.table))
241 self.EnableEditing(False)
224 self.EnableEditing(False)
242 self.Bind(wx.EVT_KEY_DOWN, self.key_pressed)
225 self.Bind(wx.EVT_KEY_DOWN, self.key_pressed)
243 self.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.cell_doubleclicked)
226 self.Bind(wx.grid.EVT_GRID_CELL_LEFT_DCLICK, self.cell_doubleclicked)
244 self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_DCLICK, self.label_doubleclicked)
227 self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_DCLICK, self.label_doubleclicked)
245 self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.on_label_leftclick)
228 self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.on_label_leftclick)
246 self.Bind(wx.grid.EVT_GRID_RANGE_SELECT, self._on_selected_range)
229 self.Bind(wx.grid.EVT_GRID_RANGE_SELECT, self._on_selected_range)
247 self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self._on_selected_cell)
230 self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self._on_selected_cell)
248 self.current_selection = set()
231 self.current_selection = set()
249 self.maxchars = 200
232 self.maxchars = 200
250
233
251 def on_label_leftclick(self, event):
234 def on_label_leftclick(self, event):
252 event.Skip()
235 event.Skip()
253
236
254 def error_output(self, text):
237 def error_output(self, text):
255 wx.Bell()
238 wx.Bell()
256 frame = self.GetParent().GetParent().GetParent()
239 frame = self.GetParent().GetParent().GetParent()
257 frame.SetStatusText(text)
240 frame.SetStatusText(text)
258
241
259 def _on_selected_range(self, event):
242 def _on_selected_range(self, event):
260 # Internal update to the selection tracking lists
243 # Internal update to the selection tracking lists
261 if event.Selecting():
244 if event.Selecting():
262 # adding to the list...
245 # adding to the list...
263 self.current_selection.update(xrange(event.GetTopRow(), event.GetBottomRow()+1))
246 self.current_selection.update(xrange(event.GetTopRow(), event.GetBottomRow()+1))
264 else:
247 else:
265 # removal from list
248 # removal from list
266 for index in xrange( event.GetTopRow(), event.GetBottomRow()+1):
249 for index in xrange( event.GetTopRow(), event.GetBottomRow()+1):
267 self.current_selection.discard(index)
250 self.current_selection.discard(index)
268 event.Skip()
251 event.Skip()
269
252
270 def _on_selected_cell(self, event):
253 def _on_selected_cell(self, event):
271 # Internal update to the selection tracking list
254 # Internal update to the selection tracking list
272 self.current_selection = set([event.GetRow()])
255 self.current_selection = set([event.GetRow()])
273 event.Skip()
256 event.Skip()
274
257
275 def sort(self, key, reverse=False):
258 def sort(self, key, reverse=False):
276 """
259 """
277 Sort the current list of items using the key function ``key``. If
260 Sort the current list of items using the key function ``key``. If
278 ``reverse`` is true the sort order is reversed.
261 ``reverse`` is true the sort order is reversed.
279 """
262 """
280 row = self.GetGridCursorRow()
263 row = self.GetGridCursorRow()
281 col = self.GetGridCursorCol()
264 col = self.GetGridCursorCol()
282 curitem = self.table.items[row] # Remember where the cursor is now
265 curitem = self.table.items[row] # Remember where the cursor is now
283 # Sort items
266 # Sort items
284 def realkey(item):
267 def realkey(item):
285 return key(item)
268 return key(item)
286 try:
269 try:
287 self.table.items = ipipe.deque(sorted(self.table.items, key=realkey, reverse=reverse))
270 self.table.items = ipipe.deque(sorted(self.table.items, key=realkey, reverse=reverse))
288 except TypeError, exc:
271 except TypeError, exc:
289 self.error_output("Exception encountered: %s" % exc)
272 self.error_output("Exception encountered: %s" % exc)
290 return
273 return
291 # Find out where the object under the cursor went
274 # Find out where the object under the cursor went
292 for (i, item) in enumerate(self.table.items):
275 for (i, item) in enumerate(self.table.items):
293 if item is curitem:
276 if item is curitem:
294 self.SetGridCursor(i,col)
277 self.SetGridCursor(i,col)
295 self.MakeCellVisible(i,col)
278 self.MakeCellVisible(i,col)
296 self.Refresh()
279 self.Refresh()
297
280
298 def sortattrasc(self):
281 def sortattrasc(self):
299 """
282 """
300 Sort in ascending order; sorting criteria is the current attribute
283 Sort in ascending order; sorting criteria is the current attribute
301 """
284 """
302 col = self.GetGridCursorCol()
285 col = self.GetGridCursorCol()
303 attr = self.table.displayattrs[col]
286 attr = self.table._displayattrs[col]
304 frame = self.GetParent().GetParent().GetParent()
287 frame = self.GetParent().GetParent().GetParent()
305 if attr is ipipe.noitem:
288 if attr is ipipe.noitem:
306 self.error_output("no column under cursor")
289 self.error_output("no column under cursor")
307 return
290 return
308 frame.SetStatusText("sort by %s (ascending)" % attr.name())
291 frame.SetStatusText("sort by %s (ascending)" % attr.name())
309 def key(item):
292 def key(item):
310 try:
293 try:
311 return attr.value(item)
294 return attr.value(item)
312 except (KeyboardInterrupt, SystemExit):
295 except (KeyboardInterrupt, SystemExit):
313 raise
296 raise
314 except Exception:
297 except Exception:
315 return None
298 return None
316 self.sort(key)
299 self.sort(key)
317
300
318 def sortattrdesc(self):
301 def sortattrdesc(self):
319 """
302 """
320 Sort in descending order; sorting criteria is the current attribute
303 Sort in descending order; sorting criteria is the current attribute
321 """
304 """
322 col = self.GetGridCursorCol()
305 col = self.GetGridCursorCol()
323 attr = self.table.displayattrs[col]
306 attr = self.table._displayattrs[col]
324 frame = self.GetParent().GetParent().GetParent()
307 frame = self.GetParent().GetParent().GetParent()
325 if attr is ipipe.noitem:
308 if attr is ipipe.noitem:
326 self.error_output("no column under cursor")
309 self.error_output("no column under cursor")
327 return
310 return
328 frame.SetStatusText("sort by %s (descending)" % attr.name())
311 frame.SetStatusText("sort by %s (descending)" % attr.name())
329 def key(item):
312 def key(item):
330 try:
313 try:
331 return attr.value(item)
314 return attr.value(item)
332 except (KeyboardInterrupt, SystemExit):
315 except (KeyboardInterrupt, SystemExit):
333 raise
316 raise
334 except Exception:
317 except Exception:
335 return None
318 return None
336 self.sort(key, reverse=True)
319 self.sort(key, reverse=True)
337
320
338 def label_doubleclicked(self, event):
321 def label_doubleclicked(self, event):
339 row = event.GetRow()
322 row = event.GetRow()
340 col = event.GetCol()
323 col = event.GetCol()
341 if col == -1:
324 if col == -1:
342 self.enter(row)
325 self.enter(row)
343
326
344 def _getvalue(self, row, col):
327 def _getvalue(self, row, col):
345 """
328 """
346 Gets the text which is displayed at ``(row, col)``
329 Gets the text which is displayed at ``(row, col)``
347 """
330 """
348 try:
331 try:
349 value = self.table.displayattrs[col].value(self.table.items[row])
332 value = self.table._displayattrs[col].value(self.table.items[row])
350 (align, width, text) = ipipe.xformat(value, "cell", self.maxchars)
333 (align, width, text) = ipipe.xformat(value, "cell", self.maxchars)
351 except IndexError:
334 except IndexError:
352 raise IndexError
335 raise IndexError
353 except Exception, exc:
336 except Exception, exc:
354 (align, width, text) = ipipe.xformat(exc, "cell", self.maxchars)
337 (align, width, text) = ipipe.xformat(exc, "cell", self.maxchars)
355 return text
338 return text
356
339
357 def search(self, searchtext, startrow=0, startcol=0, search_forward=True):
340 def search(self, searchtext, startrow=0, startcol=0, search_forward=True):
358 """
341 """
359 search for ``searchtext``, starting in ``(startrow, startcol)``;
342 search for ``searchtext``, starting in ``(startrow, startcol)``;
360 if ``search_forward`` is true the direction is "forward"
343 if ``search_forward`` is true the direction is "forward"
361 """
344 """
362 row = startrow
345 row = startrow
363 searchtext = searchtext.lower()
346 searchtext = searchtext.lower()
364 if search_forward:
347 if search_forward:
365 while True:
348 while True:
366 for col in xrange(startcol, self.table.GetNumberCols()):
349 for col in xrange(startcol, self.table.GetNumberCols()):
367 try:
350 try:
368 foo = self.table.GetValue(row, col)
351 foo = self.table.GetValue(row, col)
369 text = self._getvalue(row, col)
352 text = self._getvalue(row, col)
370 if searchtext in text.string().lower():
353 if searchtext in text.string().lower():
371 self.SetGridCursor(row, col)
354 self.SetGridCursor(row, col)
372 self.MakeCellVisible(row, col)
355 self.MakeCellVisible(row, col)
373 return
356 return
374 except IndexError:
357 except IndexError:
375 return
358 return
376 startcol = 0
359 startcol = 0
377 row += 1
360 row += 1
378 else:
361 else:
379 while True:
362 while True:
380 for col in xrange(startcol, -1, -1):
363 for col in xrange(startcol, -1, -1):
381 try:
364 try:
382 foo = self.table.GetValue(row, col)
365 foo = self.table.GetValue(row, col)
383 text = self._getvalue(row, col)
366 text = self._getvalue(row, col)
384 if searchtext in text.string().lower():
367 if searchtext in text.string().lower():
385 self.SetGridCursor(row, col)
368 self.SetGridCursor(row, col)
386 self.MakeCellVisible(row, col)
369 self.MakeCellVisible(row, col)
387 return
370 return
388 except IndexError:
371 except IndexError:
389 return
372 return
390 startcol = self.table.GetNumberCols()-1
373 startcol = self.table.GetNumberCols()-1
391 row -= 1
374 row -= 1
392
375
393 def key_pressed(self, event):
376 def key_pressed(self, event):
394 """
377 """
395 Maps pressed keys to functions
378 Maps pressed keys to functions
396 """
379 """
397 frame = self.GetParent().GetParent().GetParent()
380 frame = self.GetParent().GetParent().GetParent()
398 frame.SetStatusText("")
381 frame.SetStatusText("")
399 sh = event.ShiftDown()
382 sh = event.ShiftDown()
400 ctrl = event.ControlDown()
383 ctrl = event.ControlDown()
401
384
402 keycode = event.GetKeyCode()
385 keycode = event.GetKeyCode()
403 if keycode == ord("P"):
386 if keycode == ord("P"):
404 row = self.GetGridCursorRow()
387 row = self.GetGridCursorRow()
405 if event.ShiftDown():
388 if event.ShiftDown():
406 col = self.GetGridCursorCol()
389 col = self.GetGridCursorCol()
407 self.pickattr(row, col)
390 self.pickattr(row, col)
408 else:
391 else:
409 self.pick(row)
392 self.pick(row)
410 elif keycode == ord("M"):
393 elif keycode == ord("M"):
411 if ctrl:
394 if ctrl:
412 col = self.GetGridCursorCol()
395 col = self.GetGridCursorCol()
413 self.pickrowsattr(sorted(self.current_selection), col)
396 self.pickrowsattr(sorted(self.current_selection), col)
414 else:
397 else:
415 self.pickrows(sorted(self.current_selection))
398 self.pickrows(sorted(self.current_selection))
416 elif keycode in (wx.WXK_BACK, wx.WXK_DELETE, ord("X")) and not (ctrl or sh):
399 elif keycode in (wx.WXK_BACK, wx.WXK_DELETE, ord("X")) and not (ctrl or sh):
417 self.delete_current_notebook()
400 self.delete_current_notebook()
418 elif keycode == ord("E") and not (ctrl or sh):
401 elif keycode == ord("E") and not (ctrl or sh):
419 row = self.GetGridCursorRow()
402 row = self.GetGridCursorRow()
420 self.enter(row)
403 self.enter(row)
421 elif keycode == ord("E") and sh and not ctrl:
404 elif keycode == ord("E") and sh and not ctrl:
422 row = self.GetGridCursorRow()
405 row = self.GetGridCursorRow()
423 col = self.GetGridCursorCol()
406 col = self.GetGridCursorCol()
424 self.enterattr(row, col)
407 self.enterattr(row, col)
425 elif keycode == ord("E") and ctrl:
408 elif keycode == ord("E") and ctrl:
426 row = self.GetGridCursorRow()
409 row = self.GetGridCursorRow()
427 self.SetGridCursor(row, self.GetNumberCols()-1)
410 self.SetGridCursor(row, self.GetNumberCols()-1)
428 elif keycode == wx.WXK_HOME or (keycode == ord("A") and ctrl):
411 elif keycode == wx.WXK_HOME or (keycode == ord("A") and ctrl):
429 row = self.GetGridCursorRow()
412 row = self.GetGridCursorRow()
430 self.SetGridCursor(row, 0)
413 self.SetGridCursor(row, 0)
431 elif keycode == ord("C") and sh:
414 elif keycode == ord("C") and sh:
432 col = self.GetGridCursorCol()
415 col = self.GetGridCursorCol()
433 attr = self.table.displayattrs[col]
416 attr = self.table._displayattrs[col]
434 returnobj = []
417 returnobj = []
435 for i in xrange(self.GetNumberRows()):
418 for i in xrange(self.GetNumberRows()):
436 returnobj.append(self.table.displayattrs[col].value(self.table.items[i]))
419 returnobj.append(self.table._displayattrs[col].value(self.table.items[i]))
437 self.quit(returnobj)
420 self.quit(returnobj)
438 elif keycode in (wx.WXK_ESCAPE, ord("Q")) and not (ctrl or sh):
421 elif keycode in (wx.WXK_ESCAPE, ord("Q")) and not (ctrl or sh):
439 self.quit()
422 self.quit()
440 elif keycode == ord("<"):
423 elif keycode == ord("<"):
441 row = self.GetGridCursorRow()
424 row = self.GetGridCursorRow()
442 col = self.GetGridCursorCol()
425 col = self.GetGridCursorCol()
443 if not event.ShiftDown():
426 if not event.ShiftDown():
444 newcol = col - 1
427 newcol = col - 1
445 if newcol >= 0:
428 if newcol >= 0:
446 self.SetGridCursor(row, col - 1)
429 self.SetGridCursor(row, col - 1)
447 else:
430 else:
448 newcol = col + 1
431 newcol = col + 1
449 if newcol < self.GetNumberCols():
432 if newcol < self.GetNumberCols():
450 self.SetGridCursor(row, col + 1)
433 self.SetGridCursor(row, col + 1)
451 elif keycode == ord("D"):
434 elif keycode == ord("D"):
452 col = self.GetGridCursorCol()
435 col = self.GetGridCursorCol()
453 row = self.GetGridCursorRow()
436 row = self.GetGridCursorRow()
454 if not sh:
437 if not sh:
455 self.detail(row, col)
438 self.detail(row, col)
456 else:
439 else:
457 self.detail_attr(row, col)
440 self.detail_attr(row, col)
458 elif keycode == ord("F") and ctrl:
441 elif keycode == ord("F") and ctrl:
459 frame.enter_searchtext(event)
442 frame.enter_searchtext(event)
460 elif keycode == wx.WXK_F3:
443 elif keycode == wx.WXK_F3:
461 if sh:
444 if sh:
462 frame.find_previous(event)
445 frame.find_previous(event)
463 else:
446 else:
464 frame.find_next(event)
447 frame.find_next(event)
465 elif keycode == ord("V"):
448 elif keycode == ord("V"):
466 if sh:
449 if sh:
467 self.sortattrdesc()
450 self.sortattrdesc()
468 else:
451 else:
469 self.sortattrasc()
452 self.sortattrasc()
470 else:
453 else:
471 event.Skip()
454 event.Skip()
472
455
473 def delete_current_notebook(self):
456 def delete_current_notebook(self):
474 """
457 """
475 deletes the current notebook tab
458 deletes the current notebook tab
476 """
459 """
477 panel = self.GetParent()
460 panel = self.GetParent()
478 nb = panel.GetParent()
461 nb = panel.GetParent()
479 current = nb.GetSelection()
462 current = nb.GetSelection()
480 count = nb.GetPageCount()
463 count = nb.GetPageCount()
481 if count > 1:
464 if count > 1:
482 for i in xrange(count-1, current-1, -1):
465 for i in xrange(count-1, current-1, -1):
483 nb.DeletePage(i)
466 nb.DeletePage(i)
484 nb.GetCurrentPage().grid.SetFocus()
467 nb.GetCurrentPage().grid.SetFocus()
485 else:
468 else:
486 frame = nb.GetParent()
469 frame = nb.GetParent()
487 frame.SetStatusText("This is the last level!")
470 frame.SetStatusText("This is the last level!")
488
471
489 def _doenter(self, value, *attrs):
472 def _doenter(self, value, *attrs):
490 """
473 """
491 "enter" a special item resulting in a new notebook tab
474 "enter" a special item resulting in a new notebook tab
492 """
475 """
493 panel = self.GetParent()
476 panel = self.GetParent()
494 nb = panel.GetParent()
477 nb = panel.GetParent()
495 frame = nb.GetParent()
478 frame = nb.GetParent()
496 current = nb.GetSelection()
479 current = nb.GetSelection()
497 count = nb.GetPageCount()
480 count = nb.GetPageCount()
498 try: # if we want to enter something non-iterable, e.g. a function
481 try: # if we want to enter something non-iterable, e.g. a function
499 if current + 1 == count and value is not self.input: # we have an event in the last tab
482 if current + 1 == count and value is not self.input: # we have an event in the last tab
500 frame._add_notebook(value, *attrs)
483 frame._add_notebook(value, *attrs)
501 elif value != self.input: # we have to delete all tabs newer than [panel] first
484 elif value != self.input: # we have to delete all tabs newer than [panel] first
502 for i in xrange(count-1, current, -1): # some tabs don't close if we don't close in *reverse* order
485 for i in xrange(count-1, current, -1): # some tabs don't close if we don't close in *reverse* order
503 nb.DeletePage(i)
486 nb.DeletePage(i)
504 frame._add_notebook(value)
487 frame._add_notebook(value)
505 except TypeError, exc:
488 except TypeError, exc:
506 if exc.__class__.__module__ == "exceptions":
489 if exc.__class__.__module__ == "exceptions":
507 msg = "%s: %s" % (exc.__class__.__name__, exc)
490 msg = "%s: %s" % (exc.__class__.__name__, exc)
508 else:
491 else:
509 msg = "%s.%s: %s" % (exc.__class__.__module__, exc.__class__.__name__, exc)
492 msg = "%s.%s: %s" % (exc.__class__.__module__, exc.__class__.__name__, exc)
510 frame.SetStatusText(msg)
493 frame.SetStatusText(msg)
511
494
512 def enterattr(self, row, col):
495 def enterattr(self, row, col):
513 try:
496 try:
514 attr = self.table.displayattrs[col]
497 attr = self.table._displayattrs[col]
515 value = attr.value(self.table.items[row])
498 value = attr.value(self.table.items[row])
516 except Exception, exc:
499 except Exception, exc:
517 self.error_output(str(exc))
500 self.error_output(str(exc))
518 else:
501 else:
519 self._doenter(value)
502 self._doenter(value)
520
503
521 def enter(self, row):
504 def enter(self, row):
522 try:
505 try:
523 value = self.table.items[row]
506 value = self.table.items[row]
524 except Exception, exc:
507 except Exception, exc:
525 self.error_output(str(exc))
508 self.error_output(str(exc))
526 else:
509 else:
527 self._doenter(value)
510 self._doenter(value)
528
511
529 def detail(self, row, col):
512 def detail(self, row, col):
530 """
513 """
531 shows a detail-view of the current cell
514 shows a detail-view of the current cell
532 """
515 """
533 try:
516 try:
534 attr = self.table.displayattrs[col]
517 attr = self.table._displayattrs[col]
535 item = self.table.items[row]
518 item = self.table.items[row]
536 except Exception, exc:
519 except Exception, exc:
537 self.error_output(str(exc))
520 self.error_output(str(exc))
538 else:
521 else:
539 attrs = [ipipe.AttributeDetail(item, attr) for attr in ipipe.xattrs(item, "detail")]
522 attrs = [ipipe.AttributeDetail(item, attr) for attr in ipipe.xattrs(item, "detail")]
540 self._doenter(attrs)
523 self._doenter(attrs)
541
524
542 def detail_attr(self, row, col):
525 def detail_attr(self, row, col):
543 try:
526 try:
544 attr = self.table.displayattrs[col]
527 attr = self.table._displayattrs[col]
545 item = attr.value(self.table.items[row])
528 item = attr.value(self.table.items[row])
546 except Exception, exc:
529 except Exception, exc:
547 self.error_output(str(exc))
530 self.error_output(str(exc))
548 else:
531 else:
549 attrs = [ipipe.AttributeDetail(item, attr) for attr in ipipe.xattrs(item, "detail")]
532 attrs = [ipipe.AttributeDetail(item, attr) for attr in ipipe.xattrs(item, "detail")]
550 self._doenter(attrs)
533 self._doenter(attrs)
551
534
552 def quit(self, returnobj=None):
535 def quit(self, returnobj=None):
553 """
536 """
554 quit
537 quit
555 """
538 """
556 frame = self.GetParent().GetParent().GetParent()
539 frame = self.GetParent().GetParent().GetParent()
557 if frame.helpdialog:
540 if frame.helpdialog:
558 frame.helpdialog.Destroy()
541 frame.helpdialog.Destroy()
559 frame.parent.returnobj = returnobj
542 frame.parent.returnobj = returnobj
560 frame.Close()
543 frame.Close()
561 frame.Destroy()
544 frame.Destroy()
562
545
563 def cell_doubleclicked(self, event):
546 def cell_doubleclicked(self, event):
564 self.enterattr(event.GetRow(), event.GetCol())
547 self.enterattr(event.GetRow(), event.GetCol())
565
548
566 def pick(self, row):
549 def pick(self, row):
567 """
550 """
568 pick a single row and return to the IPython prompt
551 pick a single row and return to the IPython prompt
569 """
552 """
570 try:
553 try:
571 value = self.table.items[row]
554 value = self.table.items[row]
572 except Exception, exc:
555 except Exception, exc:
573 self.error_output(str(exc))
556 self.error_output(str(exc))
574 else:
557 else:
575 self.quit(value)
558 self.quit(value)
576
559
577 def pickrows(self, rows):
560 def pickrows(self, rows):
578 """
561 """
579 pick multiple rows and return to the IPython prompt
562 pick multiple rows and return to the IPython prompt
580 """
563 """
581 try:
564 try:
582 value = [self.table.items[row] for row in rows]
565 value = [self.table.items[row] for row in rows]
583 except Exception, exc:
566 except Exception, exc:
584 self.error_output(str(exc))
567 self.error_output(str(exc))
585 else:
568 else:
586 self.quit(value)
569 self.quit(value)
587
570
588 def pickrowsattr(self, rows, col):
571 def pickrowsattr(self, rows, col):
589 """"
572 """"
590 pick one column from multiple rows
573 pick one column from multiple rows
591 """
574 """
592 values = []
575 values = []
593 try:
576 try:
594 attr = self.table.displayattrs[col]
577 attr = self.table._displayattrs[col]
595 for row in rows:
578 for row in rows:
596 try:
579 try:
597 values.append(attr.value(self.table.items[row]))
580 values.append(attr.value(self.table.items[row]))
598 except (SystemExit, KeyboardInterrupt):
581 except (SystemExit, KeyboardInterrupt):
599 raise
582 raise
600 except Exception:
583 except Exception:
601 raise #pass
584 raise #pass
602 except Exception, exc:
585 except Exception, exc:
603 self.error_output(str(exc))
586 self.error_output(str(exc))
604 else:
587 else:
605 self.quit(values)
588 self.quit(values)
606
589
607 def pickattr(self, row, col):
590 def pickattr(self, row, col):
608 try:
591 try:
609 attr = self.table.displayattrs[col]
592 attr = self.table._displayattrs[col]
610 value = attr.value(self.table.items[row])
593 value = attr.value(self.table.items[row])
611 except Exception, exc:
594 except Exception, exc:
612 self.error_output(str(exc))
595 self.error_output(str(exc))
613 else:
596 else:
614 self.quit(value)
597 self.quit(value)
615
598
616
599
617 class IGridPanel(wx.Panel):
600 class IGridPanel(wx.Panel):
618 # Each IGridPanel contains an IGridGrid
601 # Each IGridPanel contains an IGridGrid
619 def __init__(self, parent, input, *attrs):
602 def __init__(self, parent, input, *attrs):
620 wx.Panel.__init__(self, parent, -1)
603 wx.Panel.__init__(self, parent, -1)
621 self.grid = IGridGrid(self, input, *attrs)
604 self.grid = IGridGrid(self, input, *attrs)
622 sizer = wx.BoxSizer(wx.VERTICAL)
605 sizer = wx.BoxSizer(wx.VERTICAL)
623 sizer.Add(self.grid, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
606 sizer.Add(self.grid, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
624 self.SetSizer(sizer)
607 self.SetSizer(sizer)
625 sizer.Fit(self)
608 sizer.Fit(self)
626 sizer.SetSizeHints(self)
609 sizer.SetSizeHints(self)
627
610
628
611
629 class IGridHTMLHelp(wx.Frame):
612 class IGridHTMLHelp(wx.Frame):
630 def __init__(self, parent, title, filename, size):
613 def __init__(self, parent, title, filename, size):
631 wx.Frame.__init__(self, parent, -1, title, size=size)
614 wx.Frame.__init__(self, parent, -1, title, size=size)
632 html = wx.html.HtmlWindow(self)
615 html = wx.html.HtmlWindow(self)
633 if "gtk2" in wx.PlatformInfo:
616 if "gtk2" in wx.PlatformInfo:
634 html.SetStandardFonts()
617 html.SetStandardFonts()
635 html.LoadFile(filename)
618 html.LoadFile(filename)
636
619
637
620
638 class IGridFrame(wx.Frame):
621 class IGridFrame(wx.Frame):
639 maxtitlelen = 30
622 maxtitlelen = 30
640
623
641 def __init__(self, parent, input):
624 def __init__(self, parent, input):
642 wx.Frame.__init__(self, None, title="IGrid", size=(640, 480))
625 wx.Frame.__init__(self, None, title="IGrid", size=(640, 480))
643 self.menubar = wx.MenuBar()
626 self.menubar = wx.MenuBar()
644 self.menucounter = 100
627 self.menucounter = 100
645 self.m_help = wx.Menu()
628 self.m_help = wx.Menu()
646 self.m_search = wx.Menu()
629 self.m_search = wx.Menu()
647 self.m_sort = wx.Menu()
630 self.m_sort = wx.Menu()
648 self.notebook = wx.Notebook(self, -1, style=0)
631 self.notebook = wx.Notebook(self, -1, style=0)
649 self.statusbar = self.CreateStatusBar(1, wx.ST_SIZEGRIP)
632 self.statusbar = self.CreateStatusBar(1, wx.ST_SIZEGRIP)
650 self.parent = parent
633 self.parent = parent
651 self._add_notebook(input)
634 self._add_notebook(input)
652 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
635 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
653 self.makemenu(self.m_sort, "&Sort (asc)", "Sort ascending", self.sortasc)
636 self.makemenu(self.m_sort, "&Sort (asc)", "Sort ascending", self.sortasc)
654 self.makemenu(self.m_sort, "Sort (&desc)", "Sort descending", self.sortdesc)
637 self.makemenu(self.m_sort, "Sort (&desc)", "Sort descending", self.sortdesc)
655 self.makemenu(self.m_help, "&Help", "Help", self.display_help)
638 self.makemenu(self.m_help, "&Help", "Help", self.display_help)
656 self.makemenu(self.m_help, "&Show help in browser", "Show help in browser", self.display_help_in_browser)
639 self.makemenu(self.m_help, "&Show help in browser", "Show help in browser", self.display_help_in_browser)
657 self.makemenu(self.m_search, "&Find text", "Find text", self.enter_searchtext)
640 self.makemenu(self.m_search, "&Find text", "Find text", self.enter_searchtext)
658 self.makemenu(self.m_search, "Find by &expression", "Find by expression", self.enter_searchexpression)
641 self.makemenu(self.m_search, "Find by &expression", "Find by expression", self.enter_searchexpression)
659 self.makemenu(self.m_search, "Find &next", "Find next", self.find_next)
642 self.makemenu(self.m_search, "Find &next", "Find next", self.find_next)
660 self.makemenu(self.m_search, "Find &previous", "Find previous", self.find_previous)
643 self.makemenu(self.m_search, "Find &previous", "Find previous", self.find_previous)
661 self.menubar.Append(self.m_search, "&Find")
644 self.menubar.Append(self.m_search, "&Find")
662 self.menubar.Append(self.m_sort, "&Sort")
645 self.menubar.Append(self.m_sort, "&Sort")
663 self.menubar.Append(self.m_help, "&Help")
646 self.menubar.Append(self.m_help, "&Help")
664 self.SetMenuBar(self.menubar)
647 self.SetMenuBar(self.menubar)
665 self.searchtext = ""
648 self.searchtext = ""
666 self.helpdialog = None
649 self.helpdialog = None
667
650
668 def sortasc(self, event):
651 def sortasc(self, event):
669 grid = self.notebook.GetPage(self.notebook.GetSelection()).grid
652 grid = self.notebook.GetPage(self.notebook.GetSelection()).grid
670 grid.sortattrasc()
653 grid.sortattrasc()
671
654
672 def sortdesc(self, event):
655 def sortdesc(self, event):
673 grid = self.notebook.GetPage(self.notebook.GetSelection()).grid
656 grid = self.notebook.GetPage(self.notebook.GetSelection()).grid
674 grid.sortattrdesc()
657 grid.sortattrdesc()
675
658
676 def find_previous(self, event):
659 def find_previous(self, event):
677 """
660 """
678 find previous occurrences
661 find previous occurrences
679 """
662 """
680 if self.searchtext:
663 if self.searchtext:
681 grid = self.notebook.GetPage(self.notebook.GetSelection()).grid
664 grid = self.notebook.GetPage(self.notebook.GetSelection()).grid
682 row = grid.GetGridCursorRow()
665 row = grid.GetGridCursorRow()
683 col = grid.GetGridCursorCol()
666 col = grid.GetGridCursorCol()
684 if col-1 >= 0:
667 if col-1 >= 0:
685 grid.search(self.searchtext, row, col-1, False)
668 grid.search(self.searchtext, row, col-1, False)
686 else:
669 else:
687 grid.search(self.searchtext, row-1, grid.table.GetNumberCols()-1, False)
670 grid.search(self.searchtext, row-1, grid.table.GetNumberCols()-1, False)
688 else:
671 else:
689 self.enter_searchtext(event)
672 self.enter_searchtext(event)
690
673
691 def find_next(self, event):
674 def find_next(self, event):
692 """
675 """
693 find the next occurrence
676 find the next occurrence
694 """
677 """
695 if self.searchtext:
678 if self.searchtext:
696 grid = self.notebook.GetPage(self.notebook.GetSelection()).grid
679 grid = self.notebook.GetPage(self.notebook.GetSelection()).grid
697 row = grid.GetGridCursorRow()
680 row = grid.GetGridCursorRow()
698 col = grid.GetGridCursorCol()
681 col = grid.GetGridCursorCol()
699 if col+1 < grid.table.GetNumberCols():
682 if col+1 < grid.table.GetNumberCols():
700 grid.search(self.searchtext, row, col+1)
683 grid.search(self.searchtext, row, col+1)
701 else:
684 else:
702 grid.search(self.searchtext, row+1, 0)
685 grid.search(self.searchtext, row+1, 0)
703 else:
686 else:
704 self.enter_searchtext(event)
687 self.enter_searchtext(event)
705
688
706 def display_help(self, event):
689 def display_help(self, event):
707 """
690 """
708 Display a help dialog
691 Display a help dialog
709 """
692 """
710 if self.helpdialog:
693 if self.helpdialog:
711 self.helpdialog.Destroy()
694 self.helpdialog.Destroy()
712 filename = os.path.join(os.path.dirname(__file__), "igrid_help.html")
695 filename = os.path.join(os.path.dirname(__file__), "igrid_help.html")
713 self.helpdialog = IGridHTMLHelp(None, title="Help", filename=filename, size=wx.Size(600,400))
696 self.helpdialog = IGridHTMLHelp(None, title="Help", filename=filename, size=wx.Size(600,400))
714 self.helpdialog.Show()
697 self.helpdialog.Show()
715
698
716 def display_help_in_browser(self, event):
699 def display_help_in_browser(self, event):
717 """
700 """
718 Show the help-HTML in a browser (as a ``HtmlWindow`` does not understand
701 Show the help-HTML in a browser (as a ``HtmlWindow`` does not understand
719 CSS this looks better)
702 CSS this looks better)
720 """
703 """
721 filename = urllib.pathname2url(os.path.abspath(os.path.join(os.path.dirname(__file__), "igrid_help.html")))
704 filename = urllib.pathname2url(os.path.abspath(os.path.join(os.path.dirname(__file__), "igrid_help.html")))
722 if not filename.startswith("file"):
705 if not filename.startswith("file"):
723 filename = "file:" + filename
706 filename = "file:" + filename
724 webbrowser.open(filename, new=1, autoraise=True)
707 webbrowser.open(filename, new=1, autoraise=True)
725
708
726 def enter_searchexpression(self, event):
709 def enter_searchexpression(self, event):
727 pass
710 pass
728
711
729 def makemenu(self, menu, label, help, cmd):
712 def makemenu(self, menu, label, help, cmd):
730 menu.Append(self.menucounter, label, help)
713 menu.Append(self.menucounter, label, help)
731 self.Bind(wx.EVT_MENU, cmd, id=self.menucounter)
714 self.Bind(wx.EVT_MENU, cmd, id=self.menucounter)
732 self.menucounter += 1
715 self.menucounter += 1
733
716
734 def _add_notebook(self, input, *attrs):
717 def _add_notebook(self, input, *attrs):
735 # Adds another notebook which has the starting object ``input``
718 # Adds another notebook which has the starting object ``input``
736 panel = IGridPanel(self.notebook, input, *attrs)
719 panel = IGridPanel(self.notebook, input, *attrs)
737 text = str(ipipe.xformat(input, "header", self.maxtitlelen)[2])
720 text = str(ipipe.xformat(input, "header", self.maxtitlelen)[2])
738 if len(text) >= self.maxtitlelen:
721 if len(text) >= self.maxtitlelen:
739 text = text[:self.maxtitlelen].rstrip(".") + "..."
722 text = text[:self.maxtitlelen].rstrip(".") + "..."
740 self.notebook.AddPage(panel, text, True)
723 self.notebook.AddPage(panel, text, True)
741 panel.grid.SetFocus()
724 panel.grid.SetFocus()
742 self.Layout()
725 self.Layout()
743
726
744 def OnCloseWindow(self, event):
727 def OnCloseWindow(self, event):
745 self.Destroy()
728 self.Destroy()
746
729
747 def enter_searchtext(self, event):
730 def enter_searchtext(self, event):
748 # Displays a dialog asking for the searchtext
731 # Displays a dialog asking for the searchtext
749 dlg = wx.TextEntryDialog(self, "Find:", "Find in list")
732 dlg = wx.TextEntryDialog(self, "Find:", "Find in list")
750 if dlg.ShowModal() == wx.ID_OK:
733 if dlg.ShowModal() == wx.ID_OK:
751 self.searchtext = dlg.GetValue()
734 self.searchtext = dlg.GetValue()
752 self.notebook.GetPage(self.notebook.GetSelection()).grid.search(self.searchtext, 0, 0)
735 self.notebook.GetPage(self.notebook.GetSelection()).grid.search(self.searchtext, 0, 0)
753 dlg.Destroy()
736 dlg.Destroy()
754
737
755
738
756 class igrid(ipipe.Display):
739 class igrid(ipipe.Display):
757 """
740 """
758 This is a wx-based display object that can be used instead of ``ibrowse``
741 This is a wx-based display object that can be used instead of ``ibrowse``
759 (which is curses-based) or ``idump`` (which simply does a print).
742 (which is curses-based) or ``idump`` (which simply does a print).
760 """
743 """
761 def display(self):
744 def display(self):
762 self.returnobj = None
745 self.returnobj = None
763 app = wx.App()
746 app = wx.App()
764 self.frame = IGridFrame(self, self.input)
747 self.frame = IGridFrame(self, self.input)
765 self.frame.Show()
748 self.frame.Show()
766 app.SetTopWindow(self.frame)
749 app.SetTopWindow(self.frame)
767 self.frame.Raise()
750 self.frame.Raise()
768 app.MainLoop()
751 app.MainLoop()
769 return self.returnobj
752 return self.returnobj
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now