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.25 $"
34 from node import OD_Subindex, OD_MultipleSubindexes, OD_IdenticalSubindexes, OD_IdenticalIndexes
36 from nodemanager import *
37 from subindextable import *
38 from commondialogs import *
39 from doc_index.DS301_index import *
42 from wxPython.html import *
44 wxEVT_HTML_URL_CLICK = wxNewId()
46 def EVT_HTML_URL_CLICK(win, func):
47 win.Connect(-1, -1, wxEVT_HTML_URL_CLICK, func)
49 class wxHtmlWindowUrlClick(wxPyEvent):
50 def __init__(self, linkinfo):
51 wxPyEvent.__init__(self)
52 self.SetEventType(wxEVT_HTML_URL_CLICK)
53 self.linkinfo = (linkinfo.GetHref(), linkinfo.GetTarget())
55 class wxUrlClickHtmlWindow(wxHtmlWindow):
56 """ HTML window that generates and OnLinkClicked event.
58 Use this to avoid having to override HTMLWindow
60 def OnLinkClicked(self, linkinfo):
61 wxPostEvent(self, wxHtmlWindowUrlClick(linkinfo))
63 #-------------------------------------------------------------------------------
65 #-------------------------------------------------------------------------------
67 [wxID_HTMLFRAME, wxID_HTMLFRAMEHTMLCONTENT] = [wx.NewId() for _init_ctrls in range(2)]
69 class HtmlFrame(wx.Frame):
70 def _init_ctrls(self, prnt):
71 # generated method, don't edit
72 wx.Frame.__init__(self, id=wxID_HTMLFRAME, name='HtmlFrame',
73 parent=prnt, pos=wx.Point(320, 231), size=wx.Size(853, 616),
74 style=wx.DEFAULT_FRAME_STYLE, title='')
75 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_HTMLFRAME)
77 self.HtmlContent = wxUrlClickHtmlWindow(id=wxID_HTMLFRAMEHTMLCONTENT,
78 name='HtmlContent', parent=self, pos=wx.Point(0, 0),
79 size=wx.Size(-1, -1), style=wxHW_SCROLLBAR_AUTO|wxHW_NO_SELECTION)
80 EVT_HTML_URL_CLICK(self.HtmlContent, self.OnLinkClick)
82 def __init__(self, parent, opened):
83 self._init_ctrls(parent)
84 self.HtmlFrameOpened = opened
86 def SetHtmlCode(self, htmlcode):
87 self.HtmlContent.SetPage(htmlcode)
89 def SetHtmlPage(self, htmlpage):
90 self.HtmlContent.LoadPage(htmlpage)
92 def OnCloseFrame(self, event):
93 self.HtmlFrameOpened.remove(self.GetTitle())
96 def OnLinkClick(self, event):
97 url = event.linkinfo[0]
101 wxMessageBox('Please point your browser at: %s' % url)
110 return objdictedit(parent)
113 print "\nUsage of objdictedit.py :"
114 print "\n %s [Filepath, ...]\n"%sys.argv[0]
117 opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
118 except getopt.GetoptError:
119 # print help information and exit:
124 if o in ("-h", "--help"):
129 ScriptDirectory = sys.path[0]
132 [wxID_OBJDICTEDIT, wxID_OBJDICTEDITFILEOPENED,
133 wxID_OBJDICTEDITHELPBAR,
134 ] = [wx.NewId() for _init_ctrls in range(3)]
136 [wxID_OBJDICTEDITADDMENUITEMS0, wxID_OBJDICTEDITADDMENUITEMS1,
137 wxID_OBJDICTEDITADDMENUITEMS2, wxID_OBJDICTEDITADDMENUITEMS3,
138 wxID_OBJDICTEDITADDMENUITEMS4, wxID_OBJDICTEDITADDMENUITEMS5,
139 ] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
141 [wxID_OBJDICTEDITFILEMENUITEMS0, wxID_OBJDICTEDITFILEMENUITEMS1,
142 wxID_OBJDICTEDITFILEMENUITEMS2, wxID_OBJDICTEDITFILEMENUITEMS4,
143 wxID_OBJDICTEDITFILEMENUITEMS5, wxID_OBJDICTEDITFILEMENUITEMS6,
144 wxID_OBJDICTEDITFILEMENUITEMS7, wxID_OBJDICTEDITFILEMENUITEMS8,
145 wxID_OBJDICTEDITFILEMENUITEMS9,
146 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(9)]
148 [wxID_OBJDICTEDITEDITMENUITEMS0, wxID_OBJDICTEDITEDITMENUITEMS1,
149 wxID_OBJDICTEDITEDITMENUITEMS2, wxID_OBJDICTEDITEDITMENUITEMS4,
150 wxID_OBJDICTEDITEDITMENUITEMS6, wxID_OBJDICTEDITEDITMENUITEMS7,
151 wxID_OBJDICTEDITEDITMENUITEMS8,
152 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(7)]
154 [wxID_OBJDICTEDITHELPMENUITEMS0, wxID_OBJDICTEDITHELPMENUITEMS1,
155 wxID_OBJDICTEDITHELPMENUITEMS2,
156 ] = [wx.NewId() for _init_coll_HelpMenu_Items in range(3)]
158 class objdictedit(wx.Frame):
159 def _init_coll_menuBar1_Menus(self, parent):
160 # generated method, don't edit
162 parent.Append(menu=self.FileMenu, title='File')
163 parent.Append(menu=self.EditMenu, title='Edit')
164 parent.Append(menu=self.AddMenu, title='Add')
165 parent.Append(menu=self.HelpMenu, title='Help')
167 def _init_coll_EditMenu_Items(self, parent):
168 # generated method, don't edit
170 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS4,
171 kind=wx.ITEM_NORMAL, text='Refresh\tCTRL+R')
172 parent.AppendSeparator()
173 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS1,
174 kind=wx.ITEM_NORMAL, text='Undo\tCTRL+Z')
175 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS0,
176 kind=wx.ITEM_NORMAL, text='Redo\tCTRL+Y')
177 parent.AppendSeparator()
178 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS6,
179 kind=wx.ITEM_NORMAL, text='Node infos')
180 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS2,
181 kind=wx.ITEM_NORMAL, text='DS-301 Profile')
182 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS8,
183 kind=wx.ITEM_NORMAL, text='DS-302 Profile')
184 parent.Append(help='', id=wxID_OBJDICTEDITEDITMENUITEMS7,
185 kind=wx.ITEM_NORMAL, text='Other Profile')
186 self.Bind(wx.EVT_MENU, self.OnUndoMenu,
187 id=wxID_OBJDICTEDITEDITMENUITEMS1)
188 self.Bind(wx.EVT_MENU, self.OnRedoMenu,
189 id=wxID_OBJDICTEDITEDITMENUITEMS0)
190 self.Bind(wx.EVT_MENU, self.OnCommunicationMenu,
191 id=wxID_OBJDICTEDITEDITMENUITEMS2)
192 self.Bind(wx.EVT_MENU, self.OnRefreshMenu,
193 id=wxID_OBJDICTEDITEDITMENUITEMS4)
194 self.Bind(wx.EVT_MENU, self.OnNodeInfosMenu,
195 id=wxID_OBJDICTEDITEDITMENUITEMS6)
196 self.Bind(wx.EVT_MENU, self.OnEditProfileMenu,
197 id=wxID_OBJDICTEDITEDITMENUITEMS7)
198 self.Bind(wx.EVT_MENU, self.OnOtherCommunicationMenu,
199 id=wxID_OBJDICTEDITEDITMENUITEMS8)
201 def _init_coll_HelpMenu_Items(self, parent):
202 # generated method, don't edit
204 parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS0,
205 kind=wx.ITEM_NORMAL, text='DS-301 Standard\tF1')
206 self.Bind(wx.EVT_MENU, self.OnHelpDS301Menu,
207 id=wxID_OBJDICTEDITHELPMENUITEMS0)
208 parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS1,
209 kind=wx.ITEM_NORMAL, text='CAN Festival Docs\tF2')
210 self.Bind(wx.EVT_MENU, self.OnHelpCANFestivalMenu,
211 id=wxID_OBJDICTEDITHELPMENUITEMS1)
213 parent.Append(help='', id=wxID_OBJDICTEDITHELPMENUITEMS2,
214 kind=wx.ITEM_NORMAL, text='About')
215 self.Bind(wx.EVT_MENU, self.OnAboutMenu,
216 id=wxID_OBJDICTEDITHELPMENUITEMS2)
218 def _init_coll_FileMenu_Items(self, parent):
219 # generated method, don't edit
221 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS5,
222 kind=wx.ITEM_NORMAL, text='New\tCTRL+N')
223 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS0,
224 kind=wx.ITEM_NORMAL, text='Open\tCTRL+O')
225 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS1,
226 kind=wx.ITEM_NORMAL, text='Save\tCTRL+S')
227 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS6,
228 kind=wx.ITEM_NORMAL, text='Save As...\tALT+S')
229 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS2,
230 kind=wx.ITEM_NORMAL, text='Close\tCTRL+W')
231 parent.AppendSeparator()
232 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS7,
233 kind=wx.ITEM_NORMAL, text='Import EDS file')
234 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS9,
235 kind=wx.ITEM_NORMAL, text='Export to EDS file')
236 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS8,
237 kind=wx.ITEM_NORMAL, text='Build Dictionary\tCTRL+B')
238 parent.AppendSeparator()
239 parent.Append(help='', id=wxID_OBJDICTEDITFILEMENUITEMS4,
240 kind=wx.ITEM_NORMAL, text='Exit')
241 self.Bind(wx.EVT_MENU, self.OnOpenMenu,
242 id=wxID_OBJDICTEDITFILEMENUITEMS0)
243 self.Bind(wx.EVT_MENU, self.OnSaveMenu,
244 id=wxID_OBJDICTEDITFILEMENUITEMS1)
245 self.Bind(wx.EVT_MENU, self.OnCloseMenu,
246 id=wxID_OBJDICTEDITFILEMENUITEMS2)
247 self.Bind(wx.EVT_MENU, self.OnQuitMenu,
248 id=wxID_OBJDICTEDITFILEMENUITEMS4)
249 self.Bind(wx.EVT_MENU, self.OnNewMenu,
250 id=wxID_OBJDICTEDITFILEMENUITEMS5)
251 self.Bind(wx.EVT_MENU, self.OnSaveAsMenu,
252 id=wxID_OBJDICTEDITFILEMENUITEMS6)
253 self.Bind(wx.EVT_MENU, self.OnImportEDSMenu,
254 id=wxID_OBJDICTEDITFILEMENUITEMS7)
255 self.Bind(wx.EVT_MENU, self.OnExportCMenu,
256 id=wxID_OBJDICTEDITFILEMENUITEMS8)
257 self.Bind(wx.EVT_MENU, self.OnExportEDSMenu,
258 id=wxID_OBJDICTEDITFILEMENUITEMS9)
260 def _init_coll_AddMenu_Items(self, parent):
261 # generated method, don't edit
263 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS0,
264 kind=wx.ITEM_NORMAL, text='SDO Server')
265 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS1,
266 kind=wx.ITEM_NORMAL, text='SDO Client')
267 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS2,
268 kind=wx.ITEM_NORMAL, text='PDO Transmit')
269 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS3,
270 kind=wx.ITEM_NORMAL, text='PDO Receive')
271 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS4,
272 kind=wx.ITEM_NORMAL, text='Map Variable')
273 parent.Append(help='', id=wxID_OBJDICTEDITADDMENUITEMS5,
274 kind=wx.ITEM_NORMAL, text='User Type')
275 self.Bind(wx.EVT_MENU, self.OnAddSDOServerMenu,
276 id=wxID_OBJDICTEDITADDMENUITEMS0)
277 self.Bind(wx.EVT_MENU, self.OnAddSDOClientMenu,
278 id=wxID_OBJDICTEDITADDMENUITEMS1)
279 self.Bind(wx.EVT_MENU, self.OnAddPDOTransmitMenu,
280 id=wxID_OBJDICTEDITADDMENUITEMS2)
281 self.Bind(wx.EVT_MENU, self.OnAddPDOReceiveMenu,
282 id=wxID_OBJDICTEDITADDMENUITEMS3)
283 self.Bind(wx.EVT_MENU, self.OnAddMapVariableMenu,
284 id=wxID_OBJDICTEDITADDMENUITEMS4)
285 self.Bind(wx.EVT_MENU, self.OnAddUserTypeMenu,
286 id=wxID_OBJDICTEDITADDMENUITEMS5)
288 def _init_coll_HelpBar_Fields(self, parent):
289 # generated method, don't edit
290 parent.SetFieldsCount(3)
292 parent.SetStatusText(number=0, text='')
293 parent.SetStatusText(number=1, text='')
294 parent.SetStatusText(number=2, text='')
296 parent.SetStatusWidths([100, 110, -1])
298 def _init_utils(self):
299 # generated method, don't edit
300 self.menuBar1 = wx.MenuBar()
301 self.menuBar1.SetEvtHandlerEnabled(True)
303 self.FileMenu = wx.Menu(title='')
305 self.EditMenu = wx.Menu(title='')
307 self.AddMenu = wx.Menu(title='')
309 self.HelpMenu = wx.Menu(title='')
311 self._init_coll_menuBar1_Menus(self.menuBar1)
312 self._init_coll_FileMenu_Items(self.FileMenu)
313 self._init_coll_EditMenu_Items(self.EditMenu)
314 self._init_coll_AddMenu_Items(self.AddMenu)
315 self._init_coll_HelpMenu_Items(self.HelpMenu)
317 def _init_ctrls(self, prnt):
318 # generated method, don't edit
319 wx.Frame.__init__(self, id=wxID_OBJDICTEDIT, name='objdictedit',
320 parent=prnt, pos=wx.Point(149, 178), size=wx.Size(1000, 700),
321 style=wx.DEFAULT_FRAME_STYLE, title='Objdictedit')
323 self.SetClientSize(wx.Size(1000, 700))
324 self.SetMenuBar(self.menuBar1)
325 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_OBJDICTEDIT)
327 self.FileOpened = wx.Notebook(id=wxID_OBJDICTEDITFILEOPENED,
328 name='FileOpened', parent=self, pos=wx.Point(0, 0),
329 size=wx.Size(0, 0), style=0)
330 self.FileOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
331 self.OnFileSelectedChanged, id=wxID_OBJDICTEDITFILEOPENED)
333 self.HelpBar = wx.StatusBar(id=wxID_OBJDICTEDITHELPBAR, name='HelpBar',
334 parent=self, style=wxST_SIZEGRIP)
335 self._init_coll_HelpBar_Fields(self.HelpBar)
336 self.SetStatusBar(self.HelpBar)
338 def __init__(self, parent):
339 self._init_ctrls(parent)
340 self.HtmlFrameOpened = []
343 self.Manager = NodeManager(ScriptDirectory)
344 for filepath in filesOpen:
345 result = self.Manager.OpenFileInCurrent(filepath)
346 if type(result) == IntType:
347 new_editingpanel = EditingPanel(self, self.Manager)
348 new_editingpanel.SetIndex(result)
349 self.FileOpened.AddPage(new_editingpanel, "")
350 window = self.FileOpened.GetPage(0)
352 self.Manager.ChangeCurrentNode(window.GetIndex())
353 self.FileOpened.SetSelection(0)
354 if self.Manager.CurrentDS302Defined():
355 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
357 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
358 self.RefreshEditMenu()
359 self.RefreshBufferState()
360 self.RefreshProfileMenu()
362 self.RefreshMainMenu()
364 def GetNoteBook(self):
365 return self.FileOpened
367 def OnAddSDOServerMenu(self, event):
368 self.Manager.AddSDOServerToCurrent()
369 self.RefreshBufferState()
370 self.RefreshCurrentIndexList()
373 def OnAddSDOClientMenu(self, event):
374 self.Manager.AddSDOClientToCurrent()
375 self.RefreshBufferState()
376 self.RefreshCurrentIndexList()
379 def OnAddPDOTransmitMenu(self, event):
380 self.Manager.AddPDOTransmitToCurrent()
381 self.RefreshBufferState()
382 self.RefreshCurrentIndexList()
385 def OnAddPDOReceiveMenu(self, event):
386 self.Manager.AddPDOReceiveToCurrent()
387 self.RefreshBufferState()
388 self.RefreshCurrentIndexList()
391 def OnAddMapVariableMenu(self, event):
392 self.AddMapVariable()
395 def OnAddUserTypeMenu(self, event):
399 def OnFileSelectedChanged(self, event):
400 selected = event.GetSelection()
401 # At init selected = -1
403 window = self.FileOpened.GetPage(selected)
405 self.Manager.ChangeCurrentNode(window.GetIndex())
406 self.RefreshBufferState()
407 self.RefreshStatusBar()
408 self.RefreshProfileMenu()
411 def OnHelpDS301Menu(self, event):
413 selected = self.FileOpened.GetSelection()
415 window = self.FileOpened.GetPage(selected)
416 result = window.GetSelection()
419 index, subIndex = result
420 result = OpenPDFDocIndex(index, ScriptDirectory)
421 if type(result) == StringType:
422 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
426 result = OpenPDFDocIndex(None, ScriptDirectory)
427 if type(result) == StringType:
428 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
433 def OnHelpCANFestivalMenu(self, event):
434 #self.OpenHtmlFrame("CAN Festival Reference", os.path.join(ScriptDirectory, "doc/canfestival.html"), wx.Size(1000, 600))
435 os.system("xpdf -remote CANFESTIVAL %s %d &"%(os.path.join(ScriptDirectory, "doc/manual_en.pdf"),16))
438 def OnAboutMenu(self, event):
439 self.OpenHtmlFrame("About CAN Festival", os.path.join(ScriptDirectory, "doc/about.html"), wx.Size(500, 450))
442 def OpenHtmlFrame(self, title, file, size):
443 if title not in self.HtmlFrameOpened:
444 self.HtmlFrameOpened.append(title)
445 window = HtmlFrame(self, self.HtmlFrameOpened)
446 window.SetTitle(title)
447 window.SetHtmlPage(file)
448 window.SetClientSize(size)
451 def OnQuitMenu(self, event):
455 def OnCloseFrame(self, event):
456 if self.Manager.OneFileHasChanged():
457 dialog = wxMessageDialog(self, "There are changes, do you want to save?", "Close Application", wxYES_NO|wxCANCEL|wxICON_QUESTION)
458 answer = dialog.ShowModal()
460 if answer == wxID_YES:
461 self.Manager.ChangeCurrentNode(0)
462 for i in xrange(self.FileOpened.GetPageCount()):
463 window = self.FileOpened.GetPage(i)
464 self.Manager.ChangeCurrentNode(window.GetIndex())
465 if self.Manager.CurrentIsSaved():
466 self.Manager.CloseCurrent()
469 self.Manager.CloseCurrent(True)
471 elif answer == wxID_NO:
472 for i in xrange(self.FileOpened.GetPageCount()):
473 self.Manager.CloseCurrent(True)
474 wxCallAfter(self.Close)
479 #-------------------------------------------------------------------------------
481 #-------------------------------------------------------------------------------
483 def RefreshTitle(self):
484 if self.FileOpened.GetPageCount() > 0:
485 self.SetTitle("Objdictedit - %s"%self.Manager.GetCurrentFilename())
487 self.SetTitle("Objdictedit")
489 def OnRefreshMenu(self, event):
490 self.RefreshCurrentIndexList()
493 def RefreshCurrentIndexList(self):
494 selected = self.FileOpened.GetSelection()
495 window = self.FileOpened.GetPage(selected)
496 window.RefreshIndexList()
498 def RefreshStatusBar(self):
500 selected = self.FileOpened.GetSelection()
502 window = self.FileOpened.GetPage(selected)
503 selection = window.GetSelection()
505 index, subIndex = selection
506 if self.Manager.IsCurrentEntry(index):
507 self.HelpBar.SetStatusText("Index: 0x%04X"%index, 0)
508 self.HelpBar.SetStatusText("Subindex: 0x%02X"%subIndex, 1)
509 entryinfos = self.Manager.GetEntryInfos(index)
510 name = entryinfos["name"]
511 category = "Optional"
512 if entryinfos["need"]:
513 category = "Mandatory"
516 if entryinfos["struct"] & OD_IdenticalIndexes:
517 number = " possibly defined %d times"%entryinfos["nbmax"]
518 if entryinfos["struct"] & OD_IdenticalSubindexes:
520 elif entryinfos["struct"] & OD_MultipleSubindexes:
522 text = "%s: %s entry of struct %s%s."%(name,category,struct,number)
523 self.HelpBar.SetStatusText(text, 2)
526 self.HelpBar.SetStatusText("", i)
529 self.HelpBar.SetStatusText("", i)
531 def RefreshMainMenu(self):
533 if self.FileOpened.GetPageCount() > 0:
534 self.menuBar1.EnableTop(1, True)
535 self.menuBar1.EnableTop(2, True)
536 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, True)
537 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, True)
538 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, True)
539 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, True)
540 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS9, True)
542 self.menuBar1.EnableTop(1, False)
543 self.menuBar1.EnableTop(2, False)
544 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS1, False)
545 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS2, False)
546 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS6, False)
547 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS8, False)
548 self.FileMenu.Enable(wxID_OBJDICTEDITFILEMENUITEMS9, False)
550 def RefreshEditMenu(self):
552 if self.FileOpened.GetPageCount() > 0:
553 undo, redo = self.Manager.GetCurrentBufferState()
554 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS1, undo)
555 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS0, redo)
557 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS1, False)
558 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS0, False)
560 def RefreshProfileMenu(self):
562 profile = self.Manager.GetCurrentProfileName()
563 edititem = self.EditMenu.FindItemById(wxID_OBJDICTEDITEDITMENUITEMS7)
565 length = self.AddMenu.GetMenuItemCount()
566 for i in xrange(length-6):
567 additem = self.AddMenu.FindItemByPosition(6)
568 self.AddMenu.Delete(additem.GetId())
569 if profile not in ("None", "DS-301"):
570 edititem.SetText("%s Profile"%profile)
571 edititem.Enable(True)
572 self.AddMenu.AppendSeparator()
573 for text, indexes in self.Manager.GetCurrentSpecificMenu():
575 self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
576 self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
578 edititem.SetText("Other Profile")
579 edititem.Enable(False)
582 #-------------------------------------------------------------------------------
584 #-------------------------------------------------------------------------------
586 def RefreshBufferState(self):
587 fileopened = self.Manager.GetAllFilenames()
588 for idx, filename in enumerate(fileopened):
589 self.FileOpened.SetPageText(idx, filename)
590 self.RefreshEditMenu()
593 def OnUndoMenu(self, event):
594 self.Manager.LoadCurrentPrevious()
595 self.RefreshCurrentIndexList()
596 self.RefreshBufferState()
599 def OnRedoMenu(self, event):
600 self.Manager.LoadCurrentNext()
601 self.RefreshCurrentIndexList()
602 self.RefreshBufferState()
606 #-------------------------------------------------------------------------------
607 # Load and Save Funtions
608 #-------------------------------------------------------------------------------
610 def OnNewMenu(self, event):
612 dialog = CreateNodeDialog(self, ScriptDirectory)
613 if dialog.ShowModal() == wxID_OK:
614 name, id, nodetype, description = dialog.GetValues()
615 profile, filepath = dialog.GetProfile()
616 NMT = dialog.GetNMTManagement()
617 options = dialog.GetOptions()
618 result = self.Manager.CreateNewNode(name, id, nodetype, description, profile, filepath, NMT, options)
619 if type(result) == IntType:
620 new_editingpanel = EditingPanel(self, self.Manager)
621 new_editingpanel.SetIndex(result)
622 self.FileOpened.AddPage(new_editingpanel, "")
623 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
624 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
625 if "DS302" in options:
626 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
627 self.RefreshBufferState()
628 self.RefreshProfileMenu()
629 self.RefreshMainMenu()
631 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
636 def OnOpenMenu(self, event):
637 filepath = self.Manager.GetCurrentFilePath()
639 directory = os.path.dirname(filepath)
641 directory = os.getcwd()
642 dialog = wxFileDialog(self, "Choose a file", directory, "", "OD files (*.od)|*.od|All files|*.*", wxOPEN|wxCHANGE_DIR)
643 if dialog.ShowModal() == wxID_OK:
644 filepath = dialog.GetPath()
645 if os.path.isfile(filepath):
646 result = self.Manager.OpenFileInCurrent(filepath)
647 if type(result) == IntType:
648 new_editingpanel = EditingPanel(self, self.Manager)
649 new_editingpanel.SetIndex(result)
650 self.FileOpened.AddPage(new_editingpanel, "")
651 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
652 if self.Manager.CurrentDS302Defined():
653 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, True)
655 self.EditMenu.Enable(wxID_OBJDICTEDITEDITMENUITEMS8, False)
656 self.RefreshEditMenu()
657 self.RefreshBufferState()
658 self.RefreshProfileMenu()
659 self.RefreshMainMenu()
661 message = wxMessageDialog(self, e.args[0], "Error", wxOK|wxICON_ERROR)
667 def OnSaveMenu(self, event):
671 def OnSaveAsMenu(self, event):
676 result = self.Manager.SaveCurrentInFile()
679 elif type(result) != StringType:
680 self.RefreshBufferState()
682 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
687 filepath = self.Manager.GetCurrentFilePath()
689 directory, filename = os.path.split(filepath)
691 directory, filename = os.getcwd(), "%s.od"%self.Manager.GetCurrentNodeInfos()[0]
692 dialog = wxFileDialog(self, "Choose a file", directory, filename, "OD files (*.od)|*.od|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT|wxCHANGE_DIR)
693 if dialog.ShowModal() == wxID_OK:
694 filepath = dialog.GetPath()
695 if os.path.isdir(os.path.dirname(filepath)):
696 result = self.Manager.SaveCurrentInFile(filepath)
697 if type(result) != StringType:
698 self.RefreshBufferState()
700 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
704 message = wxMessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
709 def OnCloseMenu(self, event):
711 result = self.Manager.CloseCurrent()
713 dialog = wxMessageDialog(self, "There are changes, do you want to save?", "Close File", wxYES_NO|wxCANCEL|wxICON_QUESTION)
714 answer = dialog.ShowModal()
716 if answer == wxID_YES:
717 self.OnSaveMenu(event)
718 if self.Manager.CurrentIsSaved():
719 self.Manager.CloseCurrent()
720 elif answer == wxID_NO:
721 self.Manager.CloseCurrent(True)
722 if self.FileOpened.GetPageCount() > self.Manager.GetBufferNumber():
723 current = self.FileOpened.GetSelection()
724 self.FileOpened.DeletePage(current)
725 if self.FileOpened.GetPageCount() > 0:
726 self.FileOpened.SetSelection(min(current, self.FileOpened.GetPageCount() - 1))
727 self.RefreshBufferState()
728 self.RefreshMainMenu()
732 #-------------------------------------------------------------------------------
733 # Import and Export Functions
734 #-------------------------------------------------------------------------------
736 def OnImportEDSMenu(self, event):
737 dialog = wxFileDialog(self, "Choose a file", os.getcwd(), "", "EDS files (*.eds)|*.eds|All files|*.*", wxOPEN|wxCHANGE_DIR)
738 if dialog.ShowModal() == wxID_OK:
739 filepath = dialog.GetPath()
740 if os.path.isfile(filepath):
741 result = self.Manager.ImportCurrentFromEDSFile(filepath)
742 if type(result) == IntType:
743 new_editingpanel = EditingPanel(self, self.Manager)
744 new_editingpanel.SetIndex(result)
745 self.FileOpened.AddPage(new_editingpanel, "")
746 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
747 self.RefreshBufferState()
748 self.RefreshCurrentIndexList()
749 self.RefreshProfileMenu()
750 self.RefreshMainMenu()
751 message = wxMessageDialog(self, "Import successful", "Information", wxOK|wxICON_INFORMATION)
755 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
759 message = wxMessageDialog(self, "\"%s\" is not a valid file!"%filepath, "Error", wxOK|wxICON_ERROR)
766 def OnExportEDSMenu(self, event):
767 dialog = wxFileDialog(self, "Choose a file", os.getcwd(), self.Manager.GetCurrentNodeInfos()[0], "EDS files (*.eds)|*.eds|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT|wxCHANGE_DIR)
768 if dialog.ShowModal() == wxID_OK:
769 filepath = dialog.GetPath()
770 if os.path.isdir(os.path.dirname(filepath)):
771 path, extend = os.path.splitext(filepath)
772 if extend in ("", "."):
773 filepath = path + ".eds"
774 result = self.Manager.ExportCurrentToEDSFile(filepath)
776 message = wxMessageDialog(self, "Export successful", "Information", wxOK|wxICON_INFORMATION)
780 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
784 message = wxMessageDialog(self, "\"%s\" is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
790 def OnExportCMenu(self, event):
791 dialog = wxFileDialog(self, "Choose a file", os.getcwd(), self.Manager.GetCurrentNodeInfos()[0], "CANFestival C files (*.c)|*.c|All files|*.*", wxSAVE|wxOVERWRITE_PROMPT|wxCHANGE_DIR)
792 if dialog.ShowModal() == wxID_OK:
793 filepath = dialog.GetPath()
794 if os.path.isdir(os.path.dirname(filepath)):
795 path, extend = os.path.splitext(filepath)
796 if extend in ("", "."):
797 filepath = path + ".c"
798 result = self.Manager.ExportCurrentToCFile(filepath)
800 message = wxMessageDialog(self, "Export successful", "Information", wxOK|wxICON_INFORMATION)
804 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
808 message = wxMessageDialog(self, "\"%s\" is not a valid folder!"%os.path.dirname(filepath), "Error", wxOK|wxICON_ERROR)
814 #-------------------------------------------------------------------------------
815 # Editing Profiles functions
816 #-------------------------------------------------------------------------------
818 def OnCommunicationMenu(self, event):
819 dictionary,current = self.Manager.GetCurrentCommunicationLists()
820 self.EditProfile("Edit DS-301 Profile", dictionary, current)
823 def OnOtherCommunicationMenu(self, event):
824 dictionary,current = self.Manager.GetCurrentDS302Lists()
825 self.EditProfile("Edit DS-301 Profile", dictionary, current)
828 def OnEditProfileMenu(self, event):
829 title = "Edit %s Profile"%self.Manager.GetCurrentProfileName()
830 dictionary,current = self.Manager.GetCurrentProfileLists()
831 self.EditProfile(title, dictionary, current)
834 def EditProfile(self, title, dictionary, current):
835 dialog = CommunicationDialog(self)
836 dialog.SetTitle(title)
837 dialog.SetIndexDictionary(dictionary)
838 dialog.SetCurrentList(current)
839 dialog.RefreshLists()
840 if dialog.ShowModal() == wxID_OK:
841 new_profile = dialog.GetCurrentList()
844 for index in new_profile:
845 if index not in current:
846 addinglist.append(index)
847 for index in current:
848 if index not in new_profile:
849 removinglist.append(index)
850 self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
851 self.Manager.BufferCurrentNode()
852 self.RefreshBufferState()
853 self.RefreshCurrentIndexList()
856 def GetProfileCallBack(self, text):
857 def ProfileCallBack(event):
858 self.Manager.AddSpecificEntryToCurrent(text)
859 self.RefreshBufferState()
860 self.RefreshCurrentIndexList()
862 return ProfileCallBack
864 #-------------------------------------------------------------------------------
865 # Edit Node informations function
866 #-------------------------------------------------------------------------------
868 def OnNodeInfosMenu(self, event):
869 dialog = NodeInfosDialog(self)
870 name, id, type, description = self.Manager.GetCurrentNodeInfos()
871 dialog.SetValues(name, id, type, description)
872 if dialog.ShowModal() == wxID_OK:
873 name, id, type, description = dialog.GetValues()
874 self.Manager.SetCurrentNodeInfos(name, id, type, description)
875 self.RefreshBufferState()
876 self.RefreshProfileMenu()
877 selected = self.FileOpened.GetSelection()
879 window = self.FileOpened.GetPage(selected)
880 window.RefreshTable()
884 #-------------------------------------------------------------------------------
885 # Add User Types and Variables
886 #-------------------------------------------------------------------------------
888 def AddMapVariable(self):
889 index = self.Manager.GetCurrentNextMapIndex()
891 dialog = MapVariableDialog(self)
892 dialog.SetIndex(index)
893 if dialog.ShowModal() == wxID_OK:
894 index, name, struct, number = dialog.GetValues()
895 result = self.Manager.AddMapVariableToCurrent(index, name, struct, number)
896 if type(result) != StringType:
897 self.RefreshBufferState()
898 self.RefreshCurrentIndexList()
900 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
905 message = wxMessageDialog(self, result, "No map variable index left!", wxOK|wxICON_ERROR)
909 def AddUserType(self):
910 dialog = UserTypeDialog(self)
911 dialog.SetTypeList(self.Manager.GetCustomisableTypes())
912 if dialog.ShowModal() == wxID_OK:
913 type, min, max, length = dialog.GetValues()
914 result = self.Manager.AddUserTypeToCurrent(type, min, max, length)
916 self.RefreshBufferState()
917 self.RefreshCurrentIndexList()
919 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
925 #-------------------------------------------------------------------------------
927 #-------------------------------------------------------------------------------
929 Max_Traceback_List_Size = 20
931 def Display_Exception_Dialog(e_type,e_value,e_tb):
933 for i,line in enumerate(traceback.extract_tb(e_tb)):
934 trcbck = " " + str(i+1) + ". "
935 if line[0].find(os.getcwd()) == -1:
936 trcbck += "file : " + str(line[0]) + ", "
938 trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ", "
939 trcbck += "line : " + str(line[1]) + ", " + "function : " + str(line[2])
940 trcbck_lst.append(trcbck)
943 cap = wx.Window_GetCapture()
947 dlg = wx.SingleChoiceDialog(None,
951 Click on OK for saving an error report.
953 Please contact LOLITech at:
955 bugs_objdictedit@lolitech.fr
960 str(e_type) + " : " + str(e_value),
964 res = (dlg.ShowModal() == wx.ID_OK)
970 def Display_Error_Dialog(e_value):
971 message = wxMessageDialog(None, str(e_value), "Error", wxOK|wxICON_ERROR)
975 def get_last_traceback(tb):
981 def format_namespace(d, indent=' '):
982 return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
985 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
987 def wxAddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
989 def handle_exception(e_type, e_value, e_traceback):
990 traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
991 last_tb = get_last_traceback(e_traceback)
992 ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
993 if str(e_value).startswith("!!!"):
994 Display_Error_Dialog(e_value)
995 elif ex not in ignored_exceptions:
996 ignored_exceptions.append(ex)
997 result = Display_Exception_Dialog(e_type,e_value,e_traceback)
1000 'app-title' : wx.GetApp().GetAppName(), # app_title
1001 'app-version' : app_version,
1002 'wx-version' : wx.VERSION_STRING,
1003 'wx-platform' : wx.Platform,
1004 'python-version' : platform.python_version(), #sys.version.split()[0],
1005 'platform' : platform.platform(),
1007 'e-value' : e_value,
1008 'date' : time.ctime(),
1009 'cwd' : os.getcwd(),
1012 info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
1013 last_tb = get_last_traceback(e_traceback)
1014 exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
1015 info['locals'] = format_namespace(exception_locals)
1016 if 'self' in exception_locals:
1017 info['self'] = format_namespace(exception_locals['self'].__dict__)
1019 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
1023 output.write(a+":\n"+str(info[a])+"\n\n")
1025 #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
1026 sys.excepthook = handle_exception
1028 if __name__ == '__main__':
1029 app = wxPySimpleApp()
1030 wxInitAllImageHandlers()
1032 # Install a exception handle for bug reports
1033 wxAddExceptHook(os.getcwd(),__version__)
1035 frame = objdictedit(None)