2 # -*- coding: utf-8 -*-
4 #This file is part of CanFestival, a library implementing CanOpen Stack.
6 #Copyright (C): Edouard TISSERANT, Francis DUPIN and Laurent BESSARD
8 #See COPYING file for copyrights details.
10 #This library is free software; you can redistribute it and/or
11 #modify it under the terms of the GNU Lesser General Public
12 #License as published by the Free Software Foundation; either
13 #version 2.1 of the License, or (at your option) any later version.
15 #This library is distributed in the hope that it will be useful,
16 #but WITHOUT ANY WARRANTY; without even the implied warranty of
17 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 #Lesser General Public License for more details.
20 #You should have received a copy of the GNU Lesser General Public
21 #License along with this library; if not, write to the Free Software
22 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 from wxPython.wx import *
25 from wxPython.grid import *
30 import os, re, platform, sys, time, traceback, getopt
32 __version__ = "$Revision: 1.18 $"
34 from nodemanager import *
35 from subindextable import *
36 from commondialogs import *
37 from doc_index.DS301_index import *
40 from wxPython.html import *
42 wxEVT_HTML_URL_CLICK = wxNewId()
44 def EVT_HTML_URL_CLICK(win, func):
45 win.Connect(-1, -1, wxEVT_HTML_URL_CLICK, func)
47 class wxHtmlWindowUrlClick(wxPyEvent):
48 def __init__(self, linkinfo):
49 wxPyEvent.__init__(self)
50 self.SetEventType(wxEVT_HTML_URL_CLICK)
51 self.linkinfo = (linkinfo.GetHref(), linkinfo.GetTarget())
53 class wxUrlClickHtmlWindow(wxHtmlWindow):
54 """ HTML window that generates and OnLinkClicked event.
56 Use this to avoid having to override HTMLWindow
58 def OnLinkClicked(self, linkinfo):
59 wxPostEvent(self, wxHtmlWindowUrlClick(linkinfo))
61 #-------------------------------------------------------------------------------
63 #-------------------------------------------------------------------------------
65 [wxID_HTMLFRAME, wxID_HTMLFRAMEHTMLCONTENT] = [wx.NewId() for _init_ctrls in range(2)]
67 class HtmlFrame(wx.Frame):
68 def _init_ctrls(self, prnt):
69 # generated method, don't edit
70 wx.Frame.__init__(self, id=wxID_HTMLFRAME, name='HtmlFrame',
71 parent=prnt, pos=wx.Point(320, 231), size=wx.Size(853, 616),
72 style=wx.DEFAULT_FRAME_STYLE, title='')
73 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_HTMLFRAME)
75 self.HtmlContent = wxUrlClickHtmlWindow(id=wxID_HTMLFRAMEHTMLCONTENT,
76 name='HtmlContent', parent=self, pos=wx.Point(0, 0),
77 size=wx.Size(-1, -1), style=wxHW_SCROLLBAR_AUTO|wxHW_NO_SELECTION)
78 EVT_HTML_URL_CLICK(self.HtmlContent, self.OnLinkClick)
80 def __init__(self, parent, opened):
81 self._init_ctrls(parent)
82 self.HtmlFrameOpened = opened
84 def SetHtmlCode(self, htmlcode):
85 self.HtmlContent.SetPage(htmlcode)
87 def SetHtmlPage(self, htmlpage):
88 self.HtmlContent.LoadPage(htmlpage)
90 def OnCloseFrame(self, event):
91 self.HtmlFrameOpened.remove(self.GetTitle())
94 def OnLinkClick(self, event):
95 url = event.linkinfo[0]
99 wxMessageBox('Please point your browser at: %s' % url)
108 return objdictedit(parent)
111 print "\nUsage of objdictedit.py :"
112 print "\n %s [Filepath, ...]\n"%sys.argv[0]
115 opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
116 except getopt.GetoptError:
117 # print help information and exit:
122 if o in ("-h", "--help"):
127 ScriptDirectory = sys.path[0]
130 [wxID_OBJDICTEDIT, wxID_OBJDICTEDITFILEOPENED,
131 wxID_OBJDICTEDITHELPBAR,
132 ] = [wx.NewId() for _init_ctrls in range(3)]
134 [wxID_OBJDICTEDITADDMENUITEMS0, wxID_OBJDICTEDITADDMENUITEMS1,
135 wxID_OBJDICTEDITADDMENUITEMS2, wxID_OBJDICTEDITADDMENUITEMS3,
136 wxID_OBJDICTEDITADDMENUITEMS4, wxID_OBJDICTEDITADDMENUITEMS5,
137 ] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
139 [wxID_OBJDICTEDITFILEMENUITEMS0, wxID_OBJDICTEDITFILEMENUITEMS1,
140 wxID_OBJDICTEDITFILEMENUITEMS2, wxID_OBJDICTEDITFILEMENUITEMS4,
141 wxID_OBJDICTEDITFILEMENUITEMS5, wxID_OBJDICTEDITFILEMENUITEMS6,
142 wxID_OBJDICTEDITFILEMENUITEMS7, wxID_OBJDICTEDITFILEMENUITEMS8,
143 wxID_OBJDICTEDITFILEMENUITEMS9,
144 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(9)]
146 [wxID_OBJDICTEDITEDITMENUITEMS0, wxID_OBJDICTEDITEDITMENUITEMS1,
147 wxID_OBJDICTEDITEDITMENUITEMS2, wxID_OBJDICTEDITEDITMENUITEMS4,
148 wxID_OBJDICTEDITEDITMENUITEMS6, wxID_OBJDICTEDITEDITMENUITEMS7,
149 wxID_OBJDICTEDITEDITMENUITEMS8,
150 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(7)]
152 [wxID_OBJDICTEDITHELPMENUITEMS0, wxID_OBJDICTEDITHELPMENUITEMS1,
153 wxID_OBJDICTEDITHELPMENUITEMS2,
154 ] = [wx.NewId() for _init_coll_HelpMenu_Items in range(3)]
156 class objdictedit(wx.Frame):
157 def _init_coll_menuBar1_Menus(self, parent):
158 # generated method, don't edit
160 parent.Append(menu=self.FileMenu, title='File')
161 parent.Append(menu=self.EditMenu, title='Edit')
162 parent.Append(menu=self.AddMenu, title='Add')
163 parent.Append(menu=self.HelpMenu, title='Help')
165 def _init_coll_EditMenu_Items(self, parent):
166 # generated method, don't edit
168 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS4,
169 kind=wx.ITEM_NORMAL, text='Refresh\tCTRL+R')
170 parent.AppendSeparator()
171 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS1,
172 kind=wx.ITEM_NORMAL, text='Undo\tCTRL+Z')
173 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS0,
174 kind=wx.ITEM_NORMAL, text='Redo\tCTRL+Y')
175 parent.AppendSeparator()
176 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS6,
177 kind=wx.ITEM_NORMAL, text='Node infos')
178 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS2,
179 kind=wx.ITEM_NORMAL, text='DS-301 Profile')
180 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS8,
181 kind=wx.ITEM_NORMAL, text='DS-302 Profile')
182 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS7,
183 kind=wx.ITEM_NORMAL, text='Other Profile')
184 self.Bind(wx.EVT_MENU, self.OnUndoMenu,
185 id=wxID_OBJDICTEDITEDITMENUITEMS1)
186 self.Bind(wx.EVT_MENU, self.OnRedoMenu,
187 id=wxID_OBJDICTEDITEDITMENUITEMS0)
188 self.Bind(wx.EVT_MENU, self.OnCommunicationMenu,
189 id=wxID_OBJDICTEDITEDITMENUITEMS2)
190 self.Bind(wx.EVT_MENU, self.OnRefreshMenu,
191 id=wxID_OBJDICTEDITEDITMENUITEMS4)
192 self.Bind(wx.EVT_MENU, self.OnNodeInfosMenu,
193 id=wxID_OBJDICTEDITEDITMENUITEMS6)
194 self.Bind(wx.EVT_MENU, self.OnEditProfileMenu,
195 id=wxID_OBJDICTEDITEDITMENUITEMS7)
196 self.Bind(wx.EVT_MENU, self.OnOtherCommunicationMenu,
197 id=wxID_OBJDICTEDITEDITMENUITEMS8)
199 def _init_coll_HelpMenu_Items(self, parent):
200 # generated method, don't edit
202 parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS0,
203 kind=wx.ITEM_NORMAL, text='DS-301 Standard\tF1')
204 self.Bind(wx.EVT_MENU, self.OnHelpDS301Menu,
205 id=wxID_OBJDICTEDITHELPMENUITEMS0)
206 parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS1,
207 kind=wx.ITEM_NORMAL, text='CAN Festival Docs\tF2')
208 self.Bind(wx.EVT_MENU, self.OnHelpCANFestivalMenu,
209 id=wxID_OBJDICTEDITHELPMENUITEMS1)
211 parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS2,
212 kind=wx.ITEM_NORMAL, text='About')
213 self.Bind(wx.EVT_MENU, self.OnAboutMenu,
214 id=wxID_OBJDICTEDITHELPMENUITEMS2)
216 def _init_coll_FileMenu_Items(self, parent):
217 # generated method, don't edit
219 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS5,
220 kind=wx.ITEM_NORMAL, text='New\tCTRL+N')
221 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS0,
222 kind=wx.ITEM_NORMAL, text='Open\tCTRL+O')
223 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS1,
224 kind=wx.ITEM_NORMAL, text='Save\tCTRL+S')
225 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS6,
226 kind=wx.ITEM_NORMAL, text='Save As...\tALT+S')
227 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS2,
228 kind=wx.ITEM_NORMAL, text='Close\tCTRL+W')
229 parent.AppendSeparator()
230 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS7,
231 kind=wx.ITEM_NORMAL, text='Import EDS file')
232 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS9,
233 kind=wx.ITEM_NORMAL, text='Export to EDS file')
234 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS8,
235 kind=wx.ITEM_NORMAL, text='Build Dictionary\tCTRL+B')
236 parent.AppendSeparator()
237 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS4,
238 kind=wx.ITEM_NORMAL, text='Exit')
239 self.Bind(wx.EVT_MENU, self.OnOpenMenu,
240 id=wxID_OBJDICTEDITFILEMENUITEMS0)
241 self.Bind(wx.EVT_MENU, self.OnSaveMenu,
242 id=wxID_OBJDICTEDITFILEMENUITEMS1)
243 self.Bind(wx.EVT_MENU, self.OnCloseMenu,
244 id=wxID_OBJDICTEDITFILEMENUITEMS2)
245 self.Bind(wx.EVT_MENU, self.OnQuitMenu,
246 id=wxID_OBJDICTEDITFILEMENUITEMS4)
247 self.Bind(wx.EVT_MENU, self.OnNewMenu,
248 id=wxID_OBJDICTEDITFILEMENUITEMS5)
249 self.Bind(wx.EVT_MENU, self.OnSaveAsMenu,
250 id=wxID_OBJDICTEDITFILEMENUITEMS6)
251 self.Bind(wx.EVT_MENU, self.OnImportEDSMenu,
252 id=wxID_OBJDICTEDITFILEMENUITEMS7)
253 self.Bind(wx.EVT_MENU, self.OnExportCMenu,
254 id=wxID_OBJDICTEDITFILEMENUITEMS8)
255 self.Bind(wx.EVT_MENU, self.OnExportEDSMenu,
256 id=wxID_OBJDICTEDITFILEMENUITEMS9)
258 def _init_coll_AddMenu_Items(self, parent):
259 # generated method, don't edit
261 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS0,
262 kind=wx.ITEM_NORMAL, text='SDO Server')
263 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS1,
264 kind=wx.ITEM_NORMAL, text='SDO Client')
265 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS2,
266 kind=wx.ITEM_NORMAL, text='PDO Transmit')
267 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS3,
268 kind=wx.ITEM_NORMAL, text='PDO Receive')
269 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS4,
270 kind=wx.ITEM_NORMAL, text='Map Variable')
271 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS5,
272 kind=wx.ITEM_NORMAL, text='User Type')
273 self.Bind(wx.EVT_MENU, self.OnAddSDOServerMenu,
274 id=wxID_OBJDICTEDITADDMENUITEMS0)
275 self.Bind(wx.EVT_MENU, self.OnAddSDOClientMenu,
276 id=wxID_OBJDICTEDITADDMENUITEMS1)
277 self.Bind(wx.EVT_MENU, self.OnAddPDOTransmitMenu,
278 id=wxID_OBJDICTEDITADDMENUITEMS2)
279 self.Bind(wx.EVT_MENU, self.OnAddPDOReceiveMenu,
280 id=wxID_OBJDICTEDITADDMENUITEMS3)
281 self.Bind(wx.EVT_MENU, self.OnAddMapVariableMenu,
282 id=wxID_OBJDICTEDITADDMENUITEMS4)
283 self.Bind(wx.EVT_MENU, self.OnAddUserTypeMenu,
284 id=wxID_OBJDICTEDITADDMENUITEMS5)
286 def _init_coll_HelpBar_Fields(self, parent):
287 # generated method, don't edit
288 parent.SetFieldsCount(3)
290 parent.SetStatusText(number=0, text='')
291 parent.SetStatusText(number=1, text='')
292 parent.SetStatusText(number=2, text='')
294 parent.SetStatusWidths([100, 110, -1])
296 def _init_utils(self):
297 # generated method, don't edit
298 self.menuBar1 = wx.MenuBar()
299 self.menuBar1.SetEvtHandlerEnabled(True)
301 self.FileMenu = wx.Menu(title='')
303 self.EditMenu = wx.Menu(title='')
305 self.AddMenu = wx.Menu(title='')
307 self.HelpMenu = wx.Menu(title='')
309 self._init_coll_menuBar1_Menus(self.menuBar1)
310 self._init_coll_FileMenu_Items(self.FileMenu)
311 self._init_coll_EditMenu_Items(self.EditMenu)
312 self._init_coll_AddMenu_Items(self.AddMenu)
313 self._init_coll_HelpMenu_Items(self.HelpMenu)
315 def _init_ctrls(self, prnt):
316 # generated method, don't edit
317 wx.Frame.__init__(self, id=wxID_OBJDICTEDIT, name='objdictedit',
318 parent=prnt, pos=wx.Point(149, 178), size=wx.Size(1000, 700),
319 style=wx.DEFAULT_FRAME_STYLE, title='Objdictedit')
321 self.SetClientSize(wx.Size(1000, 700))
322 self.SetMenuBar(self.menuBar1)
323 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_OBJDICTEDIT)
325 self.FileOpened = wx.Notebook(id=wxID_OBJDICTEDITFILEOPENED,
326 name='FileOpened', parent=self, pos=wx.Point(0, 0),
327 size=wx.Size(0, 0), style=0)
328 self.FileOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
329 self.OnFileSelectedChanged, id=wxID_OBJDICTEDITFILEOPENED)
331 self.HelpBar = wx.StatusBar(id=wxID_OBJDICTEDITHELPBAR, name='HelpBar',
332 parent=self, style=wxST_SIZEGRIP)
333 self._init_coll_HelpBar_Fields(self.HelpBar)
334 self.SetStatusBar(self.HelpBar)
336 def __init__(self, parent):
337 self._init_ctrls(parent)
338 self.HtmlFrameOpened = []
340 self.Manager = NodeManager(ScriptDirectory)
341 for filepath in filesOpen:
342 self.Manager.OpenFileInCurrent(filepath)
343 new_editingpanel = EditingPanel(self, self.Manager)
344 self.FileOpened.AddPage(new_editingpanel, "")
345 self.FileOpened.SetSelection(self.Manager.GetCurrentNodeIndex())
346 if self.Manager.CurrentDS302Defined():
347 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
349 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
350 self.RefreshEditMenu()
351 self.RefreshBufferState()
352 self.RefreshProfileMenu()
354 self.RefreshMainMenu()
356 def GetNoteBook(self):
357 return self.FileOpened
359 def OnAddSDOServerMenu(self, event):
360 self.Manager.AddSDOServerToCurrent()
361 self.RefreshBufferState()
362 self.RefreshCurrentIndexList()
365 def OnAddSDOClientMenu(self, event):
366 self.Manager.AddSDOClientToCurrent()
367 self.RefreshBufferState()
368 self.RefreshCurrentIndexList()
371 def OnAddPDOTransmitMenu(self, event):
372 self.Manager.AddPDOTransmitToCurrent()
373 self.RefreshBufferState()
374 self.RefreshCurrentIndexList()
377 def OnAddPDOReceiveMenu(self, event):
378 self.Manager.AddPDOReceiveToCurrent()
379 self.RefreshBufferState()
380 self.RefreshCurrentIndexList()
383 def OnAddMapVariableMenu(self, event):
384 self.AddMapVariable()
387 def OnAddUserTypeMenu(self, event):
391 def OnFileSelectedChanged(self, event):
392 selected = event.GetSelection()
393 # At init selected = -1
395 window = self.FileOpened.GetPage(selected)
396 self.Manager.ChangeCurrentNode(window.GetIndex())
397 self.RefreshBufferState()
398 self.RefreshStatusBar()
399 self.RefreshProfileMenu()
402 def OnHelpDS301Menu(self, event):
404 selected = self.FileOpened.GetSelection()
406 window = self.FileOpened.GetPage(selected)
407 result = window.GetSelection()
410 index, subIndex = result
411 result = OpenPDFDocIndex(index, ScriptDirectory)
412 if type(result) == StringType:
413 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
417 result = OpenPDFDocIndex(None, ScriptDirectory)
418 if type(result) == StringType:
419 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
424 def OnHelpCANFestivalMenu(self, event):
425 #self.OpenHtmlFrame("CAN Festival Reference", os.path.join(ScriptDirectory, "doc/canfestival.html"), wx.Size(1000, 600))
426 os.system("xpdf -remote CANFESTIVAL %s %d &"%(os.path.join(ScriptDirectory, "doc/manual_en.pdf"),16))
429 def OnAboutMenu(self, event):
430 self.OpenHtmlFrame("About CAN Festival", os.path.join(ScriptDirectory, "doc/about.html"), wx.Size(500, 450))
433 def OpenHtmlFrame(self, title, file, size):
434 if title not in self.HtmlFrameOpened:
435 self.HtmlFrameOpened.append(title)
436 window = HtmlFrame(self, self.HtmlFrameOpened)
437 window.SetTitle(title)
438 window.SetHtmlPage(file)
439 window.SetClientSize(size)
442 def OnQuitMenu(self, event):
446 def OnCloseFrame(self, event):
447 if self.Manager.OneFileHasChanged():
448 dialog = wxMessageDialog(self, "There are changes, do you want to save?", "Close Application", wxYES_NO|wxCANCEL|wxICON_QUESTION)
449 answer = dialog.ShowModal()
451 if answer == wxID_YES:
452 self.Manager.ChangeCurrentNode(0)
453 for i in xrange(self.FileOpened.GetPageCount()):
454 if self.Manager.CurrentIsSaved():
455 self.Manager.CloseCurrent()
458 self.Manager.CloseCurrent(True)
460 elif answer == wxID_NO:
461 for i in xrange(self.FileOpened.GetPageCount()):
462 self.Manager.CloseCurrent(True)
463 wxCallAfter(self.Close)
468 #-------------------------------------------------------------------------------
470 #-------------------------------------------------------------------------------
472 def RefreshTitle(self):
473 if self.FileOpened.GetPageCount() > 0:
474 self.SetTitle("Objdictedit - %s"%self.Manager.GetCurrentFilename())
476 self.SetTitle("Objdictedit")
478 def OnRefreshMenu(self, event):
479 self.RefreshCurrentIndexList()
482 def RefreshCurrentIndexList(self):
483 selected = self.FileOpened.GetSelection()
484 window = self.FileOpened.GetPage(selected)
485 window.RefreshIndexList()
487 def RefreshStatusBar(self):
489 window = self.FileOpened.GetPage(self.FileOpened.GetSelection())
490 selection = window.GetSelection()
492 index, subIndex = selection
493 if self.Manager.IsCurrentEntry(index):
494 self.HelpBar.SetStatusText("Index: 0x%04X"%index, 0)
495 self.HelpBar.SetStatusText("Subindex: 0x%02X"%subIndex, 1)
496 entryinfos = self.Manager.GetEntryInfos(index)
497 name = entryinfos["name"]
498 category = "Optional"
499 if entryinfos["need"]:
500 category = "Mandatory"
503 if entryinfos["struct"] & OD_IdenticalIndexes:
504 number = " possibly defined %d times"%entryinfos["nbmax"]
505 if entryinfos["struct"] & OD_IdenticalSubindexes:
507 elif entryinfos["struct"] & OD_MultipleSubindexes:
509 text = "%s: %s entry of struct %s%s."%(name,category,struct,number)
510 self.HelpBar.SetStatusText(text, 2)
513 self.HelpBar.SetStatusText("", i)
516 self.HelpBar.SetStatusText("", i)
518 def RefreshMainMenu(self):
520 if self.FileOpened.GetPageCount() > 0:
521 self.menuBar1.EnableTop(1, True)
522 self.menuBar1.EnableTop(2, True)
523 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, True)
524 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, True)
525 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, True)
526 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, True)
527 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS9, True)
529 self.menuBar1.EnableTop(1, False)
530 self.menuBar1.EnableTop(2, False)
531 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, False)
532 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, False)
533 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, False)
534 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, False)
535 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS9, False)
537 def RefreshEditMenu(self):
539 if self.FileOpened.GetPageCount() > 0:
540 undo, redo = self.Manager.GetCurrentBufferState()
541 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS1, undo)
542 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS0, redo)
544 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS1, False)
545 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS0, False)
547 def RefreshProfileMenu(self):
549 profile = self.Manager.GetCurrentProfileName()
550 edititem = self.EditMenu.FindItemById(wxID_OBJDICTEDITEDITMENUITEMS7)
552 length = self.AddMenu.GetMenuItemCount()
553 for i in xrange(length-6):
554 additem = self.AddMenu.FindItemByPosition(6)
555 self.AddMenu.Delete(additem.GetId())
556 if profile not in ("None", "DS-301"):
557 edititem.SetText("%s Profile"%profile)
558 edititem.Enable(True)
559 self.AddMenu.AppendSeparator()
560 for text, indexes in self.Manager.GetCurrentSpecificMenu():
562 self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
563 self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
565 edititem.SetText("Other Profile")
566 edititem.Enable(False)
569 #-------------------------------------------------------------------------------
571 #-------------------------------------------------------------------------------
573 def RefreshBufferState(self):
574 fileopened = self.Manager.GetAllFilenames()
575 for idx, filename in enumerate(fileopened):
576 self.FileOpened.SetPageText(idx, filename)
577 self.RefreshEditMenu()
580 def OnUndoMenu(self, event):
581 self.Manager.LoadCurrentPrevious()
582 self.RefreshCurrentIndexList()
583 self.RefreshBufferState()
586 def OnRedoMenu(self, event):
587 self.Manager.LoadCurrentNext()
588 self.RefreshCurrentIndexList()
589 self.RefreshBufferState()
593 #-------------------------------------------------------------------------------
594 # Load and Save Funtions
595 #-------------------------------------------------------------------------------
597 def OnNewMenu(self, event):
599 dialog = CreateNodeDialog(self)
600 if dialog.ShowModal() == wxID_OK:
601 name, id, nodetype, description = dialog.GetValues()
602 profile, filepath = dialog.GetProfile()
603 NMT = dialog.GetNMTManagement()
604 options = dialog.GetOptions()
605 result = self.Manager.CreateNewNode(name, id, nodetype, description, profile, filepath, NMT, options)
606 if type(result) == IntType:
607 new_editingpanel = EditingPanel(self, self.Manager)
608 new_editingpanel.SetIndex(result)
609 self.FileOpened.AddPage(new_editingpanel, "")
610 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
611 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
612 if "DS302" in options:
613 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
614 self.RefreshBufferState()
615 self.RefreshProfileMenu()
616 self.RefreshMainMenu()
618 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
623 def OnOpenMenu(self, event):
624 filepath = self.Manager.GetCurrentFilePath()
626 directory = os.path.dirname(filepath)
628 directory = os.getcwd()
629 dialog = wxFileDialog(self, "Choose a file", directory, "", "OD files (*.od)|*.od|All files|*.*", wxOPEN|wxCHANGE_DIR)
630 if dialog.ShowModal() == wxID_OK:
631 filepath = dialog.GetPath()
632 if os.path.isfile(filepath):
633 result = self.Manager.OpenFileInCurrent(filepath)
634 if type(result) == IntType:
635 new_editingpanel = EditingPanel(self, self.Manager)
636 new_editingpanel.SetIndex(result)
637 self.FileOpened.AddPage(new_editingpanel, "")
638 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
639 if self.Manager.CurrentDS302Defined():
640 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
642 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
643 self.RefreshEditMenu()
644 self.RefreshBufferState()
645 self.RefreshProfileMenu()
646 self.RefreshMainMenu()
648 message = wxMessageDialog(self, e.args[0], "Error", wxOK|wxICON_ERROR)
654 def OnSaveMenu(self, event):
658 def OnSaveAsMenu(self, event):
663 result = self.Manager.SaveCurrentInFile()
666 elif type(result) != StringType:
667 self.RefreshBufferState()
669 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
674 filepath = self.Manager.GetCurrentFilePath()
676 directory, filename = os.path.split(filepath)
678 directory, filename = os.getcwd(), "%s.od"%self.Manager.GetCurrentNodeInfos()[0]
679 dialog = wxFileDialog(self, "Choose a file", directory, filename, "OD files (*.od)|*.od|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT|wxCHANGE_DIR)
680 if dialog.ShowModal() == wxID_OK:
681 filepath = dialog.GetPath()
682 if os.path.isdir(os.path.dirname(filepath)):
683 result = self.Manager.SaveCurrentInFile(filepath)
684 if type(result) != StringType:
685 self.RefreshBufferState()
687 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
691 message = wxMessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
696 def OnCloseMenu(self, event):
698 result = self.Manager.CloseCurrent()
700 dialog = wxMessageDialog(self, "There are changes, do you want to save?", "Close File", wxYES_NO|wxCANCEL|wxICON_QUESTION)
701 answer = dialog.ShowModal()
703 if answer == wxID_YES:
704 self.OnSaveMenu(event)
705 if self.Manager.CurrentIsSaved():
706 self.Manager.CloseCurrent()
707 elif answer == wxID_NO:
708 self.Manager.CloseCurrent(True)
709 if self.FileOpened.GetPageCount() > self.Manager.GetBufferNumber():
710 current = self.FileOpened.GetSelection()
711 self.FileOpened.DeletePage(current)
712 if self.FileOpened.GetPageCount() > 0:
713 self.FileOpened.SetSelection(min(current, self.FileOpened.GetPageCount() - 1))
714 self.RefreshBufferState()
715 self.RefreshMainMenu()
719 #-------------------------------------------------------------------------------
720 # Import and Export Functions
721 #-------------------------------------------------------------------------------
723 def OnImportEDSMenu(self, event):
724 dialog = wxFileDialog(self, "Choose a file", os.getcwd(), "", "EDS files (*.eds)|*.eds|All files|*.*", wxOPEN|wxCHANGE_DIR)
725 if dialog.ShowModal() == wxID_OK:
726 filepath = dialog.GetPath()
727 if os.path.isfile(filepath):
728 result = self.Manager.ImportCurrentFromEDSFile(filepath)
729 if type(result) == IntType:
730 new_editingpanel = EditingPanel(self, self.Manager)
731 new_editingpanel.SetIndex(result)
732 self.FileOpened.AddPage(new_editingpanel, "")
733 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
734 self.RefreshBufferState()
735 self.RefreshCurrentIndexList()
736 self.RefreshProfileMenu()
737 self.RefreshMainMenu()
738 message = wxMessageDialog(self, "Import successful", "Information", wxOK|wxICON_INFORMATION)
742 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
746 message = wxMessageDialog(self, "\"%s\" is not a valid file!"%filepath, "Error", wxOK|wxICON_ERROR)
753 def OnExportEDSMenu(self, event):
754 dialog = wxFileDialog(self, "Choose a file", os.getcwd(), self.Manager.GetCurrentNodeInfos()[0], "EDS files (*.eds)|*.eds|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT|wxCHANGE_DIR)
755 if dialog.ShowModal() == wxID_OK:
756 filepath = dialog.GetPath()
757 if os.path.isdir(os.path.dirname(filepath)):
758 path, extend = os.path.splitext(filepath)
759 if extend in ("", "."):
760 filepath = path + ".eds"
761 result = self.Manager.ExportCurrentToEDSFile(filepath)
763 message = wxMessageDialog(self, "Export successful", "Information", wxOK|wxICON_INFORMATION)
767 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
771 message = wxMessageDialog(self, "\"%s\" is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
777 def OnExportCMenu(self, event):
778 dialog = wxFileDialog(self, "Choose a file", os.getcwd(), self.Manager.GetCurrentNodeInfos()[0], "CANFestival OD files (*.c)|*.c|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT|wxCHANGE_DIR)
779 if dialog.ShowModal() == wxID_OK:
780 filepath = dialog.GetPath()
781 if os.path.isdir(os.path.dirname(filepath)):
782 path, extend = os.path.splitext(filepath)
783 if extend in ("", "."):
784 filepath = path + ".c"
785 result = self.Manager.ExportCurrentToCFile(filepath)
787 message = wxMessageDialog(self, "Export successful", "Information", wxOK|wxICON_INFORMATION)
791 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
795 message = wxMessageDialog(self, "\"%s\" is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
801 #-------------------------------------------------------------------------------
802 # Editing Profiles functions
803 #-------------------------------------------------------------------------------
805 def OnCommunicationMenu(self, event):
806 dictionary,current = self.Manager.GetCurrentCommunicationLists()
807 self.EditProfile("Edit DS-301 Profile", dictionary, current)
810 def OnOtherCommunicationMenu(self, event):
811 dictionary,current = self.Manager.GetCurrentDS302Lists()
812 self.EditProfile("Edit DS-301 Profile", dictionary, current)
815 def OnEditProfileMenu(self, event):
816 title = "Edit %s Profile"%self.Manager.GetCurrentProfileName()
817 dictionary,current = self.Manager.GetCurrentProfileLists()
818 self.EditProfile(title, dictionary, current)
821 def EditProfile(self, title, dictionary, current):
822 dialog = CommunicationDialog(self)
823 dialog.SetTitle(title)
824 dialog.SetIndexDictionary(dictionary)
825 dialog.SetCurrentList(current)
826 dialog.RefreshLists()
827 if dialog.ShowModal() == wxID_OK:
828 new_profile = dialog.GetCurrentList()
831 for index in new_profile:
832 if index not in current:
833 addinglist.append(index)
834 for index in current:
835 if index not in new_profile:
836 removinglist.append(index)
837 self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
838 self.Manager.GenerateMapList()
839 self.Manager.BufferCurrentNode()
840 self.RefreshBufferState()
841 self.RefreshCurrentIndexList()
844 def GetProfileCallBack(self, text):
845 def ProfileCallBack(event):
846 self.Manager.AddSpecificEntryToCurrent(text)
847 self.RefreshBufferState()
848 self.RefreshCurrentIndexList()
850 return ProfileCallBack
852 #-------------------------------------------------------------------------------
853 # Edit Node informations function
854 #-------------------------------------------------------------------------------
856 def OnNodeInfosMenu(self, event):
857 dialog = NodeInfosDialog(self)
858 name, id, type, description = self.Manager.GetCurrentNodeInfos()
859 dialog.SetValues(name, id, type, description)
860 if dialog.ShowModal() == wxID_OK:
861 name, id, type, description = dialog.GetValues()
862 self.Manager.SetCurrentNodeInfos(name, id, type, description)
863 self.RefreshBufferState()
864 self.RefreshProfileMenu()
865 selected = self.FileOpened.GetSelection()
867 window = self.FileOpened.GetPage(selected)
868 window.RefreshTable()
872 #-------------------------------------------------------------------------------
873 # Add User Types and Variables
874 #-------------------------------------------------------------------------------
876 def AddMapVariable(self):
877 index = self.Manager.GetCurrentNextMapIndex()
879 dialog = MapVariableDialog(self)
880 dialog.SetIndex(index)
881 if dialog.ShowModal() == wxID_OK:
882 index, name, struct, number = dialog.GetValues()
883 result = self.Manager.AddMapVariableToCurrent(index, name, struct, number)
884 if type(result) != StringType:
885 self.RefreshBufferState()
886 self.RefreshCurrentIndexList()
888 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
893 message = wxMessageDialog(self, result, "No map variable index left!", wxOK|wxICON_ERROR)
897 def AddUserType(self):
898 dialog = UserTypeDialog(self)
899 dialog.SetTypeList(self.Manager.GetCustomisableTypes())
900 if dialog.ShowModal() == wxID_OK:
901 type, min, max, length = dialog.GetValues()
902 result = self.Manager.AddUserTypeToCurrent(type, min, max, length)
904 self.RefreshBufferState()
905 self.RefreshCurrentIndexList()
907 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
913 #-------------------------------------------------------------------------------
915 #-------------------------------------------------------------------------------
917 Max_Traceback_List_Size = 20
919 def Display_Exception_Dialog(e_type,e_value,e_tb):
921 for i,line in enumerate(traceback.extract_tb(e_tb)):
922 trcbck = " " + str(i+1) + ". "
923 if line[0].find(os.getcwd()) == -1:
924 trcbck += "file : " + str(line[0]) + ", "
926 trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ", "
927 trcbck += "line : " + str(line[1]) + ", " + "function : " + str(line[2])
928 trcbck_lst.append(trcbck)
931 cap = wx.Window_GetCapture()
935 dlg = wx.SingleChoiceDialog(None,
939 Click on OK for saving an error report.
941 Please contact LOLITech at:
943 bugs_objdictedit@lolitech.fr
948 str(e_type) + " : " + str(e_value),
952 res = (dlg.ShowModal() == wx.ID_OK)
958 def Display_Error_Dialog(e_value):
959 message = wxMessageDialog(None, str(e_value), "Error", wxOK|wxICON_ERROR)
963 def get_last_traceback(tb):
969 def format_namespace(d, indent=' '):
970 return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
973 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
975 def wxAddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
977 def handle_exception(e_type, e_value, e_traceback):
978 traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
979 last_tb = get_last_traceback(e_traceback)
980 ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
981 if str(e_value).startswith("!!!"):
982 Display_Error_Dialog(e_value)
983 elif ex not in ignored_exceptions:
984 ignored_exceptions.append(ex)
985 result = Display_Exception_Dialog(e_type,e_value,e_traceback)
988 'app-title' : wx.GetApp().GetAppName(), # app_title
989 'app-version' : app_version,
990 'wx-version' : wx.VERSION_STRING,
991 'wx-platform' : wx.Platform,
992 'python-version' : platform.python_version(), #sys.version.split()[0],
993 'platform' : platform.platform(),
996 'date' : time.ctime(),
1000 info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
1001 last_tb = get_last_traceback(e_traceback)
1002 exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
1003 info['locals'] = format_namespace(exception_locals)
1004 if 'self' in exception_locals:
1005 info['self'] = format_namespace(exception_locals['self'].__dict__)
1007 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
1011 output.write(a+":\n"+str(info[a])+"\n\n")
1013 #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
1014 sys.excepthook = handle_exception
1016 if __name__ == '__main__':
1017 app = wxPySimpleApp()
1018 wxInitAllImageHandlers()
1020 # Install a exception handle for bug reports
1021 wxAddExceptHook(os.getcwd(),__version__)
1023 frame = objdictedit(None)