dialogs/ForceVariableDialog.py
branch1.1 Korean release
changeset 968 eee7625de1f7
parent 941 b6e93549de2e
child 1571 486f94a8032c
equal deleted inserted replaced
808:6e205c1f05a0 968:eee7625de1f7
       
     1 # -*- coding: utf-8 -*-
       
     2 
       
     3 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     4 #based on the plcopen standard. 
       
     5 #
       
     6 #Copyright (C) 2007: Edouard TISSERANT and Laurent BESSARD
       
     7 #
       
     8 #See COPYING file for copyrights details.
       
     9 #
       
    10 #This library is free software; you can redistribute it and/or
       
    11 #modify it under the terms of the GNU 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.
       
    14 #
       
    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 #General Public License for more details.
       
    19 #
       
    20 #You should have received a copy of the GNU 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
       
    23 
       
    24 import re
       
    25 import datetime
       
    26 
       
    27 import wx
       
    28 
       
    29 #-------------------------------------------------------------------------------
       
    30 #                                Helpers
       
    31 #-------------------------------------------------------------------------------
       
    32 
       
    33 LOCATIONDATATYPES = {"X" : ["BOOL"],
       
    34                      "B" : ["SINT", "USINT", "BYTE", "STRING"],
       
    35                      "W" : ["INT", "UINT", "WORD", "WSTRING"],
       
    36                      "D" : ["DINT", "UDINT", "REAL", "DWORD"],
       
    37                      "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} 
       
    38 
       
    39 def gen_get_function(f):
       
    40     def get_function(v):
       
    41         try:
       
    42             return f(v)
       
    43         except:
       
    44             return None
       
    45     return get_function
       
    46 
       
    47 def gen_get_string(delimiter):
       
    48     STRING_MODEL = re.compile("%(delimiter)s([^%(delimiter)s]*)%(delimiter)s$" % {"delimiter": delimiter})
       
    49     def get_string(v):
       
    50         result = STRING_MODEL.match(v)
       
    51         if result is not None:
       
    52             return result.group(1)
       
    53         return None
       
    54     return get_string
       
    55 
       
    56 getinteger = gen_get_function(int)
       
    57 getfloat = gen_get_function(float)
       
    58 getstring = gen_get_string("'")
       
    59 getwstring = gen_get_string('"')
       
    60 
       
    61 SECOND = 1000000
       
    62 MINUTE = 60 * SECOND
       
    63 HOUR = 60 * MINUTE
       
    64 DAY = 24 * HOUR
       
    65 
       
    66 IEC_TIME_MODEL = re.compile("(?:(?:T|TIME)#)?(-)?(?:(%(float)s)D_?)?(?:(%(float)s)H_?)?(?:(%(float)s)M(?!S)_?)?(?:(%(float)s)S_?)?(?:(%(float)s)MS)?$" % {"float": "[0-9]+(?:\.[0-9]+)?"})
       
    67 IEC_DATE_MODEL = re.compile("(?:(?:D|DATE)#)?([0-9]{4})-([0-9]{2})-([0-9]{2})$")
       
    68 IEC_DATETIME_MODEL = re.compile("(?:(?:DT|DATE_AND_TIME)#)?([0-9]{4})-([0-9]{2})-([0-9]{2})-([0-9]{2}):([0-9]{2}):([0-9]{2}(?:\.[0-9]+)?)$")
       
    69 IEC_TIMEOFDAY_MODEL = re.compile("(?:(?:TOD|TIME_OF_DAY)#)?([0-9]{2}):([0-9]{2}):([0-9]{2}(?:\.[0-9]+)?)$")
       
    70 
       
    71 def gettime(v):    
       
    72     result = IEC_TIME_MODEL.match(v.upper())
       
    73     if result is not None:
       
    74         negative, days, hours, minutes, seconds, milliseconds = result.groups()
       
    75         microseconds = 0
       
    76         not_null = False
       
    77         for value, factor in [(days, DAY),
       
    78                               (hours, HOUR),
       
    79                               (minutes, MINUTE),
       
    80                               (seconds, SECOND),
       
    81                               (milliseconds, 1000)]:
       
    82             if value is not None:
       
    83                 microseconds += float(value) * factor
       
    84                 not_null = True
       
    85         if not not_null:
       
    86             return None
       
    87         if negative is not None:
       
    88             microseconds = -microseconds
       
    89         return datetime.timedelta(microseconds=microseconds)
       
    90     
       
    91     else: 
       
    92         return None
       
    93 
       
    94 def getdate(v):
       
    95     result = IEC_DATE_MODEL.match(v.upper())
       
    96     if result is not None:
       
    97         year, month, day = result.groups()
       
    98         try:
       
    99             date = datetime.datetime(int(year), int(month), int(day))
       
   100         except ValueError, e:
       
   101             return None
       
   102         base_date = datetime.datetime(1970, 1, 1)
       
   103         return date - base_date
       
   104     else: 
       
   105         return None
       
   106 
       
   107 def getdatetime(v):
       
   108     result = IEC_DATETIME_MODEL.match(v.upper())
       
   109     if result is not None:
       
   110         year, month, day, hours, minutes, seconds = result.groups()
       
   111         try:
       
   112             date = datetime.datetime(int(year), int(month), int(day), int(hours), int(minutes), int(float(seconds)), int((float(seconds) * SECOND) % SECOND))
       
   113         except ValueError, e:
       
   114             return None
       
   115         base_date = datetime.datetime(1970, 1, 1)
       
   116         return date - base_date
       
   117     else: 
       
   118         return None
       
   119 
       
   120 def gettimeofday(v):
       
   121     result = IEC_TIMEOFDAY_MODEL.match(v.upper())
       
   122     if result is not None:
       
   123         hours, minutes, seconds = result.groups()
       
   124         microseconds = 0
       
   125         for value, factor in [(hours, HOUR),
       
   126                               (minutes, MINUTE),
       
   127                               (seconds, SECOND)]:
       
   128             microseconds += float(value) * factor
       
   129         return datetime.timedelta(microseconds=microseconds)
       
   130     else:
       
   131         return None
       
   132 
       
   133 GetTypeValue = {"BOOL": lambda x: {"TRUE": True, "FALSE": False, "0": False, "1": True}.get(x.upper(), None),
       
   134                 "SINT": getinteger,
       
   135                 "INT": getinteger,
       
   136                 "DINT": getinteger,
       
   137                 "LINT": getinteger,
       
   138                 "USINT": getinteger,
       
   139                 "UINT": getinteger,
       
   140                 "UDINT": getinteger,
       
   141                 "ULINT": getinteger,
       
   142                 "BYTE": getinteger,
       
   143                 "WORD": getinteger,
       
   144                 "DWORD": getinteger,
       
   145                 "LWORD": getinteger,
       
   146                 "REAL": getfloat,
       
   147                 "LREAL": getfloat,
       
   148                 "STRING": getstring,
       
   149                 "WSTRING": getwstring,
       
   150                 "TIME": gettime,
       
   151                 "DATE": getdate,
       
   152                 "DT": getdatetime,
       
   153                 "TOD": gettimeofday}
       
   154 
       
   155 #-------------------------------------------------------------------------------
       
   156 #                            Force Variable Dialog
       
   157 #-------------------------------------------------------------------------------
       
   158 
       
   159 class ForceVariableDialog(wx.TextEntryDialog):
       
   160 
       
   161     def __init__(self, parent, iec_type, defaultValue=""):
       
   162         wx.TextEntryDialog.__init__(self, parent, message = _("Forcing Variable Value"), 
       
   163                 caption = _("Please enter value for a \"%s\" variable:") % iec_type, defaultValue = defaultValue, 
       
   164                 style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition)
       
   165         
       
   166         self.IEC_Type = iec_type 
       
   167         
       
   168         self.Bind(wx.EVT_BUTTON, self.OnOK, 
       
   169               self.GetSizer().GetItem(2).GetSizer().GetItem(1).GetSizer().GetAffirmativeButton())
       
   170         
       
   171     def OnOK(self, event):
       
   172         message = None
       
   173         value = self.GetSizer().GetItem(1).GetWindow().GetValue()
       
   174         if value == "":
       
   175             message = _("You must type a value!")
       
   176         elif GetTypeValue[self.IEC_Type](value) is None:
       
   177             message = _("Invalid value \"%s\" for \"%s\" variable!") % (value, self.IEC_Type)
       
   178         if message is not None:
       
   179             dialog = wx.MessageDialog(self, message, _("Error"), wx.OK|wx.ICON_ERROR)
       
   180             dialog.ShowModal()
       
   181             dialog.Destroy()
       
   182         else:
       
   183             self.EndModal(wx.ID_OK)
       
   184         event.Skip()
       
   185 
       
   186     def GetValue(self):
       
   187         return GetTypeValue[self.IEC_Type](wx.TextEntryDialog.GetValue(self))