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 *
27 from wx.lib.anchors import LayoutAnchors
31 import os, re, platform, sys, time, traceback, getopt
33 __version__ = "$Revision: 1.5 $"
35 from nodelist import *
36 from nodemanager import *
37 from subindextable import *
38 from commondialogs import *
39 from doc_index.DS301_index import *
42 return networkedit(parent)
45 print "\nUsage of networkedit.py :"
46 print "\n %s [Projectpath]\n"%sys.argv[0]
49 opts, args = getopt.getopt(sys.argv[1:], "h", ["help"])
50 except getopt.GetoptError:
51 # print help information and exit:
56 if o in ("-h", "--help"):
69 if os.path.isfile(os.path.join(path, "networkedit.py")):
70 ScriptDirectory = path
73 from wxPython.html import *
75 wxEVT_HTML_URL_CLICK = wxNewId()
77 def EVT_HTML_URL_CLICK(win, func):
78 win.Connect(-1, -1, wxEVT_HTML_URL_CLICK, func)
80 class wxHtmlWindowUrlClick(wxPyEvent):
81 def __init__(self, linkinfo):
82 wxPyEvent.__init__(self)
83 self.SetEventType(wxEVT_HTML_URL_CLICK)
84 self.linkinfo = (linkinfo.GetHref(), linkinfo.GetTarget())
86 class wxUrlClickHtmlWindow(wxHtmlWindow):
87 """ HTML window that generates and OnLinkClicked event.
89 Use this to avoid having to override HTMLWindow
91 def OnLinkClicked(self, linkinfo):
92 wxPostEvent(self, wxHtmlWindowUrlClick(linkinfo))
94 #-------------------------------------------------------------------------------
96 #-------------------------------------------------------------------------------
98 [wxID_HTMLFRAME, wxID_HTMLFRAMEHTMLCONTENT] = [wx.NewId() for _init_ctrls in range(2)]
100 class HtmlFrame(wx.Frame):
101 def _init_ctrls(self, prnt):
102 # generated method, don't edit
103 wx.Frame.__init__(self, id=wxID_HTMLFRAME, name='HtmlFrame',
104 parent=prnt, pos=wx.Point(320, 231), size=wx.Size(853, 616),
105 style=wx.DEFAULT_FRAME_STYLE, title='')
106 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_HTMLFRAME)
108 self.HtmlContent = wxUrlClickHtmlWindow(id=wxID_HTMLFRAMEHTMLCONTENT,
109 name='HtmlContent', parent=self, pos=wx.Point(0, 0),
110 size=wx.Size(-1, -1), style=wxHW_SCROLLBAR_AUTO|wxHW_NO_SELECTION)
111 EVT_HTML_URL_CLICK(self.HtmlContent, self.OnLinkClick)
113 def __init__(self, parent, opened):
114 self._init_ctrls(parent)
115 self.HtmlFrameOpened = opened
117 def SetHtmlCode(self, htmlcode):
118 self.HtmlContent.SetPage(htmlcode)
120 def SetHtmlPage(self, htmlpage):
121 self.HtmlContent.LoadPage(htmlpage)
123 def OnCloseFrame(self, event):
124 self.HtmlFrameOpened.remove(self.GetTitle())
127 def OnLinkClick(self, event):
128 url = event.linkinfo[0]
132 wxMessageBox('Please point your browser at: %s' % url)
141 [wxID_NETWORKEDIT, wxID_NETWORKEDITNETWORKNODES,
142 wxID_NETWORKEDITHELPBAR,
143 ] = [wx.NewId() for _init_ctrls in range(3)]
145 [wxID_NETWORKEDITADDMENUITEMS0, wxID_NETWORKEDITADDMENUITEMS1,
146 wxID_NETWORKEDITADDMENUITEMS2, wxID_NETWORKEDITADDMENUITEMS3,
147 wxID_NETWORKEDITADDMENUITEMS4, wxID_NETWORKEDITADDMENUITEMS5,
148 ] = [wx.NewId() for _init_coll_AddMenu_Items in range(6)]
150 [wxID_NETWORKEDITFILEMENUITEMS0, wxID_NETWORKEDITFILEMENUITEMS1,
151 wxID_NETWORKEDITFILEMENUITEMS2, wxID_NETWORKEDITFILEMENUITEMS4,
152 wxID_NETWORKEDITFILEMENUITEMS5, wxID_NETWORKEDITFILEMENUITEMS6,
153 ] = [wx.NewId() for _init_coll_FileMenu_Items in range(6)]
155 [wxID_NETWORKEDITNETWORKMENUITEMS0, wxID_NETWORKEDITNETWORKMENUITEMS1,
156 wxID_NETWORKEDITNETWORKMENUITEMS3,
157 ] = [wx.NewId() for _init_coll_AddMenu_Items in range(3)]
160 [wxID_NETWORKEDITEDITMENUITEMS0, wxID_NETWORKEDITEDITMENUITEMS1,
161 wxID_NETWORKEDITEDITMENUITEMS2, wxID_NETWORKEDITEDITMENUITEMS4,
162 wxID_NETWORKEDITEDITMENUITEMS6, wxID_NETWORKEDITEDITMENUITEMS7,
163 wxID_NETWORKEDITEDITMENUITEMS8,
164 ] = [wx.NewId() for _init_coll_EditMenu_Items in range(7)]
166 [wxID_NETWORKEDITHELPMENUITEMS0, wxID_NETWORKEDITHELPMENUITEMS1,
167 wxID_NETWORKEDITHELPMENUITEMS2,
168 ] = [wx.NewId() for _init_coll_HelpMenu_Items in range(3)]
170 class networkedit(wx.Frame):
171 def _init_coll_menuBar1_Menus(self, parent):
172 # generated method, don't edit
175 parent.Append(menu=self.FileMenu, title='File')
176 parent.Append(menu=self.NetworkMenu, title='Network')
177 parent.Append(menu=self.EditMenu, title='Edit')
178 parent.Append(menu=self.AddMenu, title='Add')
179 parent.Append(menu=self.HelpMenu, title='Help')
181 def _init_coll_EditMenu_Items(self, parent):
182 # generated method, don't edit
184 parent.Append(help='', id=wxID_NETWORKEDITEDITMENUITEMS4,
185 kind=wx.ITEM_NORMAL, text='Refresh\tCTRL+R')
186 parent.AppendSeparator()
187 parent.Append(help='', id=wxID_NETWORKEDITEDITMENUITEMS1,
188 kind=wx.ITEM_NORMAL, text='Undo\tCTRL+Z')
189 parent.Append(help='', id=wxID_NETWORKEDITEDITMENUITEMS0,
190 kind=wx.ITEM_NORMAL, text='Redo\tCTRL+Y')
191 parent.AppendSeparator()
192 parent.Append(help='', id=wxID_NETWORKEDITEDITMENUITEMS6,
193 kind=wx.ITEM_NORMAL, text='Node infos')
194 parent.Append(help='', id=wxID_NETWORKEDITEDITMENUITEMS2,
195 kind=wx.ITEM_NORMAL, text='DS-301 Profile')
196 parent.Append(help='', id=wxID_NETWORKEDITEDITMENUITEMS8,
197 kind=wx.ITEM_NORMAL, text='DS-302 Profile')
198 parent.Append(help='', id=wxID_NETWORKEDITEDITMENUITEMS7,
199 kind=wx.ITEM_NORMAL, text='Other Profile')
200 self.Bind(wx.EVT_MENU, self.OnUndoMenu,
201 id=wxID_NETWORKEDITEDITMENUITEMS1)
202 self.Bind(wx.EVT_MENU, self.OnRedoMenu,
203 id=wxID_NETWORKEDITEDITMENUITEMS0)
204 self.Bind(wx.EVT_MENU, self.OnCommunicationMenu,
205 id=wxID_NETWORKEDITEDITMENUITEMS2)
206 self.Bind(wx.EVT_MENU, self.OnRefreshMenu,
207 id=wxID_NETWORKEDITEDITMENUITEMS4)
208 self.Bind(wx.EVT_MENU, self.OnNodeInfosMenu,
209 id=wxID_NETWORKEDITEDITMENUITEMS6)
210 self.Bind(wx.EVT_MENU, self.OnEditProfileMenu,
211 id=wxID_NETWORKEDITEDITMENUITEMS7)
212 self.Bind(wx.EVT_MENU, self.OnOtherCommunicationMenu,
213 id=wxID_NETWORKEDITEDITMENUITEMS8)
215 def _init_coll_HelpMenu_Items(self, parent):
216 # generated method, don't edit
218 parent.Append(help='', id=wxID_NETWORKEDITHELPMENUITEMS0,
219 kind=wx.ITEM_NORMAL, text='DS-301 Standard\tF1')
220 self.Bind(wx.EVT_MENU, self.OnHelpDS301Menu,
221 id=wxID_NETWORKEDITHELPMENUITEMS0)
222 parent.Append(help='', id=wxID_NETWORKEDITHELPMENUITEMS1,
223 kind=wx.ITEM_NORMAL, text='CAN Festival Docs\tF2')
224 self.Bind(wx.EVT_MENU, self.OnHelpCANFestivalMenu,
225 id=wxID_NETWORKEDITHELPMENUITEMS1)
226 if Html_Window and self.ModeSolo:
227 parent.Append(help='', id=wxID_NETWORKEDITHELPMENUITEMS2,
228 kind=wx.ITEM_NORMAL, text='About')
229 self.Bind(wx.EVT_MENU, self.OnAboutMenu,
230 id=wxID_NETWORKEDITHELPMENUITEMS2)
232 def _init_coll_FileMenu_Items(self, parent):
233 # generated method, don't edit
235 parent.Append(help='', id=wxID_NETWORKEDITFILEMENUITEMS5,
236 kind=wx.ITEM_NORMAL, text='New\tCTRL+N')
237 parent.Append(help='', id=wxID_NETWORKEDITFILEMENUITEMS0,
238 kind=wx.ITEM_NORMAL, text='Open\tCTRL+O')
239 parent.Append(help='', id=wxID_NETWORKEDITFILEMENUITEMS1,
240 kind=wx.ITEM_NORMAL, text='Save\tCTRL+S')
241 parent.Append(help='', id=wxID_NETWORKEDITFILEMENUITEMS2,
242 kind=wx.ITEM_NORMAL, text='Close\tCTRL+W')
243 parent.AppendSeparator()
244 parent.Append(help='', id=wxID_NETWORKEDITFILEMENUITEMS4,
245 kind=wx.ITEM_NORMAL, text='Exit')
246 self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu,
247 id=wxID_NETWORKEDITFILEMENUITEMS0)
248 self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu,
249 id=wxID_NETWORKEDITFILEMENUITEMS1)
250 self.Bind(wx.EVT_MENU, self.OnCloseProjectMenu,
251 id=wxID_NETWORKEDITFILEMENUITEMS2)
252 self.Bind(wx.EVT_MENU, self.OnQuitMenu,
253 id=wxID_NETWORKEDITFILEMENUITEMS4)
254 self.Bind(wx.EVT_MENU, self.OnNewProjectMenu,
255 id=wxID_NETWORKEDITFILEMENUITEMS5)
257 def _init_coll_NetworkMenu_Items(self, parent):
258 # generated method, don't edit
260 parent.Append(help='', id=wxID_NETWORKEDITNETWORKMENUITEMS0,
261 kind=wx.ITEM_NORMAL, text='Add Slave Node')
262 parent.Append(help='', id=wxID_NETWORKEDITNETWORKMENUITEMS1,
263 kind=wx.ITEM_NORMAL, text='Remove Slave Node')
264 parent.AppendSeparator()
265 parent.Append(help='', id=wxID_NETWORKEDITNETWORKMENUITEMS3,
266 kind=wx.ITEM_NORMAL, text='Build Master Dictionary')
267 self.Bind(wx.EVT_MENU, self.OnAddSlaveMenu,
268 id=wxID_NETWORKEDITNETWORKMENUITEMS0)
269 self.Bind(wx.EVT_MENU, self.OnRemoveSlaveMenu,
270 id=wxID_NETWORKEDITNETWORKMENUITEMS1)
271 ## self.Bind(wx.EVT_MENU, self.OnBuildMasterMenu,
272 ## id=wxID_NETWORKEDITNETWORKMENUITEMS3)
274 def _init_coll_AddMenu_Items(self, parent):
275 # generated method, don't edit
277 parent.Append(help='', id=wxID_NETWORKEDITADDMENUITEMS0,
278 kind=wx.ITEM_NORMAL, text='SDO Server')
279 parent.Append(help='', id=wxID_NETWORKEDITADDMENUITEMS1,
280 kind=wx.ITEM_NORMAL, text='SDO Client')
281 parent.Append(help='', id=wxID_NETWORKEDITADDMENUITEMS2,
282 kind=wx.ITEM_NORMAL, text='PDO Transmit')
283 parent.Append(help='', id=wxID_NETWORKEDITADDMENUITEMS3,
284 kind=wx.ITEM_NORMAL, text='PDO Receive')
285 parent.Append(help='', id=wxID_NETWORKEDITADDMENUITEMS4,
286 kind=wx.ITEM_NORMAL, text='Map Variable')
287 parent.Append(help='', id=wxID_NETWORKEDITADDMENUITEMS5,
288 kind=wx.ITEM_NORMAL, text='User Type')
289 self.Bind(wx.EVT_MENU, self.OnAddSDOServerMenu,
290 id=wxID_NETWORKEDITADDMENUITEMS0)
291 self.Bind(wx.EVT_MENU, self.OnAddSDOClientMenu,
292 id=wxID_NETWORKEDITADDMENUITEMS1)
293 self.Bind(wx.EVT_MENU, self.OnAddPDOTransmitMenu,
294 id=wxID_NETWORKEDITADDMENUITEMS2)
295 self.Bind(wx.EVT_MENU, self.OnAddPDOReceiveMenu,
296 id=wxID_NETWORKEDITADDMENUITEMS3)
297 self.Bind(wx.EVT_MENU, self.OnAddMapVariableMenu,
298 id=wxID_NETWORKEDITADDMENUITEMS4)
299 self.Bind(wx.EVT_MENU, self.OnAddUserTypeMenu,
300 id=wxID_NETWORKEDITADDMENUITEMS5)
302 def _init_coll_HelpBar_Fields(self, parent):
303 # generated method, don't edit
304 parent.SetFieldsCount(3)
306 parent.SetStatusText(number=0, text='')
307 parent.SetStatusText(number=1, text='')
308 parent.SetStatusText(number=2, text='')
310 parent.SetStatusWidths([100, 110, -1])
312 def _init_utils(self):
313 # generated method, don't edit
314 self.menuBar1 = wx.MenuBar()
315 self.menuBar1.SetEvtHandlerEnabled(True)
318 self.FileMenu = wx.Menu(title='')
320 self.NetworkMenu = wx.Menu(title='')
322 self.EditMenu = wx.Menu(title='')
324 self.AddMenu = wx.Menu(title='')
326 self.HelpMenu = wx.Menu(title='')
328 self._init_coll_menuBar1_Menus(self.menuBar1)
330 self._init_coll_FileMenu_Items(self.FileMenu)
331 self._init_coll_NetworkMenu_Items(self.NetworkMenu)
332 self._init_coll_EditMenu_Items(self.EditMenu)
333 self._init_coll_AddMenu_Items(self.AddMenu)
334 self._init_coll_HelpMenu_Items(self.HelpMenu)
336 def _init_ctrls(self, prnt):
337 # generated method, don't edit
338 wx.Frame.__init__(self, id=wxID_NETWORKEDIT, name='networkedit',
339 parent=prnt, pos=wx.Point(149, 178), size=wx.Size(1000, 700),
340 style=wx.DEFAULT_FRAME_STYLE, title='Networkedit')
342 self.SetClientSize(wx.Size(1000, 700))
343 self.SetMenuBar(self.menuBar1)
344 self.Bind(wx.EVT_CLOSE, self.OnCloseFrame, id=wxID_NETWORKEDIT)
346 self.NetworkNodes = wx.Notebook(id=wxID_NETWORKEDITNETWORKNODES,
347 name='NetworkNodes', parent=self, pos=wx.Point(0, 0),
348 size=wx.Size(0, 0), style=wxNB_LEFT)
349 self.NetworkNodes.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
350 self.OnNodeSelectedChanged, id=wxID_NETWORKEDITNETWORKNODES)
352 self.HelpBar = wx.StatusBar(id=wxID_NETWORKEDITHELPBAR, name='HelpBar',
353 parent=self, style=wxST_SIZEGRIP)
354 self._init_coll_HelpBar_Fields(self.HelpBar)
355 self.SetStatusBar(self.HelpBar)
357 def __init__(self, parent, nodelist = None):
358 self.ModeSolo = nodelist == None
359 self._init_ctrls(parent)
361 self.HtmlFrameOpened = []
365 self.Manager = NodeManager(ScriptDirectory)
367 self.NodeList = NodeList(self.Manager)
368 result = self.NodeList.LoadProject(projectOpen)
370 self.RefreshNetworkNodes()
374 self.NodeList = nodelist
375 self.Manager = self.NodeList.GetManager()
376 self.NodeList.SetCurrentSelected(0)
377 self.RefreshNetworkNodes()
378 self.RefreshProfileMenu()
380 self.RefreshBufferState()
382 self.RefreshMainMenu()
384 def SetBusId(self, bus_id):
390 def GetCurrentNodeId(self):
391 selected = self.NetworkNodes.GetSelection()
392 # At init selected = -1
394 window = self.NetworkNodes.GetPage(selected)
395 return window.GetIndex()
399 def OnCloseFrame(self, event):
400 if not self.ModeSolo:
401 self.Parent.CloseEditor(self.BusId)
404 def GetNoteBook(self):
405 return self.NetworkNodes
407 def OnQuitMenu(self, event):
411 def OnAddSDOServerMenu(self, event):
412 self.Manager.AddSDOServerToCurrent()
413 self.RefreshBufferState()
414 self.RefreshCurrentIndexList()
417 def OnAddSDOClientMenu(self, event):
418 self.Manager.AddSDOClientToCurrent()
419 self.RefreshBufferState()
420 self.RefreshCurrentIndexList()
423 def OnAddPDOTransmitMenu(self, event):
424 self.Manager.AddPDOTransmitToCurrent()
425 self.RefreshBufferState()
426 self.RefreshCurrentIndexList()
429 def OnAddPDOReceiveMenu(self, event):
430 self.Manager.AddPDOReceiveToCurrent()
431 self.RefreshBufferState()
432 self.RefreshCurrentIndexList()
435 def OnAddMapVariableMenu(self, event):
436 self.AddMapVariable()
439 def OnAddUserTypeMenu(self, event):
443 def OnNodeSelectedChanged(self, event):
444 selected = event.GetSelection()
445 # At init selected = -1
447 window = self.NetworkNodes.GetPage(selected)
448 self.NodeList.SetCurrentSelected(window.GetIndex())
449 self.RefreshMainMenu()
450 self.RefreshStatusBar()
453 #-------------------------------------------------------------------------------
454 # Load and Save Funtions
455 #-------------------------------------------------------------------------------
457 def OnNewProjectMenu(self, event):
459 defaultpath = os.path.dirname(self.NodeList.GetRoot())
461 defaultpath = os.getcwd()
462 dialog = wxDirDialog(self , "Choose a project", defaultpath, wxDD_NEW_DIR_BUTTON)
463 if dialog.ShowModal() == wxID_OK:
464 projectpath = dialog.GetPath()
465 if os.path.isdir(projectpath) and len(os.listdir(projectpath)) == 0:
466 os.mkdir(os.path.join(projectpath, "eds"))
467 manager = NodeManager(ScriptDirectory)
468 nodelist = NodeList(manager)
469 result = nodelist.LoadProject(projectpath)
471 self.Manager = manager
472 self.NodeList = nodelist
473 self.NodeList.SetCurrentSelected(0)
475 self.RefreshNetworkNodes()
476 self.RefreshBufferState()
478 self.RefreshProfileMenu()
479 self.RefreshMainMenu()
481 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
486 def OnOpenProjectMenu(self, event):
488 defaultpath = os.path.dirname(self.NodeList.GetRoot())
490 defaultpath = os.getcwd()
491 dialog = wxDirDialog(self , "Choose a project", defaultpath, 0)
492 if dialog.ShowModal() == wxID_OK:
493 projectpath = dialog.GetPath()
494 if os.path.isdir(projectpath):
495 manager = NodeManager(ScriptDirectory)
496 nodelist = NodeList(manager)
497 result = nodelist.LoadProject(projectpath)
499 self.Manager = manager
500 self.NodeList = nodelist
501 self.NodeList.SetCurrentSelected(0)
503 self.RefreshNetworkNodes()
504 self.RefreshBufferState()
506 self.RefreshProfileMenu()
507 self.RefreshMainMenu()
509 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
515 def OnSaveProjectMenu(self, event):
516 result = self.NodeList.SaveProject()
518 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
523 def OnCloseProjectMenu(self, event):
525 if self.NodeList.HasChanged():
526 dialog = wxMessageDialog(self, "There are changes, do you want to save?", "Close Project", wxYES_NO|wxCANCEL|wxICON_QUESTION)
527 answer = dialog.ShowModal()
529 if answer == wxID_YES:
530 result = self.NodeList.SaveProject()
532 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
535 elif answer == wxID_NO:
536 self.NodeList.ForceChanged(False)
537 if not self.NodeList.HasChanged():
540 self.RefreshNetworkNodes()
542 self.RefreshMainMenu()
545 #-------------------------------------------------------------------------------
546 # Slave Nodes Management
547 #-------------------------------------------------------------------------------
549 def OnAddSlaveMenu(self, event):
550 dialog = AddSlaveDialog(self)
551 dialog.SetNodeList(self.NodeList)
552 if dialog.ShowModal() == wxID_OK:
553 values = dialog.GetValues()
554 result = self.NodeList.AddSlaveNode(values["slaveName"], values["slaveNodeID"], values["edsFile"])
556 new_editingpanel = EditingPanel(self, self.NodeList, False)
557 new_editingpanel.SetIndex(values["slaveNodeID"])
558 idx = self.NodeList.GetOrderNumber(values["slaveNodeID"])
559 self.NetworkNodes.InsertPage(idx, new_editingpanel, "")
560 self.NodeList.SetCurrentSelected(idx)
561 self.NetworkNodes.SetSelection(idx)
562 self.RefreshBufferState()
564 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
570 def OnRemoveSlaveMenu(self, event):
571 slavenames = self.NodeList.GetSlaveNames()
572 slaveids = self.NodeList.GetSlaveIDs()
573 dialog = wxSingleChoiceDialog(self, "Choose a slave to remove", "Remove slave", slavenames)
574 if dialog.ShowModal() == wxID_OK:
575 choice = dialog.GetSelection()
576 result = self.NodeList.RemoveSlaveNode(slaveids[choice])
579 current = self.NetworkNodes.GetSelection()
580 self.NetworkNodes.DeletePage(choice + 1)
581 if self.NetworkNodes.GetPageCount() > 0:
582 new_selection = min(current, self.NetworkNodes.GetPageCount() - 1)
583 self.NetworkNodes.SetSelection(new_selection)
584 if new_selection > 0:
585 self.NodeList.SetCurrentSelected(slaveids[new_selection - 1])
586 self.RefreshBufferState()
588 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
593 #-------------------------------------------------------------------------------
595 #-------------------------------------------------------------------------------
597 def RefreshTitle(self):
598 if self.NodeList != None:
599 self.SetTitle("Networkedit - %s"%self.NodeList.GetNetworkName())
601 self.SetTitle("Networkedit")
603 def OnRefreshMenu(self, event):
604 self.RefreshCurrentIndexList()
607 def RefreshCurrentIndexList(self):
608 selected = self.NetworkNodes.GetSelection()
610 window = self.NetworkNodes.GetPage(selected)
611 window.RefreshIndexList()
615 def RefreshNetworkNodes(self):
616 if self.NetworkNodes.GetPageCount() > 0:
617 self.NetworkNodes.DeleteAllPages()
619 new_editingpanel = EditingPanel(self, self.Manager)
620 new_editingpanel.SetIndex(0)
621 self.NetworkNodes.AddPage(new_editingpanel, "")
622 for idx in self.NodeList.GetSlaveIDs():
623 new_editingpanel = EditingPanel(self, self.NodeList, False)
624 new_editingpanel.SetIndex(idx)
625 self.NetworkNodes.AddPage(new_editingpanel, "")
627 def RefreshStatusBar(self):
629 window = self.NetworkNodes.GetPage(self.NetworkNodes.GetSelection())
630 selection = window.GetSelection()
632 index, subIndex = selection
633 if self.NodeList.IsCurrentEntry(index):
634 self.HelpBar.SetStatusText("Index: 0x%04X"%index, 0)
635 self.HelpBar.SetStatusText("Subindex: 0x%02X"%subIndex, 1)
636 entryinfos = self.NodeList.GetEntryInfos(index)
637 name = entryinfos["name"]
638 category = "Optional"
639 if entryinfos["need"]:
640 category = "Mandatory"
643 if entryinfos["struct"] & OD_IdenticalIndexes:
644 number = " possibly defined %d times"%entryinfos["nbmax"]
645 if entryinfos["struct"] & OD_IdenticalSubindexes:
647 elif entryinfos["struct"] & OD_MultipleSubindexes:
649 text = "%s: %s entry of struct %s%s."%(name,category,struct,number)
650 self.HelpBar.SetStatusText(text, 2)
653 self.HelpBar.SetStatusText("", i)
656 self.HelpBar.SetStatusText("", i)
658 def RefreshMainMenu(self):
660 self.NetworkMenu.Enable(wxID_NETWORKEDITNETWORKMENUITEMS3, False)
661 if self.NodeList == None:
663 self.menuBar1.EnableTop(1, False)
664 self.menuBar1.EnableTop(2, False)
665 self.menuBar1.EnableTop(3, False)
667 self.FileMenu.Enable(wxID_NETWORKEDITFILEMENUITEMS1, False)
668 self.FileMenu.Enable(wxID_NETWORKEDITFILEMENUITEMS2, False)
670 self.menuBar1.EnableTop(0, False)
671 self.menuBar1.EnableTop(1, False)
672 self.menuBar1.EnableTop(2, False)
675 self.menuBar1.EnableTop(1, True)
677 self.FileMenu.Enable(wxID_NETWORKEDITFILEMENUITEMS1, True)
678 self.FileMenu.Enable(wxID_NETWORKEDITFILEMENUITEMS2, True)
679 if self.NetworkNodes.GetSelection() == 0:
680 self.menuBar1.EnableTop(2, True)
681 self.menuBar1.EnableTop(3, True)
683 self.menuBar1.EnableTop(2, False)
684 self.menuBar1.EnableTop(3, False)
686 self.menuBar1.EnableTop(0, True)
687 if self.NetworkNodes.GetSelection() == 0:
688 self.menuBar1.EnableTop(1, True)
689 self.menuBar1.EnableTop(2, True)
691 self.menuBar1.EnableTop(1, False)
692 self.menuBar1.EnableTop(2, False)
694 def RefreshProfileMenu(self):
696 profile = self.Manager.GetCurrentProfileName()
697 edititem = self.EditMenu.FindItemById(wxID_NETWORKEDITEDITMENUITEMS7)
699 length = self.AddMenu.GetMenuItemCount()
700 for i in xrange(length-6):
701 additem = self.AddMenu.FindItemByPosition(6)
702 self.AddMenu.Delete(additem.GetId())
703 if profile not in ("None", "DS-301"):
704 edititem.SetText("%s Profile"%profile)
705 edititem.Enable(True)
706 self.AddMenu.AppendSeparator()
707 for text, indexes in self.Manager.GetCurrentSpecificMenu():
709 self.AddMenu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=text)
710 self.Bind(wx.EVT_MENU, self.GetProfileCallBack(text), id=new_id)
712 edititem.SetText("Other Profile")
713 edititem.Enable(False)
715 #-------------------------------------------------------------------------------
717 #-------------------------------------------------------------------------------
719 def RefreshBufferState(self):
721 nodeID = self.Manager.GetCurrentNodeID()
723 nodename = "0x%2.2X %s"%(nodeID, self.Manager.GetCurrentNodeName())
725 nodename = self.Manager.GetCurrentNodeName()
726 self.NetworkNodes.SetPageText(0, nodename)
727 for idx, name in enumerate(self.NodeList.GetSlaveNames()):
728 self.NetworkNodes.SetPageText(idx + 1, name)
731 def OnUndoMenu(self, event):
732 self.Manager.LoadCurrentPrevious()
733 self.RefreshCurrentIndexList()
734 self.RefreshBufferState()
737 def OnRedoMenu(self, event):
738 self.Manager.LoadCurrentNext()
739 self.RefreshCurrentIndexList()
740 self.RefreshBufferState()
743 #-------------------------------------------------------------------------------
745 #-------------------------------------------------------------------------------
747 def OnHelpDS301Menu(self, event):
749 selected = self.NetworkNodes.GetSelection()
751 window = self.NetworkNodes.GetPage(selected)
752 result = window.GetSelection()
755 index, subIndex = result
756 result = OpenPDFDocIndex(index, ScriptDirectory)
757 if type(result) == StringType:
758 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
762 result = OpenPDFDocIndex(None, ScriptDirectory)
763 if type(result) == StringType:
764 message = wxMessageDialog(self, result, "ERROR", wxOK|wxICON_ERROR)
769 def OnHelpCANFestivalMenu(self, event):
770 #self.OpenHtmlFrame("CAN Festival Reference", os.path.join(ScriptDirectory, "doc/canfestival.html"), wx.Size(1000, 600))
771 os.system("xpdf -remote CANFESTIVAL %s %d &"%(os.path.join(ScriptDirectory, "doc/manual_en.pdf"),16))
774 def OnAboutMenu(self, event):
775 self.OpenHtmlFrame("About CAN Festival", os.path.join(ScriptDirectory, "doc/about.html"), wx.Size(500, 450))
778 def OpenHtmlFrame(self, title, file, size):
779 if title not in self.HtmlFrameOpened:
780 self.HtmlFrameOpened.append(title)
781 window = HtmlFrame(self, self.HtmlFrameOpened)
782 window.SetTitle(title)
783 window.SetHtmlPage(file)
784 window.SetClientSize(size)
787 #-------------------------------------------------------------------------------
788 # Editing Profiles functions
789 #-------------------------------------------------------------------------------
791 def OnCommunicationMenu(self, event):
792 dictionary,current = self.Manager.GetCurrentCommunicationLists()
793 self.EditProfile("Edit DS-301 Profile", dictionary, current)
796 def OnOtherCommunicationMenu(self, event):
797 dictionary,current = self.Manager.GetCurrentDS302Lists()
798 self.EditProfile("Edit DS-301 Profile", dictionary, current)
801 def OnEditProfileMenu(self, event):
802 title = "Edit %s Profile"%self.Manager.GetCurrentProfileName()
803 dictionary,current = self.Manager.GetCurrentProfileLists()
804 self.EditProfile(title, dictionary, current)
807 def EditProfile(self, title, dictionary, current):
808 dialog = CommunicationDialog(self)
809 dialog.SetTitle(title)
810 dialog.SetIndexDictionary(dictionary)
811 dialog.SetCurrentList(current)
812 dialog.RefreshLists()
813 if dialog.ShowModal() == wxID_OK:
814 new_profile = dialog.GetCurrentList()
817 for index in new_profile:
818 if index not in current:
819 addinglist.append(index)
820 for index in current:
821 if index not in new_profile:
822 removinglist.append(index)
823 self.Manager.ManageEntriesOfCurrent(addinglist, removinglist)
824 self.Manager.GenerateMapList()
825 self.Manager.BufferCurrentNode()
826 self.RefreshBufferState()
827 self.RefreshCurrentIndexList()
830 #-------------------------------------------------------------------------------
831 # Edit Node informations function
832 #-------------------------------------------------------------------------------
834 def OnNodeInfosMenu(self, event):
835 dialog = NodeInfosDialog(self)
836 name, id, type, description = self.Manager.GetCurrentNodeInfos()
837 dialog.SetValues(name, id, type, description)
838 if dialog.ShowModal() == wxID_OK:
839 name, id, type, description = dialog.GetValues()
840 self.Manager.SetCurrentNodeInfos(name, id, type, description)
841 self.RefreshBufferState()
842 self.RefreshProfileMenu()
843 selected = self.NetworkNodes.GetSelection()
845 window = self.NetworkNodes.GetPage(selected)
846 window.RefreshTable()
850 #-------------------------------------------------------------------------------
851 # Add User Types and Variables
852 #-------------------------------------------------------------------------------
854 def AddMapVariable(self):
855 index = self.Manager.GetCurrentNextMapIndex()
857 dialog = MapVariableDialog(self)
858 dialog.SetIndex(index)
859 if dialog.ShowModal() == wxID_OK:
860 index, name, struct, number = dialog.GetValues()
861 result = self.Manager.AddMapVariableToCurrent(index, name, struct, number)
862 if type(result) != StringType:
863 self.RefreshBufferState()
864 self.RefreshCurrentIndexList()
866 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
871 message = wxMessageDialog(self, result, "No map variable index left!", wxOK|wxICON_ERROR)
875 def AddUserType(self):
876 dialog = UserTypeDialog(self)
877 dialog.SetTypeList(self.Manager.GetCustomisableTypes())
878 if dialog.ShowModal() == wxID_OK:
879 type, min, max, length = dialog.GetValues()
880 result = self.Manager.AddUserTypeToCurrent(type, min, max, length)
881 if not IsOfType(result, StringType):
882 self.RefreshBufferState()
883 self.RefreshCurrentIndexList()
885 message = wxMessageDialog(self, result, "Error", wxOK|wxICON_ERROR)
890 #-------------------------------------------------------------------------------
892 #-------------------------------------------------------------------------------
894 Max_Traceback_List_Size = 20
896 def Display_Exception_Dialog(e_type,e_value,e_tb):
898 for i,line in enumerate(traceback.extract_tb(e_tb)):
899 trcbck = " " + str(i+1) + ". "
900 if line[0].find(os.getcwd()) == -1:
901 trcbck += "file : " + str(line[0]) + ", "
903 trcbck += "file : " + str(line[0][len(os.getcwd()):]) + ", "
904 trcbck += "line : " + str(line[1]) + ", " + "function : " + str(line[2])
905 trcbck_lst.append(trcbck)
908 cap = wx.Window_GetCapture()
912 dlg = wx.SingleChoiceDialog(None,
916 Click on OK for saving an error report.
918 Please contact LOLITech at:
920 bugs_networkedit@lolitech.fr
925 str(e_type) + " : " + str(e_value),
929 res = (dlg.ShowModal() == wx.ID_OK)
935 def Display_Error_Dialog(e_value):
936 message = wxMessageDialog(None, str(e_value), "Error", wxOK|wxICON_ERROR)
940 def get_last_traceback(tb):
946 def format_namespace(d, indent=' '):
947 return '\n'.join(['%s%s: %s' % (indent, k, repr(v)[:10000]) for k, v in d.iteritems()])
950 ignored_exceptions = [] # a problem with a line in a module is only reported once per session
952 def wxAddExceptHook(path, app_version='[No version]'):#, ignored_exceptions=[]):
954 def handle_exception(e_type, e_value, e_traceback):
955 traceback.print_exception(e_type, e_value, e_traceback) # this is very helpful when there's an exception in the rest of this func
956 last_tb = get_last_traceback(e_traceback)
957 ex = (last_tb.tb_frame.f_code.co_filename, last_tb.tb_frame.f_lineno)
958 if str(e_value).startswith("!!!"):
959 Display_Error_Dialog(e_value)
960 elif ex not in ignored_exceptions:
961 ignored_exceptions.append(ex)
962 result = Display_Exception_Dialog(e_type,e_value,e_traceback)
965 'app-title' : wx.GetApp().GetAppName(), # app_title
966 'app-version' : app_version,
967 'wx-version' : wx.VERSION_STRING,
968 'wx-platform' : wx.Platform,
969 'python-version' : platform.python_version(), #sys.version.split()[0],
970 'platform' : platform.platform(),
973 'date' : time.ctime(),
977 info['traceback'] = ''.join(traceback.format_tb(e_traceback)) + '%s: %s' % (e_type, e_value)
978 last_tb = get_last_traceback(e_traceback)
979 exception_locals = last_tb.tb_frame.f_locals # the locals at the level of the stack trace where the exception actually occurred
980 info['locals'] = format_namespace(exception_locals)
981 if 'self' in exception_locals:
982 info['self'] = format_namespace(exception_locals['self'].__dict__)
984 output = open(path+os.sep+"bug_report_"+info['date'].replace(':','-').replace(' ','_')+".txt",'w')
988 output.write(a+":\n"+str(info[a])+"\n\n")
990 #sys.excepthook = lambda *args: wx.CallAfter(handle_exception, *args)
991 sys.excepthook = handle_exception
993 if __name__ == '__main__':
994 app = wxPySimpleApp()
995 wxInitAllImageHandlers()
997 # Install a exception handle for bug reports
998 wxAddExceptHook(os.getcwd(),__version__)
1000 frame = networkedit(None)