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.40 $"
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)
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)
108 ScriptDirectory = os.path.split(os.path.realpath(__file__))[0]
110 [ID_OBJDICTEDIT, ID_OBJDICTEDITFILEOPENED,
111 ID_OBJDICTEDITHELPBAR,
112 ] = [wx.NewId() for _init_ctrls in range(3)]
114 [ID_OBJDICTEDITADDMENUITEMS0, ID_OBJDICTEDITADDMENUITEMS1,
115 ID_OBJDICTEDITADDMENUITEMS2, ID_OBJDICTEDITADDMENUITEMS3,
116 ID_OBJDICTEDITADDMENUITEMS4, ID_OBJDICTEDITADDMENUITEMS5,
117 ] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
119 [ID_OBJDICTEDITFILEMENUITEMS0, ID_OBJDICTEDITFILEMENUITEMS1,
120 ID_OBJDICTEDITFILEMENUITEMS2, ID_OBJDICTEDITFILEMENUITEMS4,
121 ID_OBJDICTEDITFILEMENUITEMS5, ID_OBJDICTEDITFILEMENUITEMS6,
122 ID_OBJDICTEDITFILEMENUITEMS7, ID_OBJDICTEDITFILEMENUITEMS8,
123 ID_OBJDICTEDITFILEMENUITEMS9,
124 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(9)]
126 [ID_OBJDICTEDITEDITMENUITEMS0, ID_OBJDICTEDITEDITMENUITEMS1,
127 ID_OBJDICTEDITEDITMENUITEMS2, ID_OBJDICTEDITEDITMENUITEMS4,
128 ID_OBJDICTEDITEDITMENUITEMS6, ID_OBJDICTEDITEDITMENUITEMS7,
129 ID_OBJDICTEDITEDITMENUITEMS8,
130 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(7)]
132 [ID_OBJDICTEDITHELPMENUITEMS0, ID_OBJDICTEDITHELPMENUITEMS1,
133 ID_OBJDICTEDITHELPMENUITEMS2,
134 ] = [wx.NewId() for _init_coll_HelpMenu_Items in range(3)]
136 class objdictedit(wx.Frame):
137 def _init_coll_menuBar1_Menus(self, parent):
138 parent.Append(menu=self.FileMenu, title='File')
139 parent.Append(menu=self.EditMenu, title='Edit')
140 parent.Append(menu=self.AddMenu, title='Add')
141 parent.Append(menu=self.HelpMenu, title='Help')
143 def _init_coll_EditMenu_Items(self, parent):
144 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS4,
145 kind=wx.ITEM_NORMAL, text='Refresh\tCTRL+R')
146 parent.AppendSeparator()
147 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS1,
148 kind=wx.ITEM_NORMAL, text='Undo\tCTRL+Z')
149 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS0,
150 kind=wx.ITEM_NORMAL, text='Redo\tCTRL+Y')
151 parent.AppendSeparator()
152 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS6,
153 kind=wx.ITEM_NORMAL, text='Node infos')
154 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS2,
155 kind=wx.ITEM_NORMAL, text='DS-301 Profile')
156 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS8,
157 kind=wx.ITEM_NORMAL, text='DS-302 Profile')
158 parent.Append(help='', id=ID_OBJDICTEDITEDITMENUITEMS7,
159 kind=wx.ITEM_NORMAL, text='Other Profile')
160 self.Bind(wx.EVT_MENU, self.OnUndoMenu,
161 id=ID_OBJDICTEDITEDITMENUITEMS1)
162 self.Bind(wx.EVT_MENU, self.OnRedoMenu,
163 id=ID_OBJDICTEDITEDITMENUITEMS0)
164 self.Bind(wx.EVT_MENU, self.OnCommunicationMenu,
165 id=ID_OBJDICTEDITEDITMENUITEMS2)
166 self.Bind(wx.EVT_MENU, self.OnRefreshMenu,
167 id=ID_OBJDICTEDITEDITMENUITEMS4)
168 self.Bind(wx.EVT_MENU, self.OnNodeInfosMenu,
169 id=ID_OBJDICTEDITEDITMENUITEMS6)
170 self.Bind(wx.EVT_MENU, self.OnEditProfileMenu,
171 id=ID_OBJDICTEDITEDITMENUITEMS7)
172 self.Bind(wx.EVT_MENU, self.OnOtherCommunicationMenu,
173 id=ID_OBJDICTEDITEDITMENUITEMS8)
175 def _init_coll_HelpMenu_Items(self, parent):
176 parent.Append(help='', id=ID_OBJDICTEDITHELPMENUITEMS0,
177 kind=wx.ITEM_NORMAL, text='DS-301 Standard\tF1')
178 self.Bind(wx.EVT_MENU, self.OnHelpDS301Menu,
179 id=ID_OBJDICTEDITHELPMENUITEMS0)
180 parent.Append(help='', id=ID_OBJDICTEDITHELPMENUITEMS1,
181 kind=wx.ITEM_NORMAL, text='CAN Festival Docs\tF2')
182 self.Bind(wx.EVT_MENU, self.OnHelpCANFestivalMenu,
183 id=ID_OBJDICTEDITHELPMENUITEMS1)
185 parent.Append(help='', id=ID_OBJDICTEDITHELPMENUITEMS2,
186 kind=wx.ITEM_NORMAL, text='About')
187 self.Bind(wx.EVT_MENU, self.OnAboutMenu,
188 id=ID_OBJDICTEDITHELPMENUITEMS2)
190 def _init_coll_FileMenu_Items(self, parent):
191 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS5,
192 kind=wx.ITEM_NORMAL, text='New\tCTRL+N')
193 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS0,
194 kind=wx.ITEM_NORMAL, text='Open\tCTRL+O')
195 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS1,
196 kind=wx.ITEM_NORMAL, text='Save\tCTRL+S')
197 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS6,
198 kind=wx.ITEM_NORMAL, text='Save As...\tALT+S')
199 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS2,
200 kind=wx.ITEM_NORMAL, text='Close\tCTRL+W')
201 parent.AppendSeparator()
202 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS7,
203 kind=wx.ITEM_NORMAL, text='Import EDS file')
204 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS9,
205 kind=wx.ITEM_NORMAL, text='Export to EDS file')
206 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS8,
207 kind=wx.ITEM_NORMAL, text='Build Dictionary\tCTRL+B')
208 parent.AppendSeparator()
209 parent.Append(help='', id=ID_OBJDICTEDITFILEMENUITEMS4,
210 kind=wx.ITEM_NORMAL, text='Exit')
211 self.Bind(wx.EVT_MENU, self.OnOpenMenu,
212 id=ID_OBJDICTEDITFILEMENUITEMS0)
213 self.Bind(wx.EVT_MENU, self.OnSaveMenu,
214 id=ID_OBJDICTEDITFILEMENUITEMS1)
215 self.Bind(wx.EVT_MENU, self.OnCloseMenu,
216 id=ID_OBJDICTEDITFILEMENUITEMS2)
217 self.Bind(wx.EVT_MENU, self.OnQuitMenu,
218 id=ID_OBJDICTEDITFILEMENUITEMS4)
219 self.Bind(wx.EVT_MENU, self.OnNewMenu,
220 id=ID_OBJDICTEDITFILEMENUITEMS5)
221 self.Bind(wx.EVT_MENU, self.OnSaveAsMenu,
222 id=ID_OBJDICTEDITFILEMENUITEMS6)
223 self.Bind(wx.EVT_MENU, self.OnImportEDSMenu,
224 id=ID_OBJDICTEDITFILEMENUITEMS7)
225 self.Bind(wx.EVT_MENU, self.OnExportCMenu,
226 id=ID_OBJDICTEDITFILEMENUITEMS8)
227 self.Bind(wx.EVT_MENU, self.OnExportEDSMenu,
228 id=ID_OBJDICTEDITFILEMENUITEMS9)
230 def _init_coll_AddMenu_Items(self, parent):
231 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS0,
232 kind=wx.ITEM_NORMAL, text='SDO Server')
233 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS1,
234 kind=wx.ITEM_NORMAL, text='SDO Client')
235 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS2,
236 kind=wx.ITEM_NORMAL, text='PDO Transmit')
237 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS3,
238 kind=wx.ITEM_NORMAL, text='PDO Receive')
239 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS4,
240 kind=wx.ITEM_NORMAL, text='Map Variable')
241 parent.Append(help='', id=ID_OBJDICTEDITADDMENUITEMS5,
242 kind=wx.ITEM_NORMAL, text='User Type')
243 self.Bind(wx.EVT_MENU, self.OnAddSDOServerMenu,
244 id=ID_OBJDICTEDITADDMENUITEMS0)
245 self.Bind(wx.EVT_MENU, self.OnAddSDOClientMenu,
246 id=ID_OBJDICTEDITADDMENUITEMS1)
247 self.Bind(wx.EVT_MENU, self.OnAddPDOTransmitMenu,
248 id=ID_OBJDICTEDITADDMENUITEMS2)
249 self.Bind(wx.EVT_MENU, self.OnAddPDOReceiveMenu,
250 id=ID_OBJDICTEDITADDMENUITEMS3)
251 self.Bind(wx.EVT_MENU, self.OnAddMapVariableMenu,
252 id=ID_OBJDICTEDITADDMENUITEMS4)
253 self.Bind(wx.EVT_MENU, self.OnAddUserTypeMenu,
254 id=ID_OBJDICTEDITADDMENUITEMS5)
256 def _init_coll_HelpBar_Fields(self, parent):
257 parent.SetFieldsCount(3)
259 parent.SetStatusText(number=0, text='')
260 parent.SetStatusText(number=1, text='')
261 parent.SetStatusText(number=2, text='')
263 parent.SetStatusWidths([100, 110, -1])
265 def _init_utils(self):
266 self.menuBar1 = wx.MenuBar()
267 self.menuBar1.SetEvtHandlerEnabled(True)
269 self.FileMenu = wx.Menu(title='')
270 self.EditMenu = wx.Menu(title='')
271 self.AddMenu = wx.Menu(title='')
272 self.HelpMenu = wx.Menu(title='')
274 self._init_coll_menuBar1_Menus(self.menuBar1)
275 self._init_coll_FileMenu_Items(self.FileMenu)
276 self._init_coll_EditMenu_Items(self.EditMenu)
277 self._init_coll_AddMenu_Items(self.AddMenu)
278 self._init_coll_HelpMenu_Items(self.HelpMenu)
280 def _init_ctrls(self, prnt):
281 wx.Frame.__init__(self, id=ID_OBJDICTEDIT, name='objdictedit',
282 parent=prnt, pos=wx.Point(149, 178), size=wx.Size(1000, 700),
283 style=wx.DEFAULT_FRAME_STYLE, title='Objdictedit')
285 self.SetClientSize(wx.Size(1000, 700))
286 self.SetMenuBar(self.menuBar1)
287 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame)
289 self.FileOpened = wx.Notebook(id=ID_OBJDICTEDITFILEOPENED,
290 name='FileOpened', parent=self, pos=wx.Point(0, 0),
291 size=wx.Size(0, 0), style=0)
292 self.FileOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
293 self.OnFileSelectedChanged, id=ID_OBJDICTEDITFILEOPENED)
295 self.HelpBar = wx.StatusBar(id=ID_OBJDICTEDITHELPBAR, name='HelpBar',
296 parent=self, style=wx.ST_SIZEGRIP)
297 self._init_coll_HelpBar_Fields(self.HelpBar)
298 self.SetStatusBar(self.HelpBar)
300 def __init__(self, parent, filesOpen = []):
301 self._init_ctrls(parent)
302 self.HtmlFrameOpened = []
305 icon = wx.Icon(os.path.join(ScriptDirectory,"networkedit.ico"),wx.BITMAP_TYPE_ICO)
308 self.Manager = NodeManager()
309 for filepath in filesOpen:
310 result = self.Manager.OpenFileInCurrent(filepath)
311 if type(result) == IntType:
312 new_editingpanel = EditingPanel(self.FileOpened, self, self.Manager)
313 new_editingpanel.SetIndex(result)
314 self.FileOpened.AddPage(new_editingpanel, "")
315 window = self.FileOpened.GetPage(0)
317 self.Manager.ChangeCurrentNode(window.GetIndex())
318 self.FileOpened.SetSelection(0)
319 if self.Manager.CurrentDS302Defined():
320 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, True)
322 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, False)
323 self.RefreshEditMenu()
324 self.RefreshBufferState()
325 self.RefreshProfileMenu()
327 self.RefreshMainMenu()
329 def OnAddSDOServerMenu(self, event):
330 self.Manager.AddSDOServerToCurrent()
331 self.RefreshBufferState()
332 self.RefreshCurrentIndexList()
335 def OnAddSDOClientMenu(self, event):
336 self.Manager.AddSDOClientToCurrent()
337 self.RefreshBufferState()
338 self.RefreshCurrentIndexList()
341 def OnAddPDOTransmitMenu(self, event):
342 self.Manager.AddPDOTransmitToCurrent()
343 self.RefreshBufferState()
344 self.RefreshCurrentIndexList()
347 def OnAddPDOReceiveMenu(self, event):
348 self.Manager.AddPDOReceiveToCurrent()
349 self.RefreshBufferState()
350 self.RefreshCurrentIndexList()
353 def OnAddMapVariableMenu(self, event):
354 self.AddMapVariable()
357 def OnAddUserTypeMenu(self, event):
361 def OnFileSelectedChanged(self, event):
362 selected = event.GetSelection()
363 # At init selected = -1
365 window = self.FileOpened.GetPage(selected)
367 self.Manager.ChangeCurrentNode(window.GetIndex())
368 wx.CallAfter(self.RefreshBufferState)
369 self.RefreshStatusBar()
370 self.RefreshProfileMenu()
373 def OnHelpDS301Menu(self, event):
375 selected = self.FileOpened.GetSelection()
377 window = self.FileOpened.GetPage(selected)
378 result = window.GetSelection()
381 index, subIndex = result
382 result = OpenPDFDocIndex(index, ScriptDirectory)
383 if type(result) == StringType:
384 message = wx.MessageDialog(self, result, "ERROR", wx.OK|wx.ICON_ERROR)
388 result = OpenPDFDocIndex(None, ScriptDirectory)
389 if type(result) == StringType:
390 message = wx.MessageDialog(self, result, "ERROR", wx.OK|wx.ICON_ERROR)
395 def OnHelpCANFestivalMenu(self, event):
396 #self.OpenHtmlFrame("CAN Festival Reference", os.path.join(ScriptDirectory, "doc/canfestival.html"), wx.Size(1000, 600))
397 if wx.Platform == '__WXMSW__':
398 readerpath = get_acroversion()
399 readerexepath = os.path.join(readerpath,"AcroRd32.exe")
400 if(os.path.isfile(readerexepath)):
401 os.spawnl(os.P_DETACH, readerexepath, "AcroRd32.exe", '"%s"'%os.path.join(ScriptDirectory, "doc","manual_en.pdf"))
403 os.system("xpdf -remote CANFESTIVAL %s %d &"%(os.path.join(ScriptDirectory, "doc/manual_en.pdf"),16))
406 def OnAboutMenu(self, event):
407 self.OpenHtmlFrame("About CAN Festival", os.path.join(ScriptDirectory, "doc/about.html"), wx.Size(500, 450))
410 def OpenHtmlFrame(self, title, file, size):
411 if title not in self.HtmlFrameOpened:
412 self.HtmlFrameOpened.append(title)
413 window = HtmlFrame(self, self.HtmlFrameOpened)
414 window.SetTitle(title)
415 window.SetHtmlPage(file)
416 window.SetClientSize(size)
419 def OnQuitMenu(self, event):
423 def OnCloseFrame(self, event):
424 if self.Manager.OneFileHasChanged():
425 dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
426 answer = dialog.ShowModal()
428 if answer == wx.ID_YES:
429 self.Manager.ChangeCurrentNode(0)
430 for i in xrange(self.FileOpened.GetPageCount()):
431 window = self.FileOpened.GetPage(i)
432 self.Manager.ChangeCurrentNode(window.GetIndex())
433 if self.Manager.CurrentIsSaved():
434 self.Manager.CloseCurrent()
437 self.Manager.CloseCurrent(True)
439 elif answer == wx.ID_NO:
440 for i in xrange(self.FileOpened.GetPageCount()):
441 self.Manager.CloseCurrent(True)
442 wx.CallAfter(self.Close)
447 #-------------------------------------------------------------------------------
449 #-------------------------------------------------------------------------------
451 def RefreshTitle(self):
452 if self.FileOpened.GetPageCount() > 0:
453 self.SetTitle("Objdictedit - %s"%self.Manager.GetCurrentFilename())
455 self.SetTitle("Objdictedit")
457 def OnRefreshMenu(self, event):
458 self.RefreshCurrentIndexList()
461 def RefreshCurrentIndexList(self):
462 selected = self.FileOpened.GetSelection()
463 window = self.FileOpened.GetPage(selected)
464 window.RefreshIndexList()
466 def RefreshStatusBar(self):
467 if self and self.HelpBar:
468 selected = self.FileOpened.GetSelection()
470 window = self.FileOpened.GetPage(selected)
471 selection = window.GetSelection()
473 index, subIndex = selection
474 if self.Manager.IsCurrentEntry(index):
475 self.HelpBar.SetStatusText("Index: 0x%04X"%index, 0)
476 self.HelpBar.SetStatusText("Subindex: 0x%02X"%subIndex, 1)
477 entryinfos = self.Manager.GetEntryInfos(index)
478 name = entryinfos["name"]
479 category = "Optional"
480 if entryinfos["need"]:
481 category = "Mandatory"
484 if entryinfos["struct"] & OD_IdenticalIndexes:
485 number = " possibly defined %d times"%entryinfos["nbmax"]
486 if entryinfos["struct"] & OD_IdenticalSubindexes:
488 elif entryinfos["struct"] & OD_MultipleSubindexes:
490 text = "%s: %s entry of struct %s%s."%(name,category,struct,number)
491 self.HelpBar.SetStatusText(text, 2)
494 self.HelpBar.SetStatusText("", i)
497 self.HelpBar.SetStatusText("", i)
499 def RefreshMainMenu(self):
501 if self.FileOpened.GetPageCount() > 0:
502 self.menuBar1.EnableTop(1, True)
503 self.menuBar1.EnableTop(2, True)
504 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS1, True)
505 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS2, True)
506 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS6, True)
507 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS8, True)
508 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS9, True)
510 self.menuBar1.EnableTop(1, False)
511 self.menuBar1.EnableTop(2, False)
512 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS1, False)
513 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS2, False)
514 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS6, False)
515 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS8, False)
516 self.FileMenu.Enable(ID_OBJDICTEDITFILEMENUITEMS9, False)
518 def RefreshEditMenu(self):
520 if self.FileOpened.GetPageCount() > 0:
521 undo, redo = self.Manager.GetCurrentBufferState()
522 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS1, undo)
523 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS0, redo)
525 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS1, False)
526 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS0, False)
528 def RefreshProfileMenu(self):
530 profile = self.Manager.GetCurrentProfileName()
531 edititem = self.EditMenu.FindItemById(ID_OBJDICTEDITEDITMENUITEMS7)
533 length = self.AddMenu.GetMenuItemCount()
534 for i in xrange(length-6):
535 additem = self.AddMenu.FindItemByPosition(6)
536 self.AddMenu.Delete(additem.GetId())
537 if profile not in ("None", "DS-301"):
538 edititem.SetText("%s Profile"%profile)
539 edititem.Enable(True)
540 self.AddMenu.AppendSeparator()
541 for text, indexes in self.Manager.GetCurrentSpecificMenu():
543 self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
544 self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
546 edititem.SetText("Other Profile")
547 edititem.Enable(False)
550 #-------------------------------------------------------------------------------
552 #-------------------------------------------------------------------------------
554 def RefreshBufferState(self):
555 fileopened = self.Manager.GetAllFilenames()
556 for idx, filename in enumerate(fileopened):
557 self.FileOpened.SetPageText(idx, filename)
558 self.RefreshEditMenu()
561 def OnUndoMenu(self, event):
562 self.Manager.LoadCurrentPrevious()
563 self.RefreshCurrentIndexList()
564 self.RefreshBufferState()
567 def OnRedoMenu(self, event):
568 self.Manager.LoadCurrentNext()
569 self.RefreshCurrentIndexList()
570 self.RefreshBufferState()
574 #-------------------------------------------------------------------------------
575 # Load and Save Funtions
576 #-------------------------------------------------------------------------------
578 def OnNewMenu(self, event):
580 dialog = CreateNodeDialog(self)
581 if dialog.ShowModal() == wx.ID_OK:
582 name, id, nodetype, description = dialog.GetValues()
583 profile, filepath = dialog.GetProfile()
584 NMT = dialog.GetNMTManagement()
585 options = dialog.GetOptions()
586 result = self.Manager.CreateNewNode(name, id, nodetype, description, profile, filepath, NMT, options)
587 if type(result) == IntType:
588 new_editingpanel = EditingPanel(self.FileOpened, self, self.Manager)
589 new_editingpanel.SetIndex(result)
590 self.FileOpened.AddPage(new_editingpanel, "")
591 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
592 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, False)
593 if "DS302" in options:
594 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, True)
595 self.RefreshBufferState()
596 self.RefreshProfileMenu()
597 self.RefreshMainMenu()
599 message = wx.MessageDialog(self, result, "ERROR", wx.OK|wx.ICON_ERROR)
605 def OnOpenMenu(self, event):
606 filepath = self.Manager.GetCurrentFilePath()
608 directory = os.path.dirname(filepath)
610 directory = os.getcwd()
611 dialog = wx.FileDialog(self, "Choose a file", directory, "", "OD files (*.od)|*.od|All files|*.*", wx.OPEN|wx.CHANGE_DIR)
612 if dialog.ShowModal() == wx.ID_OK:
613 filepath = dialog.GetPath()
614 if os.path.isfile(filepath):
615 result = self.Manager.OpenFileInCurrent(filepath)
616 if type(result) == IntType:
617 new_editingpanel = EditingPanel(self.FileOpened, self, self.Manager)
618 new_editingpanel.SetIndex(result)
619 self.FileOpened.AddPage(new_editingpanel, "")
620 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
621 if self.Manager.CurrentDS302Defined():
622 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, True)
624 self.EditMenu.Enable(ID_OBJDICTEDITEDITMENUITEMS8, False)
625 self.RefreshEditMenu()
626 self.RefreshBufferState()
627 self.RefreshProfileMenu()
628 self.RefreshMainMenu()
630 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
636 def OnSaveMenu(self, event):
640 def OnSaveAsMenu(self, event):
645 result = self.Manager.SaveCurrentInFile()
648 elif type(result) != StringType:
649 self.RefreshBufferState()
651 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
656 filepath = self.Manager.GetCurrentFilePath()
658 directory, filename = os.path.split(filepath)
660 directory, filename = os.getcwd(), "%s.od"%self.Manager.GetCurrentNodeInfos()[0]
661 dialog = wx.FileDialog(self, "Choose a file", directory, filename, "OD files (*.od)|*.od|All files|*.*", wx.SAVE|wx.OVERWRITE_PROMPT|wx.CHANGE_DIR)
662 if dialog.ShowModal() == wx.ID_OK:
663 filepath = dialog.GetPath()
664 if os.path.isdir(os.path.dirname(filepath)):
665 result = self.Manager.SaveCurrentInFile(filepath)
666 if type(result) != StringType:
667 self.RefreshBufferState()
669 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
673 message = wx.MessageDialog(self, "%s is not a valid folder!"%os.path.dirname(filepath), "Error", wx.OK|wx.ICON_ERROR)
678 def OnCloseMenu(self, event):
680 result = self.Manager.CloseCurrent()
682 dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close File", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
683 answer = dialog.ShowModal()
685 if answer == wx.ID_YES:
686 self.OnSaveMenu(event)
687 if self.Manager.CurrentIsSaved():
688 self.Manager.CloseCurrent()
689 elif answer == wx.ID_NO:
690 self.Manager.CloseCurrent(True)
691 if self.FileOpened.GetPageCount() > self.Manager.GetBufferNumber():
692 current = self.FileOpened.GetSelection()
693 self.FileOpened.DeletePage(current)
694 if self.FileOpened.GetPageCount() > 0:
695 self.FileOpened.SetSelection(min(current, self.FileOpened.GetPageCount() - 1))
696 self.RefreshBufferState()
697 self.RefreshMainMenu()
701 #-------------------------------------------------------------------------------
702 # Import and Export Functions
703 #-------------------------------------------------------------------------------
705 def OnImportEDSMenu(self, event):
706 dialog = wx.FileDialog(self, "Choose a file", os.getcwd(), "", "EDS files (*.eds)|*.eds|All files|*.*", wx.OPEN|wx.CHANGE_DIR)
707 if dialog.ShowModal() == wx.ID_OK:
708 filepath = dialog.GetPath()
709 if os.path.isfile(filepath):
710 result = self.Manager.ImportCurrentFromEDSFile(filepath)
711 if type(result) == IntType:
712 new_editingpanel = EditingPanel(self.FileOpened, self, self.Manager)
713 new_editingpanel.SetIndex(result)
714 self.FileOpened.AddPage(new_editingpanel, "")
715 self.FileOpened.SetSelection(self.FileOpened.GetPageCount() - 1)
716 self.RefreshBufferState()
717 self.RefreshCurrentIndexList()
718 self.RefreshProfileMenu()
719 self.RefreshMainMenu()
720 message = wx.MessageDialog(self, "Import successful", "Information", wx.OK|wx.ICON_INFORMATION)
724 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
728 message = wx.MessageDialog(self, "\"%s\" is not a valid file!"%filepath, "Error", wx.OK|wx.ICON_ERROR)
735 def OnExportEDSMenu(self, event):
736 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)
737 if dialog.ShowModal() == wx.ID_OK:
738 filepath = dialog.GetPath()
739 if os.path.isdir(os.path.dirname(filepath)):
740 path, extend = os.path.splitext(filepath)
741 if extend in ("", "."):
742 filepath = path + ".eds"
743 result = self.Manager.ExportCurrentToEDSFile(filepath)
745 message = wx.MessageDialog(self, "Export successful", "Information", wx.OK|wx.ICON_INFORMATION)
749 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
753 message = wx.MessageDialog(self, "\"%s\" is not a valid folder!"%os.path.dirname(filepath), "Error", wx.OK|wx.ICON_ERROR)
759 def OnExportCMenu(self, event):
760 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)
761 if dialog.ShowModal() == wx.ID_OK:
762 filepath = dialog.GetPath()
763 if os.path.isdir(os.path.dirname(filepath)):
764 path, extend = os.path.splitext(filepath)
765 if extend in ("", "."):
766 filepath = path + ".c"
767 result = self.Manager.ExportCurrentToCFile(filepath)
769 message = wx.MessageDialog(self, "Export successful", "Information", wx.OK|wx.ICON_INFORMATION)
773 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
777 message = wx.MessageDialog(self, "\"%s\" is not a valid folder!"%os.path.dirname(filepath), "Error", wx.OK|wx.ICON_ERROR)
783 #-------------------------------------------------------------------------------
784 # Editing Profiles functions
785 #-------------------------------------------------------------------------------
787 def OnCommunicationMenu(self, event):
788 dictionary,current = self.Manager.GetCurrentCommunicationLists()
789 self.EditProfile("Edit DS-301 Profile", dictionary, current)
792 def OnOtherCommunicationMenu(self, event):
793 dictionary,current = self.Manager.GetCurrentDS302Lists()
794 self.EditProfile("Edit DS-301 Profile", dictionary, current)
797 def OnEditProfileMenu(self, event):
798 title = "Edit %s Profile"%self.Manager.GetCurrentProfileName()
799 dictionary,current = self.Manager.GetCurrentProfileLists()
800 self.EditProfile(title, dictionary, current)
803 def EditProfile(self, title, dictionary, current):
804 dialog = CommunicationDialog(self)
805 dialog.SetTitle(title)
806 dialog.SetIndexDictionary(dictionary)
807 dialog.SetCurrentList(current)
808 dialog.RefreshLists()
809 if dialog.ShowModal() == wx.ID_OK:
810 new_profile = dialog.GetCurrentList()
813 for index in new_profile:
814 if index not in current:
815 addinglist.append(index)
816 for index in current:
817 if index not in new_profile:
818 removinglist.append(index)
819 self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
820 self.Manager.BufferCurrentNode()
821 self.RefreshBufferState()
822 self.RefreshCurrentIndexList()
825 def GetProfileCallBack(self, text):
826 def ProfileCallBack(event):
827 self.Manager.AddSpecificEntryToCurrent(text)
828 self.RefreshBufferState()
829 self.RefreshCurrentIndexList()
831 return ProfileCallBack
833 #-------------------------------------------------------------------------------
834 # Edit Node informations function
835 #-------------------------------------------------------------------------------
837 def OnNodeInfosMenu(self, event):
838 dialog = NodeInfosDialog(self)
839 name, id, type, description = self.Manager.GetCurrentNodeInfos()
840 dialog.SetValues(name, id, type, description)
841 if dialog.ShowModal() == wx.ID_OK:
842 name, id, type, description = dialog.GetValues()
843 self.Manager.SetCurrentNodeInfos(name, id, type, description)
844 self.RefreshBufferState()
845 self.RefreshProfileMenu()
846 selected = self.FileOpened.GetSelection()
848 window = self.FileOpened.GetPage(selected)
849 window.RefreshTable()
853 #-------------------------------------------------------------------------------
854 # Add User Types and Variables
855 #-------------------------------------------------------------------------------
857 def AddMapVariable(self):
858 index = self.Manager.GetCurrentNextMapIndex()
860 dialog = MapVariableDialog(self)
861 dialog.SetIndex(index)
862 if dialog.ShowModal() == wx.ID_OK:
863 index, name, struct, number = dialog.GetValues()
864 result = self.Manager.AddMapVariableToCurrent(index, name, struct, number)
865 if type(result) != StringType:
866 self.RefreshBufferState()
867 self.RefreshCurrentIndexList()
869 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
874 message = wx.MessageDialog(self, result, "No map variable index left!", wx.OK|wx.ICON_ERROR)
878 def AddUserType(self):
879 dialog = UserTypeDialog(self)
880 dialog.SetTypeList(self.Manager.GetCustomisableTypes())
881 if dialog.ShowModal() == wx.ID_OK:
882 type, min, max, length = dialog.GetValues()
883 result = self.Manager.AddUserTypeToCurrent(type, min, max, length)
885 self.RefreshBufferState()
886 self.RefreshCurrentIndexList()
888 message = wx.MessageDialog(self, result, "Error", wx.OK|wx.ICON_ERROR)
894 #-------------------------------------------------------------------------------
896 #-------------------------------------------------------------------------------
898 Max_Traceback_List_Size = 20
900 def Display_Exception_Dialog(e_type,e_value,e_tb):
902 for i,line in enumerate(traceback.extract_tb(e_tb)):
903 trcbck = " " + str(i+1) + ". "
904 if line[0].find(os.getcwd()) == -1:
905 trcbck += "file : " + str(line[0]) + ", "
907 trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ", "
908 trcbck += "line : " + str(line[1]) + ", " + "function : " + str(line[2])
909 trcbck_lst.append(trcbck)
912 cap = wx.Window_GetCapture()
916 dlg = wx.SingleChoiceDialog(None,
920 Click on OK for saving an error report.
922 Please contact LOLITech at:
924 bugs_objdictedit@lolitech.fr
929 str(e_type) + " : " + str(e_value),
933 res = (dlg.ShowModal() == wx.ID_OK)
939 def Display_Error_Dialog(e_value):
940 message = wx.MessageDialog(None, str(e_value), "Error", wx.OK|wx.ICON_ERROR)
944 def get_last_traceback(tb):
950 def format_namespace(d, indent=' '):
951 return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
954 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
956 def AddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
958 def handle_exception(e_type, e_value, e_traceback):
959 traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
960 last_tb = get_last_traceback(e_traceback)
961 ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
962 if str(e_value).startswith("!!!"):
963 Display_Error_Dialog(e_value)
964 elif ex not in ignored_exceptions:
965 ignored_exceptions.append(ex)
966 result = Display_Exception_Dialog(e_type,e_value,e_traceback)
969 'app-title' : wx.GetApp().GetAppName(), # app_title
970 'app-version' : app_version,
971 'wx-version' : wx.VERSION_STRING,
972 'wx-platform' : wx.Platform,
973 'python-version' : platform.python_version(), #sys.version.split()[0],
974 'platform' : platform.platform(),
977 'date' : time.ctime(),
981 info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
982 last_tb = get_last_traceback(e_traceback)
983 exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
984 info['locals'] = format_namespace(exception_locals)
985 if 'self' in exception_locals:
986 info['self'] = format_namespace(exception_locals['self'].__dict__)
988 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
992 output.write(a+":\n"+str(info[a])+"\n\n")
994 #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
995 sys.excepthook = handle_exception
997 if __name__ == '__main__':
999 print "\nUsage of objdictedit.py :"
1000 print "\n %s [Filepath, ...]\n"%sys.argv[0]
1003 opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
1004 except getopt.GetoptError:
1005 # print help information and exit:
1010 if o in ("-h", "--help"):
1014 app = wx.PySimpleApp()
1015 wx.InitAllImageHandlers()
1017 # Install a exception handle for bug reports
1018 AddExceptHook(os.getcwd(),__version__)
1020 frame = objdictedit(None, args)