1
2 """GNUmed xDT viewer.
3
4 TODO:
5
6 - popup menu on right-click
7 - import this line
8 - import all lines like this
9 - search
10 - print
11 - ...
12 """
13
14 __author__ = "S.Hilbert, K.Hilbert"
15
16 import sys, os, os.path, io, logging
17
18
19 import wx
20
21
22 from Gnumed.wxpython import gmGuiHelpers, gmPlugin
23 from Gnumed.pycommon import gmI18N, gmDispatcher
24 from Gnumed.business import gmXdtMappings, gmXdtObjects
25 from Gnumed.wxGladeWidgets import wxgXdtListPnl
26 from Gnumed.wxpython import gmAccessPermissionWidgets
27
28
29 _log = logging.getLogger('gm.ui')
30
31
32
33 -class cXdtListPnl(wxgXdtListPnl.wxgXdtListPnl):
35 wxgXdtListPnl.wxgXdtListPnl.__init__(self, *args, **kwargs)
36
37 self.filename = None
38
39 self.__cols = [
40 _('Field name'),
41 _('Interpreted content'),
42 _('xDT field ID'),
43 _('Raw content')
44 ]
45 self.__init_ui()
46
48 for col in range(len(self.__cols)):
49 self._LCTRL_xdt.InsertColumn(col, self.__cols[col])
50
51
52
54 if path is None:
55 root_dir = os.path.expanduser(os.path.join('~', 'gnumed'))
56 else:
57 root_dir = path
58
59
60 dlg = wx.FileDialog (
61 parent = self,
62 message = _("Choose an xDT file"),
63 defaultDir = root_dir,
64 defaultFile = '',
65 wildcard = '%s (*.xDT)|*.?DT;*.?dt|%s (*)|*|%s (*.*)|*.*' % (_('xDT files'), _('all files'), _('all files (Win)')),
66 style = wx.FD_OPEN | wx.FD_FILE_MUST_EXIST
67 )
68 choice = dlg.ShowModal()
69 fname = None
70 if choice == wx.ID_OK:
71 fname = dlg.GetPath()
72 dlg.Destroy()
73 return fname
74
76 if filename is None:
77 filename = self.select_file()
78 if filename is None:
79 return True
80
81 self.filename = None
82
83 try:
84 f = open(filename, 'r')
85 except IOError:
86 gmGuiHelpers.gm_show_error (
87 _('Cannot access xDT file\n\n'
88 ' [%s]'),
89 _('loading xDT file')
90 )
91 return False
92 f.close()
93
94 encoding = gmXdtObjects.determine_xdt_encoding(filename = filename)
95 if encoding is None:
96 encoding = 'utf8'
97 gmDispatcher.send(signal = 'statustext', msg = _('Encoding missing in xDT file. Assuming [%s].') % encoding)
98 _log.warning('xDT file [%s] does not define an encoding, assuming [%s]' % (filename, encoding))
99
100 try:
101 xdt_file = io.open(filename, mode = 'rt', encoding = encoding, errors = 'replace')
102 except IOError:
103 gmGuiHelpers.gm_show_error (
104 _('Cannot access xDT file\n\n'
105 ' [%s]'),
106 _('loading xDT file')
107 )
108 return False
109
110
111 self._LCTRL_xdt.DeleteAllItems()
112
113 self._LCTRL_xdt.InsertItem(index=0, label=_('name of xDT file'))
114 self._LCTRL_xdt.SetItem(index=0, column=1, label=filename)
115
116 idx = 1
117 for line in xdt_file:
118 line = line.replace('\015','')
119 line = line.replace('\012','')
120 length, field, content = line[:3], line[3:7], line[7:]
121
122 try:
123 left = gmXdtMappings.xdt_id_map[field]
124 except KeyError:
125 left = field
126
127 try:
128 right = gmXdtMappings.xdt_map_of_content_maps[field][content]
129 except KeyError:
130 right = content
131
132 self._LCTRL_xdt.InsertItem(index=idx, label=left)
133 self._LCTRL_xdt.SetItem(index=idx, column=1, label=right)
134 self._LCTRL_xdt.SetItem(index=idx, column=2, label=field)
135 self._LCTRL_xdt.SetItem(index=idx, column=3, label=content)
136 idx += 1
137
138 xdt_file.close()
139
140 self._LCTRL_xdt.SetColumnWidth(0, wx.LIST_AUTOSIZE)
141 self._LCTRL_xdt.SetColumnWidth(1, wx.LIST_AUTOSIZE)
142
143 self._LCTRL_xdt.SetFocus()
144 self._LCTRL_xdt.SetItemState (
145 item = 0,
146 state = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED,
147 stateMask = wx.LIST_STATE_SELECTED | wx.LIST_STATE_FOCUSED
148 )
149
150 self.filename = filename
151
152
153
156
157
158
163
165 - def __init__(self, parent, aFileName = None):
166 wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
167
168
169 tID = wx.NewId()
170 self.list = gmXdtListCtrl(
171 self,
172 tID,
173 style=wx.LC_REPORT | wx.SUNKEN_BORDER | wx.LC_VRULES
174 )
175
176 self.list.InsertColumn(0, _("XDT field"))
177 self.list.InsertColumn(1, _("XDT field content"))
178
179 self.filename = aFileName
180
181
182 wx.EVT_SIZE(self, self.OnSize)
183
184 wx.EVT_LIST_ITEM_SELECTED(self, tID, self.OnItemSelected)
185 wx.EVT_LIST_ITEM_DESELECTED(self, tID, self.OnItemDeselected)
186 wx.EVT_LIST_ITEM_ACTIVATED(self, tID, self.OnItemActivated)
187 wx.EVT_LIST_DELETE_ITEM(self, tID, self.OnItemDelete)
188
189 wx.EVT_LIST_COL_CLICK(self, tID, self.OnColClick)
190 wx.EVT_LIST_COL_RIGHT_CLICK(self, tID, self.OnColRightClick)
191
192
193
194
195 wx.EVT_LEFT_DCLICK(self.list, self.OnDoubleClick)
196 wx.EVT_RIGHT_DOWN(self.list, self.OnRightDown)
197
198 if wx.Platform == '__WXMSW__':
199 wx.EVT_COMMAND_RIGHT_CLICK(self.list, tID, self.OnRightClick)
200 elif wx.Platform == '__WXGTK__':
201 wx.EVT_RIGHT_UP(self.list, self.OnRightClick)
202
203
205
206
207 items = self.__decode_xdt()
208 for item_idx in range(len(items),0,-1):
209 data = items[item_idx]
210 idx = self.list.InsertItem(info=wx.ListItem())
211 self.list.SetItem(index=idx, column=0, label=data[0])
212 self.list.SetItem(index=idx, column=1, label=data[1])
213
214
215
216 self.list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
217 self.list.SetColumnWidth(1, wx.LIST_AUTOSIZE)
218
219
220
221
222
223
224
225
226
227
228
229
230 self.currentItem = 0
231
233 if self.filename is None:
234 _log.error("Need name of file to parse !")
235 return None
236
237 xDTFile = fileinput.input(self.filename)
238 items = {}
239 i = 1
240 for line in xDTFile:
241
242 line = string.replace(line,'\015','')
243 line = string.replace(line,'\012','')
244 length ,ID, content = line[:3], line[3:7], line[7:]
245
246 try:
247 left = xdt_id_map[ID]
248 except KeyError:
249 left = ID
250
251 try:
252 right = xdt_map_of_content_maps[ID][content]
253 except KeyError:
254 right = content
255
256 items[i] = (left, right)
257 i = i + 1
258
259 fileinput.close()
260 return items
261
269
270 - def getColumnText(self, index, col):
271 item = self.list.GetItem(index, col)
272 return item.GetText()
273
275 self.currentItem = event.ItemIndex
276
279
280
281
282
283
285 self.currentItem = event.ItemIndex
286
289
292
295
296
297
298
299
300
301
302
303
304
307
309 return
310 menu = wx.Menu()
311 tPopupID1 = 0
312 tPopupID2 = 1
313 tPopupID3 = 2
314 tPopupID4 = 3
315 tPopupID5 = 5
316
317
318 item = wx.MenuItem(menu, tPopupID1,"One")
319 item.SetBitmap(images.getSmilesBitmap())
320
321 menu.AppendItem(item)
322 menu.Append(tPopupID2, "Two")
323 menu.Append(tPopupID3, "ClearAll and repopulate")
324 menu.Append(tPopupID4, "DeleteAllItems")
325 menu.Append(tPopupID5, "GetItem")
326 wx.EVT_MENU(self, tPopupID1, self.OnPopupOne)
327 wx.EVT_MENU(self, tPopupID2, self.OnPopupTwo)
328 wx.EVT_MENU(self, tPopupID3, self.OnPopupThree)
329 wx.EVT_MENU(self, tPopupID4, self.OnPopupFour)
330 wx.EVT_MENU(self, tPopupID5, self.OnPopupFive)
331 self.PopupMenu(menu, wxPoint(self.x, self.y))
332 menu.Destroy()
333 event.Skip()
334
336 print("FindItem:", self.list.FindItem(-1, "Roxette"))
337 print("FindItemData:", self.list.FindItemData(-1, 11))
338
341
343 self.list.ClearAll()
344 wx.CallAfter(self.PopulateList)
345
346
347
349 self.list.DeleteAllItems()
350
352 item = self.list.GetItem(self.currentItem)
353 print(item.Text, item.Id, self.list.GetItemData(self.currentItem))
354
358
387
388
389
390 if __name__ == '__main__':
391 from Gnumed.pycommon import gmCfg2
392
393 cfg = gmCfg2.gmCfgData()
394 cfg.add_cli(long_options=['xdt-file='])
399
400 fname = ""
401
402 fname = cfg.get(option = '--xdt-file', source_order = [('cli', 'return')])
403 if fname is not None:
404 _log.debug('XDT file is [%s]' % fname)
405
406 if not os.access(fname, os.R_OK):
407 title = _('Opening xDT file')
408 msg = _('Cannot open xDT file.\n'
409 '[%s]') % fname
410 gmGuiHelpers.gm_show_error(msg, title)
411 return False
412 else:
413 title = _('Opening xDT file')
414 msg = _('You must provide an xDT file on the command line.\n'
415 'Format: --xdt-file=<file>')
416 gmGuiHelpers.gm_show_error(msg, title)
417 return False
418
419 frame = wx.Frame(
420 parent = None,
421 id = -1,
422 title = _("XDT Viewer"),
423 size = wx.Size(800,600)
424 )
425 pnl = gmXdtViewerPanel(frame, fname)
426 pnl.Populate()
427 frame.Show(1)
428 return True
429
430 try:
431 app = TestApp ()
432 app.MainLoop ()
433 except Exception:
434 _log.exception('Unhandled exception.')
435 raise
436
437
438