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
27 import os, re, platform, sys, time, traceback, getopt
29 __version__ = "$Revision: 1.26 $"
31 from node import OD_Subindex, OD_MultipleSubindexes, OD_IdenticalSubindexes, OD_IdenticalIndexes
33 from nodemanager import *
34 from subindextable import *
35 from commondialogs import *
36 from doc_index.DS301_index import *
41 EVT_HTML_URL_CLICK = wx.NewId()
43 class HtmlWindowUrlClick(wx.PyEvent):
44 def __init__(self, linkinfo):
45 wx.PyEvent.__init__(self)
46 self.SetEventType(EVT_HTML_URL_CLICK)
47 self.linkinfo = (linkinfo.GetHref(), linkinfo.GetTarget())
49 class UrlClickHtmlWindow(wx.html.HtmlWindow):
50 """ HTML window that generates and OnLinkClicked event.
52 Use this to avoid having to override HTMLWindow
54 def OnLinkClicked(self, linkinfo):
55 wx.PostEvent(self, HtmlWindowUrlClick(linkinfo))
57 def Bind(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY):
58 if event == HtmlWindowUrlClick:
59 self.Connect(-1, -1, EVT_HTML_URL_CLICK, handler)
61 wx.html.HtmlWindow.Bind(event, handler, source=source, id=id, id2=id2)
63 #-------------------------------------------------------------------------------
65 #-------------------------------------------------------------------------------
67 [ID_HTMLFRAME, ID_HTMLFRAMEHTMLCONTENT] = [wx.NewId() for _init_ctrls in range(2)]
69 class HtmlFrame(wx.Frame):
70 def _init_ctrls(self, prnt):
71 wx.Frame.__init__(self, id=ID_HTMLFRAME, name='HtmlFrame',
72 parent=prnt, pos=wx.Point(320, 231), size=wx.Size(853, 616),
73 style=wx.DEFAULT_FRAME_STYLE, title='')
74 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=ID_HTMLFRAME)
76 self.HtmlContent = UrlClickHtmlWindow(id=ID_HTMLFRAMEHTMLCONTENT,
77 name='HtmlContent', parent=self, pos=wx.Point(0, 0),
78 size=wx.Size(-1, -1), style=wx.html.HW_SCROLLBAR_AUTO|wx.html.HW_NO_SELECTION)
79 self.HtmlContent.Bind(HtmlWindowUrlClick, self.OnLinkClick)
81 def __init__(self, parent, opened):
82 self._init_ctrls(parent)
83 self.HtmlFrameOpened = opened
85 def SetHtmlCode(self, htmlcode):
86 self.HtmlContent.SetPage(htmlcode)
88 def SetHtmlPage(self, htmlpage):
89 self.HtmlContent.LoadPage(htmlpage)
91 def OnCloseFrame(self, event):
92 self.HtmlFrameOpened.remove(self.GetTitle())
95 def OnLinkClick(self, event):
96 url = event.linkinfo[0]
100 wx.MessageBox('Please point your browser at: %s' % url)
109 return objdictedit(parent)
112 print "\nUsage of objdictedit.py :"
113 print "\n %s [Filepath, ...]\n"%sys.argv[0]
116 opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
117 except getopt.GetoptError:
118 # print help information and exit:
123 if o in ("-h", "--help"):
128 ScriptDirectory = sys.path[0]
131 [ID_OBJDICTEDIT, ID_OBJDICTEDITFILEOPENED,
132 ID_OBJDICTEDITHELPBAR,
133 ] = [wx.NewId() for _init_ctrls in range(3)]
135 [ID_OBJDICTEDITADDMENUITEMS0, ID_OBJDICTEDITADDMENUITEMS1,
136 ID_OBJDICTEDITADDMENUITEMS2, ID_OBJDICTEDITADDMENUITEMS3,
137 ID_OBJDICTEDITADDMENUITEMS4, ID_OBJDICTEDITADDMENUITEMS5,
138 ] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
140 [ID_OBJDICTEDITFILEMENUITEMS0, ID_OBJDICTEDITFILEMENUITEMS1,
141 ID_OBJDICTEDITFILEMENUITEMS2, ID_OBJDICTEDITFILEMENUITEMS4,
142 ID_OBJDICTEDITFILEMENUITEMS5, ID_OBJDICTEDITFILEMENUITEMS6,
143 ID_OBJDICTEDITFILEMENUITEMS7, ID_OBJDICTEDITFILEMENUITEMS8,
144 ID_OBJDICTEDITFILEMENUITEMS9,
145 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(9)]
147 [ID_OBJDICTEDITEDITMENUITEMS0, ID_OBJDICTEDITEDITMENUITEMS1,
148 ID_OBJDICTEDITEDITMENUITEMS2, ID_OBJDICTEDITEDITMENUITEMS4,
149 ID_OBJDICTEDITEDITMENUITEMS6, ID_OBJDICTEDITEDITMENUITEMS7,
150 ID_OBJDICTEDITEDITMENUITEMS8,
151 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(7)]
153 [ID_OBJDICTEDITHELPMENUITEMS0, ID_OBJDICTEDITHELPMENUITEMS1,
154 ID_OBJDICTEDITHELPMENUITEMS2,
155 ] = [wx.NewId() for _init_coll_HelpMenu_Items in range(3)]
157 class objdictedit(wx.Frame):
158 def _init_coll_menuBar1_Menus(self, parent):
159 parent.Append(menu=self.FileMenu, title='File')
160 parent.Append(menu=self.EditMenu, title='Edit')
161 parent.Append(menu=self.AddMenu, title='Add')
162 parent.Append(menu=self.HelpMenu, title='Help')
164 def _init_coll_EditMenu_Items(self, parent):
165 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS4,
166 kind=wx.ITEM_NORMAL, text='Refresh\tCTRL+R')
167 parent.AppendSeparator()
168 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS1,
169 kind=wx.ITEM_NORMAL, text='Undo\tCTRL+Z')
170 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS0,
171 kind=wx.ITEM_NORMAL, text='Redo\tCTRL+Y')
172 parent.AppendSeparator()
173 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS6,
174 kind=wx.ITEM_NORMAL, text='Node infos')
175 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS2,
176 kind=wx.ITEM_NORMAL, text='DS-301 Profile')
177 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS8,
178 kind=wx.ITEM_NORMAL, text='DS-302 Profile')
179 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS7,
180 kind=wx.ITEM_NORMAL, text='Other Profile')
181 self.Bind(wx.EVT_MENU, self.OnUndoMenu,
182 id=ID_OBJDICTEDITEDITMENUITEMS1)
183 self.Bind(wx.EVT_MENU, self.OnRedoMenu,
184 id=ID_OBJDICTEDITEDITMENUITEMS0)
185 self.Bind(wx.EVT_MENU, self.OnCommunicationMenu,
186 id=ID_OBJDICTEDITEDITMENUITEMS2)
187 self.Bind(wx.EVT_MENU, self.OnRefreshMenu,
188 id=ID_OBJDICTEDITEDITMENUITEMS4)
189 self.Bind(wx.EVT_MENU, self.OnNodeInfosMenu,
190 id=ID_OBJDICTEDITEDITMENUITEMS6)
191 self.Bind(wx.EVT_MENU, self.OnEditProfileMenu,
192 id=ID_OBJDICTEDITEDITMENUITEMS7)
193 self.Bind(wx.EVT_MENU, self.OnOtherCommunicationMenu,
194 id=ID_OBJDICTEDITEDITMENUITEMS8)
196 def _init_coll_HelpMenu_Items(self, parent):
197 parent.Append(help='', id=ID_OBJDICTEDITHELPMENUITEMS0,
198 kind=wx.ITEM_NORMAL, text='DS-301 Standard\tF1')
199 self.Bind(wx.EVT_MENU, self.OnHelpDS301Menu,
200 id=ID_OBJDICTEDITHELPMENUITEMS0)
201 parent.Append(help='', id=ID_OBJDICTEDITHELPMENUITEMS1,
202 kind=wx.ITEM_NORMAL, text='CAN Festival Docs\tF2')
203 self.Bind(wx.EVT_MENU, self.OnHelpCANFestivalMenu,
204 id=ID_OBJDICTEDITHELPMENUITEMS1)
206 parent.Append(help='', id=ID_OBJDICTEDITHELPMENUITEMS2,
207 kind=wx.ITEM_NORMAL, text='About')
208 self.Bind(wx.EVT_MENU, self.OnAboutMenu,
209 id=ID_OBJDICTEDITHELPMENUITEMS2)
211 def _init_coll_FileMenu_Items(self, parent):
212 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS5,
213 kind=wx.ITEM_NORMAL, text='New\tCTRL+N')
214 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS0,
215 kind=wx.ITEM_NORMAL, text='Open\tCTRL+O')
216 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS1,
217 kind=wx.ITEM_NORMAL, text='Save\tCTRL+S')
218 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS6,
219 kind=wx.ITEM_NORMAL, text='Save As...\tALT+S')
220 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS2,
221 kind=wx.ITEM_NORMAL, text='Close\tCTRL+W')
222 parent.AppendSeparator()
223 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS7,
224 kind=wx.ITEM_NORMAL, text='Import EDS file')
225 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS9,
226 kind=wx.ITEM_NORMAL, text='Export to EDS file')
227 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS8,
228 kind=wx.ITEM_NORMAL, text='Build Dictionary\tCTRL+B')
229 parent.AppendSeparator()
230 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS4,
231 kind=wx.ITEM_NORMAL, text='Exit')
232 self.Bind(wx.EVT_MENU, self.OnOpenMenu,
233 id=ID_OBJDICTEDITFILEMENUITEMS0)
234 self.Bind(wx.EVT_MENU, self.OnSaveMenu,
235 id=ID_OBJDICTEDITFILEMENUITEMS1)
236 self.Bind(wx.EVT_MENU, self.OnCloseMenu,
237 id=ID_OBJDICTEDITFILEMENUITEMS2)
238 self.Bind(wx.EVT_MENU, self.OnQuitMenu,
239 id=ID_OBJDICTEDITFILEMENUITEMS4)
240 self.Bind(wx.EVT_MENU, self.OnNewMenu,
241 id=ID_OBJDICTEDITFILEMENUITEMS5)
242 self.Bind(wx.EVT_MENU, self.OnSaveAsMenu,
243 id=ID_OBJDICTEDITFILEMENUITEMS6)
244 self.Bind(wx.EVT_MENU, self.OnImportEDSMenu,
245 id=ID_OBJDICTEDITFILEMENUITEMS7)
246 self.Bind(wx.EVT_MENU, self.OnExportCMenu,
247 id=ID_OBJDICTEDITFILEMENUITEMS8)
248 self.Bind(wx.EVT_MENU, self.OnExportEDSMenu,
249 id=ID_OBJDICTEDITFILEMENUITEMS9)
251 def _init_coll_AddMenu_Items(self, parent):
252 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS0,
253 kind=wx.ITEM_NORMAL, text='SDO Server')
254 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS1,
255 kind=wx.ITEM_NORMAL, text='SDO Client')
256 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS2,
257 kind=wx.ITEM_NORMAL, text='PDO Transmit')
258 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS3,
259 kind=wx.ITEM_NORMAL, text='PDO Receive')
260 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS4,
261 kind=wx.ITEM_NORMAL, text='Map Variable')
262 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS5,
263 kind=wx.ITEM_NORMAL, text='User Type')
264 self.Bind(wx.EVT_MENU, self.OnAddSDOServerMenu,
265 id=ID_OBJDICTEDITADDMENUITEMS0)
266 self.Bind(wx.EVT_MENU, self.OnAddSDOClientMenu,
267 id=ID_OBJDICTEDITADDMENUITEMS1)
268 self.Bind(wx.EVT_MENU, self.OnAddPDOTransmitMenu,
269 id=ID_OBJDICTEDITADDMENUITEMS2)
270 self.Bind(wx.EVT_MENU, self.OnAddPDOReceiveMenu,
271 id=ID_OBJDICTEDITADDMENUITEMS3)
272 self.Bind(wx.EVT_MENU, self.OnAddMapVariableMenu,
273 id=ID_OBJDICTEDITADDMENUITEMS4)
274 self.Bind(wx.EVT_MENU, self.OnAddUserTypeMenu,
275 id=ID_OBJDICTEDITADDMENUITEMS5)
277 def _init_coll_HelpBar_Fields(self, parent):
278 parent.SetFieldsCount(3)
280 parent.SetStatusText(number=0, text='')
281 parent.SetStatusText(number=1, text='')
282 parent.SetStatusText(number=2, text='')
284 parent.SetStatusWidths([100, 110, -1])
286 def _init_utils(self):
287 self.menuBar1 = wx.MenuBar()
288 self.menuBar1.SetEvtHandlerEnabled(True)
290 self.FileMenu = wx.Menu(title='')
291 self.EditMenu = wx.Menu(title='')
292 self.AddMenu = wx.Menu(title='')
293 self.HelpMenu = wx.Menu(title='')
295 self._init_coll_menuBar1_Menus(self.menuBar1)
296 self._init_coll_FileMenu_Items(self.FileMenu)
297 self._init_coll_EditMenu_Items(self.EditMenu)
298 self._init_coll_AddMenu_Items(self.AddMenu)
299 self._init_coll_HelpMenu_Items(self.HelpMenu)
301 def _init_ctrls(self, prnt):
302 wx.Frame.__init__(self, id=ID_OBJDICTEDIT, name='objdictedit',
303 parent=prnt, pos=wx.Point(149, 178), size=wx.Size(1000, 700),
304 style=wx.DEFAULT_FRAME_STYLE, title='Objdictedit')
306 self.SetClientSize(wx.Size(1000, 700))
307 self.SetMenuBar(self.menuBar1)
308 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=ID_OBJDICTEDIT)
310 self.FileOpened = wx.Notebook(id=ID_OBJDICTEDITFILEOPENED,
311 name='FileOpened', parent=self, pos=wx.Point(0, 0),
312 size=wx.Size(0, 0), style=0)
313 self.FileOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
314 self.OnFileSelectedChanged, id=ID_OBJDICTEDITFILEOPENED)
316 self.HelpBar = wx.StatusBar(id=ID_OBJDICTEDITHELPBAR, name='HelpBar',
317 parent=self, style=wx.ST_SIZEGRIP)
318 self._init_coll_HelpBar_Fields(self.HelpBar)
319 self.SetStatusBar(self.HelpBar)
321 def __init__(self, parent):
322 self._init_ctrls(parent)
323 self.HtmlFrameOpened = []
326 self.Manager = NodeManager(ScriptDirectory)
327 for filepath in filesOpen:
328 result = self.Manager.OpenFileInCurrent(filepath)
329 if type(result) == IntType:
330 new_editingpanel = EditingPanel(self, self.Manager)
331 new_editingpanel.SetIndex(result)
332 self.FileOpened.AddPage(new_editingpanel, "")
333 window = self.FileOpened.GetPage(0)
335 self.Manager.ChangeCurrentNode(window.GetIndex())
336 self.FileOpened.SetSelection(0)
337 if self.Manager.CurrentDS302Defined():
338 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, True)
340 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, False)
341 self.RefreshEditMenu()
342 self.RefreshBufferState()
343 self.RefreshProfileMenu()
345 self.RefreshMainMenu()
347 def GetNoteBook(self):
348 return self.FileOpened
350 def OnAddSDOServerMenu(self, event):
351 self.Manager.AddSDOServerToCurrent()
352 self.RefreshBufferState()
353 self.RefreshCurrentIndexList()
356 def OnAddSDOClientMenu(self, event):
357 self.Manager.AddSDOClientToCurrent()
358 self.RefreshBufferState()
359 self.RefreshCurrentIndexList()
362 def OnAddPDOTransmitMenu(self, event):
363 self.Manager.AddPDOTransmitToCurrent()
364 self.RefreshBufferState()
365 self.RefreshCurrentIndexList()
368 def OnAddPDOReceiveMenu(self, event):
369 self.Manager.AddPDOReceiveToCurrent()
370 self.RefreshBufferState()
371 self.RefreshCurrentIndexList()
374 def OnAddMapVariableMenu(self, event):
375 self.AddMapVariable()
378 def OnAddUserTypeMenu(self, event):
382 def OnFileSelectedChanged(self, event):
383 selected = event.GetSelection()
384 # At init selected = -1
386 window = self.FileOpened.GetPage(selected)
388 self.Manager.ChangeCurrentNode(window.GetIndex())
389 self.RefreshBufferState()
390 self.RefreshStatusBar()
391 self.RefreshProfileMenu()
394 def OnHelpDS301Menu(self, event):
396 selected = self.FileOpened.GetSelection()
398 window = self.FileOpened.GetPage(selected)
399 result = window.GetSelection()
402 index, subIndex = result
403 result = OpenPDFDocIndex(index, ScriptDirectory)
404 if type(result) == StringType:
405 message = wx.MessageDialog(self, result, "ERROR", wx.OK|wx.ICON_ERROR)
409 result = OpenPDFDocIndex(None, ScriptDirectory)
410 if type(result) == StringType:
411 message = wx.MessageDialog(self, result, "ERROR", wx.OK|wx.ICON_ERROR)
416 def OnHelpCANFestivalMenu(self, event):
417 #self.OpenHtmlFrame("CAN Festival Reference", os.path.join(ScriptDirectory, "doc/canfestival.html"), wx.Size(1000, 600))
418 os.system("xpdf -remote CANFESTIVAL %s %d &"%(os.path.join(ScriptDirectory, "doc/manual_en.pdf"),16))
421 def OnAboutMenu(self, event):
422 self.OpenHtmlFrame("About CAN Festival", os.path.join(ScriptDirectory, "doc/about.html"), wx.Size(500, 450))
425 def OpenHtmlFrame(self, title, file, size):
426 if title not in self.HtmlFrameOpened:
427 self.HtmlFrameOpened.append(title)
428 window = HtmlFrame(self, self.HtmlFrameOpened)
429 window.SetTitle(title)
430 window.SetHtmlPage(file)
431 window.SetClientSize(size)
434 def OnQuitMenu(self, event):
438 def OnCloseFrame(self, event):
439 if self.Manager.OneFileHasChanged():
440 dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
441 answer = dialog.ShowModal()
443 if answer == wx.ID_YES:
444 self.Manager.ChangeCurrentNode(0)
445 for i in xrange(self.FileOpened.GetPageCount()):
446 window = self.FileOpened.GetPage(i)
447 self.Manager.ChangeCurrentNode(window.GetIndex())
448 if self.Manager.CurrentIsSaved():
449 self.Manager.CloseCurrent()
452 self.Manager.CloseCurrent(True)
454 elif answer == wx.ID_NO:
455 for i in xrange(self.FileOpened.GetPageCount()):
456 self.Manager.CloseCurrent(True)
457 wx.CallAfter(self.Close)
462 #-------------------------------------------------------------------------------
464 #-------------------------------------------------------------------------------
466 def RefreshTitle(self):
467 if self.FileOpened.GetPageCount() > 0:
468 self.SetTitle("Objdictedit - %s"%self.Manager.GetCurrentFilename())
470 self.SetTitle("Objdictedit")
472 def OnRefreshMenu(self, event):
473 self.RefreshCurrentIndexList()
476 def RefreshCurrentIndexList(self):
477 selected = self.FileOpened.GetSelection()
478 window = self.FileOpened.GetPage(selected)
479 window.RefreshIndexList()
481 def RefreshStatusBar(self):
483 selected = self.FileOpened.GetSelection()
485 window = self.FileOpened.GetPage(selected)
486 selection = window.GetSelection()
488 index, subIndex = selection
489 if self.Manager.IsCurrentEntry(index):
490 self.HelpBar.SetStatusText("Index: 0x%04X"%index, 0)
491 self.HelpBar.SetStatusText("Subindex: 0x%02X"%subIndex, 1)
492 entryinfos = self.Manager.GetEntryInfos(index)
493 name = entryinfos["name"]
494 category = "Optional"
495 if entryinfos["need"]:
496 category = "Mandatory"
499 if entryinfos["struct"] & OD_IdenticalIndexes:
500 number = " possibly defined %d times"%entryinfos["nbmax"]
501 if entryinfos["struct"] & OD_IdenticalSubindexes:
503 elif entryinfos["struct"] & OD_MultipleSubindexes:
505 text = "%s: %s entry of struct %s%s."%(name,category,struct,number)
506 self.HelpBar.SetStatusText(text, 2)
509 self.HelpBar.SetStatusText("", i)
512 self.HelpBar.SetStatusText("", i)
514 def RefreshMainMenu(self):
516 if self.FileOpened.GetPageCount() > 0:
517 self.menuBar1.EnableTop(1, True)
518 self.menuBar1.EnableTop(2, True)
519 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS1, True)
520 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS2, True)
521 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS6, True)
522 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS8, True)
523 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS9, True)
525 self.menuBar1.EnableTop(1, False)
526 self.menuBar1.EnableTop(2, False)
527 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS1, False)
528 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS2, False)
529 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS6, False)
530 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS8, False)
531 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS9, False)
533 def RefreshEditMenu(self):
535 if self.FileOpened.GetPageCount() > 0:
536 undo, redo = self.Manager.GetCurrentBufferState()
537 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS1, undo)
538 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS0, redo)
540 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS1, False)
541 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS0, False)
543 def RefreshProfileMenu(self):
545 profile = self.Manager.GetCurrentProfileName()
546 edititem = self.EditMenu.FindItemById(ID_OBJDICTEDITEDITMENUITEMS7)
548 length = self.AddMenu.GetMenuItemCount()
549 for i in xrange(length-6):
550 additem = self.AddMenu.FindItemByPosition(6)
551 self.AddMenu.Delete(additem.GetId())
552 if profile not in ("None", "DS-301"):
553 edititem.SetText("%s Profile"%profile)
554 edititem.Enable(True)
555 self.AddMenu.AppendSeparator()
556 for text, indexes in self.Manager.GetCurrentSpecificMenu():
558 self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
559 self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
561 edititem.SetText("Other Profile")
562 edititem.Enable(False)
565 #-------------------------------------------------------------------------------
567 #-------------------------------------------------------------------------------
569 def RefreshBufferState(self):
570 fileopened = self.Manager.GetAllFilenames()
571 for idx, filename in enumerate(fileopened):
572 self.FileOpened.SetPageText(idx, filename)
573 self.RefreshEditMenu()
576 def OnUndoMenu(self, event):
577 self.Manager.LoadCurrentPrevious()
578 self.RefreshCurrentIndexList()
579 self.RefreshBufferState()
582 def OnRedoMenu(self, event):
583 self.Manager.LoadCurrentNext()
584 self.RefreshCurrentIndexList()
585 self.RefreshBufferState()
589 #-------------------------------------------------------------------------------
590 # Load and Save Funtions
591 #-------------------------------------------------------------------------------
593 def OnNewMenu(self, event):
595 dialog = CreateNodeDialog(self, ScriptDirectory)
596 if dialog.ShowModal() == wx.ID_OK:
597 name, id, nodetype, description = dialog.GetValues()
598 profile, filepath = dialog.GetProfile()
599 NMT = dialog.GetNMTManagement()
600 options = dialog.GetOptions()
601 result = self.Manager.CreateNewNode(name, id, nodetype, description, profile, filepath, NMT, options)
602 if type(result) == IntType:
603 new_editingpanel = EditingPanel(self, self.Manager)
604 new_editingpanel.SetIndex(result)
605 self.FileOpened.AddPage(new_editingpanel, "")
606 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
607 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, False)
608 if "DS302" in options:
609 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, True)
610 self.RefreshBufferState()
611 self.RefreshProfileMenu()
612 self.RefreshMainMenu()
614 message = wx.MessageDialog(self, result, "ERROR", wx.OK|wx.ICON_ERROR)
619 def OnOpenMenu(self, event):
620 filepath = self.Manager.GetCurrentFilePath()
622 directory = os.path.dirname(filepath)
624 directory = os.getcwd()
625 dialog = wx.FileDialog(self, "Choose a file", directory, "", "OD files (*.od)|*.od|All files|*.*", wx.OPEN|wx.CHANGE_DIR)
626 if dialog.ShowModal() == wx.ID_OK:
627 filepath = dialog.GetPath()
628 if os.path.isfile(filepath):
629 result = self.Manager.OpenFileInCurrent(filepath)
630 if type(result) == IntType:
631 new_editingpanel = EditingPanel(self, self.Manager)
632 new_editingpanel.SetIndex(result)
633 self.FileOpened.AddPage(new_editingpanel, "")
634 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
635 if self.Manager.CurrentDS302Defined():
636 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, True)
638 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, False)
639 self.RefreshEditMenu()
640 self.RefreshBufferState()
641 self.RefreshProfileMenu()
642 self.RefreshMainMenu()
644 message = wx.MessageDialog(self, e.args[0], "Error", wx.OK|wx.ICON_ERROR)
650 def OnSaveMenu(self, event):
654 def OnSaveAsMenu(self, event):
659 result = self.Manager.SaveCurrentInFile()
662 elif type(result) != StringType:
663 self.RefreshBufferState()
665 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
670 filepath = self.Manager.GetCurrentFilePath()
672 directory, filename = os.path.split(filepath)
674 directory, filename = os.getcwd(), "%s.od"%self.Manager.GetCurrentNodeInfos()[0]
675 dialog = wx.FileDialog(self, "Choose a file", directory, filename, "OD files (*.od)|*.od|All files|*.*", wx.SAVE|wx.OVERWRITE_PROMPT|wx.CHANGE_DIR)
676 if dialog.ShowModal() == wx.ID_OK:
677 filepath = dialog.GetPath()
678 if os.path.isdir(os.path.dirname(filepath)):
679 result = self.Manager.SaveCurrentInFile(filepath)
680 if type(result) != StringType:
681 self.RefreshBufferState()
683 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
687 message = wx.MessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wx.OK|wx.ICON_ERROR)
692 def OnCloseMenu(self, event):
694 result = self.Manager.CloseCurrent()
696 dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close File", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
697 answer = dialog.ShowModal()
699 if answer == wx.ID_YES:
700 self.OnSaveMenu(event)
701 if self.Manager.CurrentIsSaved():
702 self.Manager.CloseCurrent()
703 elif answer == wx.ID_NO:
704 self.Manager.CloseCurrent(True)
705 if self.FileOpened.GetPageCount() > self.Manager.GetBufferNumber():
706 current = self.FileOpened.GetSelection()
707 self.FileOpened.DeletePage(current)
708 if self.FileOpened.GetPageCount() > 0:
709 self.FileOpened.SetSelection(min(current, self.FileOpened.GetPageCount() - 1))
710 self.RefreshBufferState()
711 self.RefreshMainMenu()
715 #-------------------------------------------------------------------------------
716 # Import and Export Functions
717 #-------------------------------------------------------------------------------
719 def OnImportEDSMenu(self, event):
720 dialog = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "EDS files (*.eds)|*.eds|All files|*.*", wx.OPEN|wx.CHANGE_DIR)
721 if dialog.ShowModal() == wx.ID_OK:
722 filepath = dialog.GetPath()
723 if os.path.isfile(filepath):
724 result = self.Manager.ImportCurrentFromEDSFile(filepath)
725 if type(result) == IntType:
726 new_editingpanel = EditingPanel(self, self.Manager)
727 new_editingpanel.SetIndex(result)
728 self.FileOpened.AddPage(new_editingpanel, "")
729 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
730 self.RefreshBufferState()
731 self.RefreshCurrentIndexList()
732 self.RefreshProfileMenu()
733 self.RefreshMainMenu()
734 message = wx.MessageDialog(self, "Import successful", "Information", wx.OK|wx.ICON_INFORMATION)
738 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
742 message = wx.MessageDialog(self, "\"%s\" is not a valid file!"%filepath, "Error", wx.OK|wx.ICON_ERROR)
749 def OnExportEDSMenu(self, event):
750 dialog = wx.FileDialog(self, "Choose a file", os.getcwd(), self.Manager.GetCurrentNodeInfos()[0], "EDS files (*.eds)|*.eds|All files|*.*", wx.SAVE|wx.OVERWRITE_PROMPT|wx.CHANGE_DIR)
751 if dialog.ShowModal() == wx.ID_OK:
752 filepath = dialog.GetPath()
753 if os.path.isdir(os.path.dirname(filepath)):
754 path, extend = os.path.splitext(filepath)
755 if extend in ("", "."):
756 filepath = path + ".eds"
757 result = self.Manager.ExportCurrentToEDSFile(filepath)
759 message = wx.MessageDialog(self, "Export successful", "Information", wx.OK|wx.ICON_INFORMATION)
763 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
767 message = wx.MessageDialog(self, "\"%s\" is not a valid folder!"%os.path.dirname(filepath), "Error", wx.OK|wx.ICON_ERROR)
773 def OnExportCMenu(self, event):
774 dialog = wx.FileDialog(self, "Choose a file", os.getcwd(), self.Manager.GetCurrentNodeInfos()[0], "CANFestival C files (*.c)|*.c|All files|*.*", wx.SAVE|wx.OVERWRITE_PROMPT|wx.CHANGE_DIR)
775 if dialog.ShowModal() == wx.ID_OK:
776 filepath = dialog.GetPath()
777 if os.path.isdir(os.path.dirname(filepath)):
778 path, extend = os.path.splitext(filepath)
779 if extend in ("", "."):
780 filepath = path + ".c"
781 result = self.Manager.ExportCurrentToCFile(filepath)
783 message = wx.MessageDialog(self, "Export successful", "Information", wx.OK|wx.ICON_INFORMATION)
787 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
791 message = wx.MessageDialog(self, "\"%s\" is not a valid folder!"%os.path.dirname(filepath), "Error", wx.OK|wx.ICON_ERROR)
797 #-------------------------------------------------------------------------------
798 # Editing Profiles functions
799 #-------------------------------------------------------------------------------
801 def OnCommunicationMenu(self, event):
802 dictionary,current = self.Manager.GetCurrentCommunicationLists()
803 self.EditProfile("Edit DS-301 Profile", dictionary, current)
806 def OnOtherCommunicationMenu(self, event):
807 dictionary,current = self.Manager.GetCurrentDS302Lists()
808 self.EditProfile("Edit DS-301 Profile", dictionary, current)
811 def OnEditProfileMenu(self, event):
812 title = "Edit %s Profile"%self.Manager.GetCurrentProfileName()
813 dictionary,current = self.Manager.GetCurrentProfileLists()
814 self.EditProfile(title, dictionary, current)
817 def EditProfile(self, title, dictionary, current):
818 dialog = CommunicationDialog(self)
819 dialog.SetTitle(title)
820 dialog.SetIndexDictionary(dictionary)
821 dialog.SetCurrentList(current)
822 dialog.RefreshLists()
823 if dialog.ShowModal() == wx.ID_OK:
824 new_profile = dialog.GetCurrentList()
827 for index in new_profile:
828 if index not in current:
829 addinglist.append(index)
830 for index in current:
831 if index not in new_profile:
832 removinglist.append(index)
833 self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
834 self.Manager.BufferCurrentNode()
835 self.RefreshBufferState()
836 self.RefreshCurrentIndexList()
839 def GetProfileCallBack(self, text):
840 def ProfileCallBack(event):
841 self.Manager.AddSpecificEntryToCurrent(text)
842 self.RefreshBufferState()
843 self.RefreshCurrentIndexList()
845 return ProfileCallBack
847 #-------------------------------------------------------------------------------
848 # Edit Node informations function
849 #-------------------------------------------------------------------------------
851 def OnNodeInfosMenu(self, event):
852 dialog = NodeInfosDialog(self)
853 name, id, type, description = self.Manager.GetCurrentNodeInfos()
854 dialog.SetValues(name, id, type, description)
855 if dialog.ShowModal() == wx.ID_OK:
856 name, id, type, description = dialog.GetValues()
857 self.Manager.SetCurrentNodeInfos(name, id, type, description)
858 self.RefreshBufferState()
859 self.RefreshProfileMenu()
860 selected = self.FileOpened.GetSelection()
862 window = self.FileOpened.GetPage(selected)
863 window.RefreshTable()
867 #-------------------------------------------------------------------------------
868 # Add User Types and Variables
869 #-------------------------------------------------------------------------------
871 def AddMapVariable(self):
872 index = self.Manager.GetCurrentNextMapIndex()
874 dialog = MapVariableDialog(self)
875 dialog.SetIndex(index)
876 if dialog.ShowModal() == wx.ID_OK:
877 index, name, struct, number = dialog.GetValues()
878 result = self.Manager.AddMapVariableToCurrent(index, name, struct, number)
879 if type(result) != StringType:
880 self.RefreshBufferState()
881 self.RefreshCurrentIndexList()
883 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
888 message = wx.MessageDialog(self, result, "No map variable index left!", wx.OK|wx.ICON_ERROR)
892 def AddUserType(self):
893 dialog = UserTypeDialog(self)
894 dialog.SetTypeList(self.Manager.GetCustomisableTypes())
895 if dialog.ShowModal() == wx.ID_OK:
896 type, min, max, length = dialog.GetValues()
897 result = self.Manager.AddUserTypeToCurrent(type, min, max, length)
899 self.RefreshBufferState()
900 self.RefreshCurrentIndexList()
902 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
908 #-------------------------------------------------------------------------------
910 #-------------------------------------------------------------------------------
912 Max_Traceback_List_Size = 20
914 def Display_Exception_Dialog(e_type,e_value,e_tb):
916 for i,line in enumerate(traceback.extract_tb(e_tb)):
917 trcbck = " " + str(i+1) + ". "
918 if line[0].find(os.getcwd()) == -1:
919 trcbck += "file : " + str(line[0]) + ", "
921 trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ", "
922 trcbck += "line : " + str(line[1]) + ", " + "function : " + str(line[2])
923 trcbck_lst.append(trcbck)
926 cap = wx.Window_GetCapture()
930 dlg = wx.SingleChoiceDialog(None,
934 Click on OK for saving an error report.
936 Please contact LOLITech at:
938 bugs_objdictedit@lolitech.fr
943 str(e_type) + " : " + str(e_value),
947 res = (dlg.ShowModal() == wx.ID_OK)
953 def Display_Error_Dialog(e_value):
954 message = wx.MessageDialog(None, str(e_value), "Error", wx.OK|wx.ICON_ERROR)
958 def get_last_traceback(tb):
964 def format_namespace(d, indent=' '):
965 return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
968 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
970 def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
972 def handle_exception(e_type, e_value, e_traceback):
973 traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
974 last_tb = get_last_traceback(e_traceback)
975 ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
976 if str(e_value).startswith("!!!"):
977 Display_Error_Dialog(e_value)
978 elif ex not in ignored_exceptions:
979 ignored_exceptions.append(ex)
980 result = Display_Exception_Dialog(e_type,e_value,e_traceback)
983 'app-title' : wx.GetApp().GetAppName(), # app_title
984 'app-version' : app_version,
985 'wx-version' : wx.VERSION_STRING,
986 'wx-platform' : wx.Platform,
987 'python-version' : platform.python_version(), #sys.version.split()[0],
988 'platform' : platform.platform(),
991 'date' : time.ctime(),
995 info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
996 last_tb = get_last_traceback(e_traceback)
997 exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
998 info['locals'] = format_namespace(exception_locals)
999 if 'self' in exception_locals:
1000 info['self'] = format_namespace(exception_locals['self'].__dict__)
1002 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
1006 output.write(a+":\n"+str(info[a])+"\n\n")
1008 #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
1009 sys.excepthook = handle_exception
1011 if __name__ == '__main__':
1012 app = wx.PySimpleApp()
1013 wx.InitAllImageHandlers()
1015 # Install a exception handle for bug reports
1016 AddExceptHook(os.getcwd(),__version__)
1018 frame = objdictedit(None)