108 updateinfoThread.start() |
108 updateinfoThread.start() |
109 updateinfoThread.join(2) |
109 updateinfoThread.join(2) |
110 splash.SetText(text=updateinfo) |
110 splash.SetText(text=updateinfo) |
111 wx.Yield() |
111 wx.Yield() |
112 |
112 |
113 # Import module for internationalization |
113 from util.TranslationCatalogs import AddCatalog |
114 import gettext |
114 from util.BitmapLibrary import AddBitmapFolder, GetBitmap |
115 |
115 |
116 # Get folder containing translation files |
116 AddCatalog(os.path.join(CWD, "locale")) |
117 localedir = os.path.join(CWD,"locale") |
117 AddBitmapFolder(os.path.join(CWD, "images")) |
118 # Get the default language |
|
119 langid = wx.LANGUAGE_DEFAULT |
|
120 # Define translation domain (name of translation files) |
|
121 domain = "Beremiz" |
|
122 |
|
123 # Define locale for wx |
|
124 loc = __builtin__.__dict__.get('loc', None) |
|
125 if loc is None: |
|
126 test_loc = wx.Locale(langid) |
|
127 test_loc.AddCatalogLookupPathPrefix(localedir) |
|
128 if test_loc.AddCatalog(domain): |
|
129 loc = wx.Locale(langid) |
|
130 else: |
|
131 loc = wx.Locale(wx.LANGUAGE_ENGLISH) |
|
132 __builtin__.__dict__['loc'] = loc |
|
133 # Define location for searching translation files |
|
134 loc.AddCatalogLookupPathPrefix(localedir) |
|
135 # Define locale domain |
|
136 loc.AddCatalog(domain) |
|
137 |
|
138 def unicode_translation(message): |
|
139 return wx.GetTranslation(message).encode("utf-8") |
|
140 |
118 |
141 if __name__ == '__main__': |
119 if __name__ == '__main__': |
142 __builtin__.__dict__['_'] = wx.GetTranslation#unicode_translation |
120 # Import module for internationalization |
143 |
121 import gettext |
144 base_folder = os.path.split(sys.path[0])[0] |
122 |
145 sys.path.append(base_folder) |
123 __builtin__.__dict__['_'] = wx.GetTranslation |
146 sys.path.append(os.path.join(base_folder, "plcopeneditor")) |
124 |
147 |
|
148 from utils.BitmapLibrary import AddBitmapFolder, GetBitmap |
|
149 AddBitmapFolder(os.path.join(CWD, "images")) |
|
150 |
|
151 if __name__ == '__main__': |
|
152 # Load extensions |
125 # Load extensions |
153 for extfilename in extensions: |
126 for extfilename in extensions: |
154 extension_folder = os.path.split(os.path.realpath(extfilename))[0] |
127 extension_folder = os.path.split(os.path.realpath(extfilename))[0] |
155 sys.path.append(extension_folder) |
128 sys.path.append(extension_folder) |
|
129 AddCatalog(os.path.join(extension_folder, "locale")) |
156 AddBitmapFolder(os.path.join(extension_folder, "images")) |
130 AddBitmapFolder(os.path.join(extension_folder, "images")) |
157 execfile(extfilename, locals()) |
131 execfile(extfilename, locals()) |
158 |
132 |
159 import wx.lib.buttons, wx.lib.statbmp |
133 import wx.lib.buttons, wx.lib.statbmp |
160 import cPickle |
134 import cPickle |
161 import types, time, re, platform, time, traceback, commands |
135 import types, time, re, platform, time, traceback, commands |
162 |
136 |
163 from docutil import OpenHtmlFrame |
137 from docutil import OpenHtmlFrame |
164 from PLCOpenEditor import IDEFrame, AppendMenu, TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES |
138 from IDEFrame import IDEFrame, AppendMenu |
165 from PLCOpenEditor import EditorPanel, Viewer, TextViewer, GraphicViewer, ResourceEditor, ConfigurationEditor, DataTypeEditor |
139 from IDEFrame import TITLE, EDITORTOOLBAR, FILEMENU, EDITMENU, DISPLAYMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL, LIBRARYTREE, SCALING, PAGETITLES |
166 from PLCOpenEditor import EncodeFileSystemPath, DecodeFileSystemPath |
140 from IDEFrame import EncodeFileSystemPath, DecodeFileSystemPath |
167 from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY, ITEM_PROJECT, ITEM_RESOURCE |
141 from editors.EditorPanel import EditorPanel |
168 |
142 from editors.Viewer import Viewer |
169 from util.TextCtrlAutoComplete import TextCtrlAutoComplete |
143 from editors.TextViewer import TextViewer |
170 from util.BrowseValuesLibraryDialog import BrowseValuesLibraryDialog |
144 from editors.GraphicViewer import GraphicViewer |
|
145 from editors.ResourceEditor import ConfigurationEditor, ResourceEditor |
|
146 from editors.DataTypeEditor import DataTypeEditor |
171 from util.MiniTextControler import MiniTextControler |
147 from util.MiniTextControler import MiniTextControler |
172 from util.ProcessLogger import ProcessLogger |
148 from util.ProcessLogger import ProcessLogger |
|
149 |
|
150 from PLCControler import LOCATION_CONFNODE, LOCATION_MODULE, LOCATION_GROUP, LOCATION_VAR_INPUT, LOCATION_VAR_OUTPUT, LOCATION_VAR_MEMORY, ITEM_PROJECT, ITEM_RESOURCE |
173 from ProjectController import ProjectController, MATIEC_ERROR_MODEL, ITEM_CONFNODE |
151 from ProjectController import ProjectController, MATIEC_ERROR_MODEL, ITEM_CONFNODE |
|
152 |
174 |
153 |
175 MAX_RECENT_PROJECTS = 10 |
154 MAX_RECENT_PROJECTS = 10 |
176 |
155 |
177 class GenStaticBitmap(wx.lib.statbmp.GenStaticBitmap): |
156 class GenStaticBitmap(wx.lib.statbmp.GenStaticBitmap): |
178 """ Customized GenStaticBitmap, fix transparency redraw bug on wx2.8/win32, |
157 """ Customized GenStaticBitmap, fix transparency redraw bug on wx2.8/win32, |
214 # to prevent rapid fire on rising log panel |
193 # to prevent rapid fire on rising log panel |
215 self.rising_timer = 0 |
194 self.rising_timer = 0 |
216 self.lock = Lock() |
195 self.lock = Lock() |
217 self.YieldLock = Lock() |
196 self.YieldLock = Lock() |
218 self.RefreshLock = Lock() |
197 self.RefreshLock = Lock() |
|
198 self.TimerAccessLock = Lock() |
219 self.stack = [] |
199 self.stack = [] |
220 self.LastRefreshTime = gettime() |
200 self.LastRefreshTime = gettime() |
221 self.LastRefreshTimer = None |
201 self.LastRefreshTimer = None |
222 |
202 |
223 def write(self, s, style = None): |
203 def write(self, s, style = None): |
224 if self.lock.acquire(): |
204 if self.lock.acquire(): |
225 self.stack.append((s,style)) |
205 self.stack.append((s,style)) |
226 self.lock.release() |
206 self.lock.release() |
227 current_time = gettime() |
207 current_time = gettime() |
|
208 self.TimerAccessLock.acquire() |
228 if self.LastRefreshTimer: |
209 if self.LastRefreshTimer: |
229 self.LastRefreshTimer.cancel() |
210 self.LastRefreshTimer.cancel() |
230 self.LastRefreshTimer=None |
211 self.LastRefreshTimer=None |
|
212 self.TimerAccessLock.release() |
231 if current_time - self.LastRefreshTime > REFRESH_PERIOD and self.RefreshLock.acquire(False): |
213 if current_time - self.LastRefreshTime > REFRESH_PERIOD and self.RefreshLock.acquire(False): |
232 self._should_write() |
214 self._should_write() |
233 else: |
215 else: |
234 self.LastRefreshTimer = Timer(REFRESH_PERIOD, self._should_write) |
216 self.TimerAccessLock.acquire() |
|
217 self.LastRefreshTimer = Timer(REFRESH_PERIOD, self._timer_expired) |
235 self.LastRefreshTimer.start() |
218 self.LastRefreshTimer.start() |
|
219 self.TimerAccessLock.release() |
|
220 |
|
221 def _timer_expired(self): |
|
222 if self.RefreshLock.acquire(False): |
|
223 self._should_write() |
|
224 else: |
|
225 self.TimerAccessLock.acquire() |
|
226 self.LastRefreshTimer = Timer(REFRESH_PERIOD, self._timer_expired) |
|
227 self.LastRefreshTimer.start() |
|
228 self.TimerAccessLock.release() |
236 |
229 |
237 def _should_write(self): |
230 def _should_write(self): |
238 wx.CallAfter(self._write) |
231 wx.CallAfter(self._write) |
239 if MainThread == currentThread().ident: |
232 if MainThread == currentThread().ident: |
240 app = wx.GetApp() |
233 app = wx.GetApp() |
301 |
294 |
302 IDEFrame._init_utils(self) |
295 IDEFrame._init_utils(self) |
303 |
296 |
304 def _init_coll_FileMenu_Items(self, parent): |
297 def _init_coll_FileMenu_Items(self, parent): |
305 AppendMenu(parent, help='', id=wx.ID_NEW, |
298 AppendMenu(parent, help='', id=wx.ID_NEW, |
306 kind=wx.ITEM_NORMAL, text=_(u'New\tCTRL+N')) |
299 kind=wx.ITEM_NORMAL, text=_(u'New') + '\tCTRL+N') |
307 AppendMenu(parent, help='', id=wx.ID_OPEN, |
300 AppendMenu(parent, help='', id=wx.ID_OPEN, |
308 kind=wx.ITEM_NORMAL, text=_(u'Open\tCTRL+O')) |
301 kind=wx.ITEM_NORMAL, text=_(u'Open') + '\tCTRL+O') |
309 parent.AppendMenu(ID_FILEMENURECENTPROJECTS, _("&Recent Projects"), self.RecentProjectsMenu) |
302 parent.AppendMenu(ID_FILEMENURECENTPROJECTS, _("&Recent Projects"), self.RecentProjectsMenu) |
310 parent.AppendSeparator() |
303 parent.AppendSeparator() |
311 AppendMenu(parent, help='', id=wx.ID_SAVE, |
304 AppendMenu(parent, help='', id=wx.ID_SAVE, |
312 kind=wx.ITEM_NORMAL, text=_(u'Save\tCTRL+S')) |
305 kind=wx.ITEM_NORMAL, text=_(u'Save') + '\tCTRL+S') |
313 AppendMenu(parent, help='', id=wx.ID_SAVEAS, |
306 AppendMenu(parent, help='', id=wx.ID_SAVEAS, |
314 kind=wx.ITEM_NORMAL, text=_(u'Save as\tCTRL+SHIFT+S')) |
307 kind=wx.ITEM_NORMAL, text=_(u'Save as') + '\tCTRL+SHIFT+S') |
315 AppendMenu(parent, help='', id=wx.ID_CLOSE, |
308 AppendMenu(parent, help='', id=wx.ID_CLOSE, |
316 kind=wx.ITEM_NORMAL, text=_(u'Close Tab\tCTRL+W')) |
309 kind=wx.ITEM_NORMAL, text=_(u'Close Tab') + '\tCTRL+W') |
317 AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL, |
310 AppendMenu(parent, help='', id=wx.ID_CLOSE_ALL, |
318 kind=wx.ITEM_NORMAL, text=_(u'Close Project\tCTRL+SHIFT+W')) |
311 kind=wx.ITEM_NORMAL, text=_(u'Close Project') + '\tCTRL+SHIFT+W') |
319 parent.AppendSeparator() |
312 parent.AppendSeparator() |
320 AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP, |
313 AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP, |
321 kind=wx.ITEM_NORMAL, text=_(u'Page Setup\tCTRL+ALT+P')) |
314 kind=wx.ITEM_NORMAL, text=_(u'Page Setup') + '\tCTRL+ALT+P') |
322 AppendMenu(parent, help='', id=wx.ID_PREVIEW, |
315 AppendMenu(parent, help='', id=wx.ID_PREVIEW, |
323 kind=wx.ITEM_NORMAL, text=_(u'Preview\tCTRL+SHIFT+P')) |
316 kind=wx.ITEM_NORMAL, text=_(u'Preview') + '\tCTRL+SHIFT+P') |
324 AppendMenu(parent, help='', id=wx.ID_PRINT, |
317 AppendMenu(parent, help='', id=wx.ID_PRINT, |
325 kind=wx.ITEM_NORMAL, text=_(u'Print\tCTRL+P')) |
318 kind=wx.ITEM_NORMAL, text=_(u'Print') + '\tCTRL+P') |
326 parent.AppendSeparator() |
319 parent.AppendSeparator() |
327 AppendMenu(parent, help='', id=wx.ID_EXIT, |
320 AppendMenu(parent, help='', id=wx.ID_EXIT, |
328 kind=wx.ITEM_NORMAL, text=_(u'Quit\tCTRL+Q')) |
321 kind=wx.ITEM_NORMAL, text=_(u'Quit') + '\tCTRL+Q') |
329 |
322 |
330 self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW) |
323 self.Bind(wx.EVT_MENU, self.OnNewProjectMenu, id=wx.ID_NEW) |
331 self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN) |
324 self.Bind(wx.EVT_MENU, self.OnOpenProjectMenu, id=wx.ID_OPEN) |
332 self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE) |
325 self.Bind(wx.EVT_MENU, self.OnSaveProjectMenu, id=wx.ID_SAVE) |
333 self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS) |
326 self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS) |
497 self.local_runtime_tmpdir = tempfile.mkdtemp() |
490 self.local_runtime_tmpdir = tempfile.mkdtemp() |
498 # choose an arbitrary random port for runtime |
491 # choose an arbitrary random port for runtime |
499 self.runtime_port = int(random.random() * 1000) + 61131 |
492 self.runtime_port = int(random.random() * 1000) + 61131 |
500 # launch local runtime |
493 # launch local runtime |
501 self.local_runtime = ProcessLogger(self.Log, |
494 self.local_runtime = ProcessLogger(self.Log, |
502 "\"%s\" \"%s\" -p %s -i localhost %s %s"%(sys.executable, |
495 "\"%s\" \"%s\" -p %s -i localhost %s %s"%( |
503 Bpath("Beremiz_service.py"), |
496 sys.executable, |
504 self.runtime_port, |
497 Bpath("Beremiz_service.py"), |
505 {False : "-x 0", True :"-x 1"}[taskbaricon], |
498 self.runtime_port, |
506 self.local_runtime_tmpdir), |
499 {False : "-x 0", True :"-x 1"}[taskbaricon], |
507 no_gui=False, |
500 self.local_runtime_tmpdir), |
508 timeout=500, keyword = "working") |
501 no_gui=False, |
|
502 timeout=500, keyword = "working", |
|
503 cwd = self.local_runtime_tmpdir) |
509 self.local_runtime.spin() |
504 self.local_runtime.spin() |
510 return self.runtime_port |
505 return self.runtime_port |
511 |
506 |
512 def KillLocalRuntime(self): |
507 def KillLocalRuntime(self): |
513 if self.local_runtime is not None: |
508 if self.local_runtime is not None: |
945 |
939 |
946 if item_infos["type"] == ITEM_CONFNODE: |
940 if item_infos["type"] == ITEM_CONFNODE: |
947 confnode_menu = wx.Menu(title='') |
941 confnode_menu = wx.Menu(title='') |
948 |
942 |
949 confnode = item_infos["confnode"] |
943 confnode = item_infos["confnode"] |
950 if confnode is not None and len(confnode.CTNChildrenTypes) > 0: |
944 if confnode is not None: |
951 for name, XSDClass, help in confnode.CTNChildrenTypes: |
945 menu_items = confnode.GetContextualMenuItems() |
952 new_id = wx.NewId() |
946 if menu_items is not None: |
953 confnode_menu.Append(help=help, id=new_id, kind=wx.ITEM_NORMAL, text=name) |
947 for text, help, callback in menu_items: |
954 self.Bind(wx.EVT_MENU, self.GetAddConfNodeFunction(name, confnode), id=new_id) |
948 new_id = wx.NewId() |
|
949 confnode_menu.Append(help=help, id=new_id, kind=wx.ITEM_NORMAL, text=text) |
|
950 self.Bind(wx.EVT_MENU, callback, id=new_id) |
|
951 else: |
|
952 for name, XSDClass, help in confnode.CTNChildrenTypes: |
|
953 new_id = wx.NewId() |
|
954 confnode_menu.Append(help=help, id=new_id, kind=wx.ITEM_NORMAL, text=_("Add") + " " + name) |
|
955 self.Bind(wx.EVT_MENU, self.GetAddConfNodeFunction(name, confnode), id=new_id) |
955 |
956 |
956 new_id = wx.NewId() |
957 new_id = wx.NewId() |
957 AppendMenu(confnode_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete")) |
958 AppendMenu(confnode_menu, help='', id=new_id, kind=wx.ITEM_NORMAL, text=_("Delete")) |
958 self.Bind(wx.EVT_MENU, self.GetDeleteMenuFunction(confnode), id=new_id) |
959 self.Bind(wx.EVT_MENU, self.GetDeleteMenuFunction(confnode), id=new_id) |
959 |
960 |
1023 self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) |
1024 self._Refresh(TITLE, FILEMENU, EDITMENU, PROJECTTREE, POUINSTANCEVARIABLESPANEL) |
1024 self.EditProjectElement(ITEM_RESOURCE, tagname) |
1025 self.EditProjectElement(ITEM_RESOURCE, tagname) |
1025 |
1026 |
1026 def AddConfNode(self, ConfNodeType, confnode=None): |
1027 def AddConfNode(self, ConfNodeType, confnode=None): |
1027 if self.CTR.CheckProjectPathPerm(): |
1028 if self.CTR.CheckProjectPathPerm(): |
1028 ConfNodeName = "%s-0" % ConfNodeType |
1029 ConfNodeName = "%s_0" % ConfNodeType |
1029 if confnode is not None: |
1030 if confnode is not None: |
1030 confnode.CTNAddChild(ConfNodeName, ConfNodeType) |
1031 confnode.CTNAddChild(ConfNodeName, ConfNodeType) |
1031 else: |
1032 else: |
1032 self.CTR.CTNAddChild(ConfNodeName, ConfNodeType) |
1033 self.CTR.CTNAddChild(ConfNodeName, ConfNodeType) |
1033 self._Refresh(TITLE, FILEMENU, PROJECTTREE) |
1034 self._Refresh(TITLE, FILEMENU, PROJECTTREE) |
1041 if dialog.ShowModal() == wx.ID_YES: |
1042 if dialog.ShowModal() == wx.ID_YES: |
1042 confnode.CTNRemove() |
1043 confnode.CTNRemove() |
1043 del confnode |
1044 del confnode |
1044 self._Refresh(TITLE, FILEMENU, PROJECTTREE) |
1045 self._Refresh(TITLE, FILEMENU, PROJECTTREE) |
1045 dialog.Destroy() |
1046 dialog.Destroy() |
1046 |
1047 |
|
1048 #------------------------------------------------------------------------------- |
|
1049 # Highlights showing functions |
|
1050 #------------------------------------------------------------------------------- |
|
1051 |
|
1052 def ShowHighlight(self, infos, start, end, highlight_type): |
|
1053 config_name = self.Controler.GetProjectMainConfigurationName() |
|
1054 if config_name is not None and infos[0] == self.Controler.ComputeConfigurationName(config_name): |
|
1055 self.CTR._OpenView() |
|
1056 selected = self.TabsOpened.GetSelection() |
|
1057 if selected != -1: |
|
1058 viewer = self.TabsOpened.GetPage(selected) |
|
1059 viewer.AddHighlight(infos[1:], start, end, highlight_type) |
|
1060 else: |
|
1061 IDEFrame.ShowHighlight(self, infos, start, end, highlight_type) |
|
1062 |
1047 #------------------------------------------------------------------------------- |
1063 #------------------------------------------------------------------------------- |
1048 # Exception Handler |
1064 # Exception Handler |
1049 #------------------------------------------------------------------------------- |
1065 #------------------------------------------------------------------------------- |
1050 |
1066 |
1051 Max_Traceback_List_Size = 20 |
1067 Max_Traceback_List_Size = 20 |