"Fossies" - the Fresh Open Source Software Archive

Member "spambayes-1.1a6/Outlook2000/dialogs/resources/rcparser.py" (6 Dec 2008, 13801 Bytes) of archive /windows/mail/spambayes-1.1a6.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. For more information about "rcparser.py" see the Fossies "Dox" file reference documentation.

    1 # Windows dialog .RC file parser, by Adam Walker.
    2 
    3 # This module is part of the spambayes project, which is Copyright 2003
    4 # The Python Software Foundation and is covered by the Python Software
    5 # Foundation license.
    6 __author__="Adam Walker"
    7 
    8 import sys, os, shlex
    9 import win32con
   10 #import win32gui
   11 import commctrl
   12 
   13 _controlMap = {"DEFPUSHBUTTON":0x80,
   14                "PUSHBUTTON":0x80,
   15                "Button":0x80,
   16                "GROUPBOX":0x80,
   17                "Static":0x82,
   18                "CTEXT":0x82,
   19                "RTEXT":0x82,
   20                "LTEXT":0x82,
   21                "LISTBOX":0x83,
   22                "SCROLLBAR":0x84,
   23                "COMBOBOX":0x85,
   24                "EDITTEXT":0x81,
   25                }
   26 
   27 _addDefaults = {"EDITTEXT":win32con.WS_BORDER,
   28                 "GROUPBOX":win32con.BS_GROUPBOX,
   29                 "LTEXT":win32con.SS_LEFT,
   30                 "DEFPUSHBUTTON":win32con.BS_DEFPUSHBUTTON,
   31                 "CTEXT":win32con.SS_CENTER,
   32                 "RTEXT":win32con.SS_RIGHT}
   33 
   34 defaultControlStyle = win32con.WS_CHILD | win32con.WS_VISIBLE
   35 class DialogDef:
   36     name = ""
   37     id = 0
   38     style = 0
   39     styleEx = None
   40     caption = ""
   41     font = "MS Sans Serif"
   42     fontSize = 8
   43     x = 0
   44     y = 0
   45     w = 0
   46     h = 0
   47     template = None
   48     def __init__(self, n, i):
   49         self.name = n
   50         self.id = i
   51         self.styles = []
   52         self.stylesEx = []
   53         self.controls = []
   54         #print "dialog def for ",self.name, self.id
   55     def createDialogTemplate(self):
   56         t = None
   57         self.template = [[self.caption, (self.x,self.y,self.w,self.h), self.style, self.styleEx, (self.fontSize, self.font)]]
   58         # Add the controls
   59         for control in self.controls:
   60             self.template.append(control.createDialogTemplate())
   61         return self.template
   62 
   63 class ControlDef:
   64     id = ""
   65     controlType = ""
   66     subType = ""
   67     idNum = 0
   68     style = defaultControlStyle
   69     label = ""
   70     x = 0
   71     y = 0
   72     w = 0
   73     h = 0
   74     def __init__(self):
   75         self.styles = []
   76     def toString(self):
   77         s = "<Control id:"+self.id+" controlType:"+self.controlType+" subType:"+self.subType\
   78             +" idNum:"+str(self.idNum)+" style:"+str(self.style)+" styles:"+str(self.styles)+" label:"+self.label\
   79             +" x:"+str(self.x)+" y:"+str(self.y)+" w:"+str(self.w)+" h:"+str(self.h)+">"
   80         return s
   81     def createDialogTemplate(self):
   82         ct = self.controlType
   83         if "CONTROL"==ct:
   84             ct = self.subType
   85         if ct in _addDefaults:
   86             self.style |= _addDefaults[ct]
   87         if ct in _controlMap:
   88             ct = _controlMap[ct]
   89         t = [ct, self.label, self.idNum, (self.x, self.y, self.w, self.h), self.style]
   90         #print t
   91         return t
   92 
   93 
   94 class gt_str(str):
   95     """Change a string to a gettext version of itself."""
   96     def __repr__(self):
   97         if len(self) > 0:
   98             # timeit indicates that addition is faster than interpolation
   99             # here
  100             return "_(" + super(gt_str, self).__repr__() + ")"
  101         else:
  102             return super(gt_str, self).__repr__() 
  103 
  104 
  105 class RCParser:
  106     next_id = 1001
  107     dialogs = {}
  108     _dialogs = {}
  109     debugEnabled = False;
  110     token = ""
  111 
  112     def __init__(self):
  113         self.ids = {"IDOK":1, "IDCANCEL":2, "IDC_STATIC": -1}
  114         self.names = {1:"IDOK", 2:"IDCANCEL", -1:"IDC_STATIC"}
  115         self.bitmaps = {}
  116         self.gettexted = False
  117 
  118     def debug(self, *args):
  119         if self.debugEnabled:
  120             print args
  121 
  122     def getToken(self):
  123         self.token = self.lex.get_token()
  124         self.debug("getToken returns:", self.token)
  125         if self.token=="":
  126             self.token = None
  127         return self.token
  128 
  129     def getCommaToken(self):
  130         tok = self.getToken()
  131         assert tok == ",", "Token '%s' should be a comma!" % tok
  132 
  133     def loadDialogs(self, rcFileName):
  134         """
  135         RCParser.loadDialogs(rcFileName) -> None
  136         Load the dialog information into the parser. Dialog Definations can then be accessed
  137         using the "dialogs" dictionary member (name->DialogDef). The "ids" member contains the dictionary of id->name.
  138         The "names" member contains the dictionary of name->id
  139         """
  140         hFileName = rcFileName[:-2]+"h"
  141         if not os.path.exists(hFileName):
  142             # Translated dialogs don't need their own copy of dialogs.h,
  143             # so look for one in this directory if there isn't one in the
  144             # expected place.
  145             # This will only work with Python > 2.2 and as source, but
  146             # it shouldn't ever be run by binary users, so that shoudln't
  147             # matter.
  148             hFileName = os.path.join(os.path.dirname(__file__),
  149                                      os.path.basename(hFileName))
  150         try:
  151             h = open(hFileName, "rU")
  152             self.parseH(h)
  153             h.close()
  154         except IOError:
  155             print "No .h file. ignoring."
  156         f = open(rcFileName)
  157         self.open(f)
  158         self.getToken()
  159         while self.token!=None:
  160             self.parse()
  161             self.getToken()
  162         f.close()
  163     def open(self, file):
  164         self.lex = shlex.shlex(file)
  165         self.lex.commenters = "//#"
  166 
  167     def parseH(self, file):
  168         lex = shlex.shlex(file)
  169         lex.commenters = "//"
  170         token = " "
  171         while token is not None:
  172             token = lex.get_token()
  173             if token == "" or token is None:
  174                 token = None
  175             else:
  176                 if token=='define':
  177                     n = lex.get_token()
  178                     i = int(lex.get_token())
  179                     self.ids[n] = i
  180                     if self.names.has_key(i):
  181                         # ignore AppStudio special ones.
  182                         if not n.startswith("_APS_"):
  183                             print "Duplicate id",i,"for",n,"is", self.names[i]
  184                     else:
  185                         self.names[i] = n
  186                     if self.next_id<=i:
  187                         self.next_id = i+1
  188 
  189     def parse(self):
  190         deep = 0
  191         if self.token == None:
  192             more == None
  193         elif "BEGIN" == self.token:
  194             deep = 1
  195             while deep!=0:
  196                 self.getToken()
  197                 if "BEGIN" == self.token:
  198                     deep += 1
  199                 elif "END" == self.token:
  200                     deep -= 1
  201         elif "IDD_" == self.token[:4]:
  202             possibleDlgName = self.token
  203             #print "possible dialog:", possibleDlgName
  204             self.getToken()
  205             if "DIALOG" == self.token or "DIALOGEX" == self.token:
  206                 self.dialog(possibleDlgName)
  207         elif "IDB_" == self.token[:4]:
  208             possibleBitmap = self.token
  209             self.getToken()
  210             if "BITMAP" == self.token:
  211                 self.getToken()
  212                 if self.token=="MOVEABLE":
  213                     self.getToken() # PURE
  214                     self.getToken() # bmpname
  215                 bmf = self.token[1:-1] # quotes
  216                 self.bitmaps[possibleBitmap] = bmf
  217                 print "BITMAP", possibleBitmap, bmf
  218                 #print win32gui.LoadImage(0, bmf, win32con.IMAGE_BITMAP,0,0,win32con.LR_DEFAULTCOLOR|win32con.LR_LOADFROMFILE)
  219 
  220     def addId(self, id_name):
  221         if id_name in self.ids:
  222             id = self.ids[id_name]
  223         else:
  224             id = self.next_id
  225             self.next_id += 1
  226             self.ids[id_name] = id
  227             self.names[id] = id_name
  228         return id
  229 
  230     def lang(self):
  231         while self.token[0:4]=="LANG" or self.token[0:7]=="SUBLANG" or self.token==',':
  232             self.getToken();
  233 
  234     def dialog(self, name):
  235         dlg = DialogDef(name,self.addId(name))
  236         assert len(dlg.controls)==0
  237         self._dialogs[name] = dlg
  238         extras = []
  239         self.getToken()
  240         while not self.token.isdigit():
  241             self.debug("extra", self.token)
  242             extras.append(self.token)
  243             self.getToken()
  244         dlg.x = int(self.token)
  245         self.getCommaToken()
  246         self.getToken() # number
  247         dlg.y = int(self.token)
  248         self.getCommaToken()
  249         self.getToken() # number
  250         dlg.w = int(self.token)
  251         self.getCommaToken()
  252         self.getToken() # number
  253         dlg.h = int(self.token)
  254         self.getToken()
  255         while not (self.token==None or self.token=="" or self.token=="END"):
  256             if self.token=="STYLE":
  257                 self.dialogStyle(dlg)
  258             elif self.token=="EXSTYLE":
  259                 self.dialogExStyle(dlg)
  260             elif self.token=="CAPTION":
  261                 self.dialogCaption(dlg)
  262             elif self.token=="FONT":
  263                 self.dialogFont(dlg)
  264             elif self.token=="BEGIN":
  265                 self.controls(dlg)
  266             else:
  267                 break
  268         self.dialogs[name] = dlg.createDialogTemplate()
  269 
  270     def dialogStyle(self, dlg):
  271         dlg.style, dlg.styles = self.styles( [], win32con.WS_VISIBLE | win32con.DS_SETFONT)
  272     def dialogExStyle(self, dlg):
  273         self.getToken()
  274         dlg.styleEx, dlg.stylesEx = self.styles( [], 0)
  275 
  276     def styles(self, defaults, defaultStyle):
  277         list = defaults
  278         style = defaultStyle
  279 
  280         if "STYLE"==self.token:
  281             self.getToken()
  282         i = 0
  283         Not = False
  284         while ((i%2==1 and ("|"==self.token or "NOT"==self.token)) or (i%2==0)) and not self.token==None:
  285             Not = False;
  286             if "NOT"==self.token:
  287                 Not = True
  288                 self.getToken()
  289             i += 1
  290             if self.token!="|":
  291                 if self.token in win32con.__dict__:
  292                     value = getattr(win32con,self.token)
  293                 else:
  294                     if self.token in commctrl.__dict__:
  295                         value = getattr(commctrl,self.token)
  296                     else:
  297                         value = 0
  298                 if Not:
  299                     list.append("NOT "+self.token)
  300                     self.debug("styles add Not",self.token, value)
  301                     style &= ~value
  302                 else:
  303                     list.append(self.token)
  304                     self.debug("styles add", self.token, value)
  305                     style |= value
  306             self.getToken()
  307         self.debug("style is ",style)
  308 
  309         return style, list
  310 
  311     def dialogCaption(self, dlg):
  312         if "CAPTION"==self.token:
  313             self.getToken()
  314         self.token = self.token[1:-1]
  315         self.debug("Caption is:",self.token)
  316         if self.gettexted:
  317             # gettext captions 
  318             dlg.caption = gt_str(self.token)
  319         else:
  320             dlg.caption = self.token
  321         self.getToken()
  322     def dialogFont(self, dlg):
  323         if "FONT"==self.token:
  324             self.getToken()
  325         dlg.fontSize = int(self.token)
  326         self.getCommaToken()
  327         self.getToken() # Font name
  328         dlg.font = self.token[1:-1] # it's quoted
  329         self.getToken()
  330         while "BEGIN"!=self.token:
  331             self.getToken()
  332     def controls(self, dlg):
  333         if self.token=="BEGIN": self.getToken()
  334         while self.token!="END":
  335             control = ControlDef()
  336             control.controlType = self.token;
  337             #print self.token
  338             self.getToken()
  339             if self.token[0:1]=='"':
  340                 if self.gettexted:
  341                     # gettext labels 
  342                     control.label = gt_str(self.token[1:-1])
  343                 else:
  344                     control.label = self.token[1:-1]
  345                 self.getCommaToken()
  346                 self.getToken()
  347             elif self.token.isdigit():
  348                 control.label = self.token
  349                 self.getCommaToken()
  350                 self.getToken()
  351             # msvc seems to occasionally replace "IDC_STATIC" with -1
  352             if self.token=='-':
  353                 if self.getToken() != '1':
  354                     raise RuntimeError, \
  355                           "Negative literal in rc script (other than -1) - don't know what to do"
  356                 self.token = "IDC_STATIC"
  357             control.id = self.token
  358             control.idNum = self.addId(control.id)
  359             self.getCommaToken()
  360             if control.controlType == "CONTROL":
  361                 self.getToken()
  362                 control.subType = self.token[1:-1]
  363                 # Styles
  364                 self.getCommaToken()
  365                 self.getToken()
  366                 control.style, control.styles = self.styles([], defaultControlStyle)
  367                 #self.getToken() #,
  368             # Rect
  369             control.x = int(self.getToken())
  370             self.getCommaToken()
  371             control.y = int(self.getToken())
  372             self.getCommaToken()
  373             control.w = int(self.getToken())
  374             self.getCommaToken()
  375             self.getToken()
  376             control.h = int(self.token)
  377             self.getToken()
  378             if self.token==",":
  379                 self.getToken()
  380                 control.style, control.styles = self.styles([], defaultControlStyle)
  381             #print control.toString()
  382             dlg.controls.append(control)
  383 
  384 def ParseDialogs(rc_file, gettexted=False):
  385     rcp = RCParser()
  386     rcp.gettexted = gettexted
  387     try:
  388         rcp.loadDialogs(rc_file)
  389     except:
  390         lex = getattr(rcp, "lex", None)
  391         if lex:
  392             print "ERROR parsing dialogs at line", lex.lineno
  393             print "Next 10 tokens are:"
  394             for i in range(10):
  395                 print lex.get_token(),
  396             print
  397         raise
  398 
  399     return rcp
  400 
  401 if __name__=='__main__':
  402     rc_file = os.path.join(os.path.dirname(__file__), "dialogs.rc")
  403     d = ParseDialogs(rc_file)
  404     import pprint
  405     for id, ddef in d.dialogs.items():
  406         print "Dialog %s (%d controls)" % (id, len(ddef))
  407         pprint.pprint(ddef)
  408         print