GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
mcalc_builder.py
Go to the documentation of this file.
00001 """!
00002 @package modules::mcalc_builder
00003 
00004 @brief Map calculator, GUI wrapper for r.mapcalc
00005 
00006 Classes:
00007  - mcalc_builder::MapCalcFrame
00008 
00009 (C) 2008, 2011 by the GRASS Development Team
00010 
00011 This program is free software under the GNU General Public License
00012 (>=v2). Read the file COPYING that comes with GRASS for details.
00013 
00014 @author Michael Barton, Arizona State University
00015 @author Martin Landa <landa.martin gmail.com>
00016 @author Tim Michelsen (load/save expression)
00017 """
00018 
00019 import os
00020 import sys
00021 
00022 if __name__ == "__main__":
00023     sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'gui', 'wxpython'))
00024 from core import globalvar
00025 import wx
00026 
00027 import grass.script as grass
00028 
00029 from core.gcmd        import GError, RunCommand
00030 from gui_core.gselect import Select
00031 from core.settings    import UserSettings
00032 
00033 
00034 class MapCalcFrame(wx.Frame):
00035     """!Mapcalc Frame class. Calculator-style window to create and run
00036     r(3).mapcalc statements.
00037     """
00038     def __init__(self, parent, cmd, id = wx.ID_ANY,
00039                  style = wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER, **kwargs):
00040         self.parent = parent
00041         if self.parent:
00042             self.log = self.parent.GetLogWindow()
00043         else:
00044             self.log = None
00045         
00046         # grass command
00047         self.cmd = cmd
00048 
00049         if self.cmd == 'r.mapcalc':
00050             self.rast3d = False
00051             title = _('GRASS GIS Raster Map Calculator')
00052         if self.cmd == 'r3.mapcalc':
00053             self.rast3d = True
00054             title = _('GRASS GIS 3D Raster Map Calculator')
00055             
00056         wx.Frame.__init__(self, parent, id = id, title = title, **kwargs)
00057         self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
00058         
00059         self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
00060         self.CreateStatusBar()
00061         
00062         #
00063         # variables
00064         #
00065         self.heading = _('mapcalc statement')
00066         self.funct_dict = {
00067             'abs(x)':'abs()',
00068             'acos(x)':'acos()',
00069             'asin(x)':'asin()',
00070             'atan(x)':'atan()',
00071             'atan(x,y)':'atan( , )',
00072             'cos(x)':'cos()',
00073             'double(x)':'double()',
00074             'eval([x,y,...,]z)':'eval()',
00075             'exp(x)':'exp()',
00076             'exp(x,y)':'exp( , )',
00077             'float(x)':'float()',
00078             'graph(x,x1,y1[x2,y2..])':'graph( , , )',
00079             'if(x)':'if()',
00080             'if(x,a)':'if( , )',
00081             'if(x,a,b)':'if( , , )',
00082             'if(x,a,b,c)':'if( , , , )',
00083             'int(x)':'if()',
00084             'isnull(x)':'isnull()',
00085             'log(x)':'log(',
00086             'log(x,b)':'log( , )',
00087             'max(x,y[,z...])':'max( , )',
00088             'median(x,y[,z...])':'median( , )',
00089             'min(x,y[,z...])':'min( , )',
00090             'mode(x,y[,z...])':'mode( , )',
00091             'not(x)':'not()',
00092             'pow(x,y)':'pow( , )',
00093             'rand(a,b)':'rand( , )',
00094             'round(x)':'round()',
00095             'sin(x)':'sin()',
00096             'sqrt(x)':'sqrt()',
00097             'tan(x)':'tan()',
00098             'xor(x,y)':'xor( , )',
00099             'row()':'row()',
00100             'col()':'col()',
00101             'x()':'x()',
00102             'y()':'y()',
00103             'ewres()':'ewres()',
00104             'nsres()':'nsres()',
00105             'null()':'null()'
00106             }
00107         
00108         if self.rast3d:
00109             self.funct_dict['z()'] = 'z()'
00110             self.funct_dict['tbres()'] = 'tbres()'
00111             element = 'rast3d'
00112         else:
00113             element = 'cell'
00114         
00115         self.operatorBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
00116                                         label=" %s " % _('Operators'))
00117         self.operandBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
00118                                        label=" %s " % _('Operands'))
00119         self.expressBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
00120                                        label=" %s " % _('Expression'))
00121         
00122         #
00123         # Buttons
00124         #
00125         self.btn_clear = wx.Button(parent = self.panel, id = wx.ID_CLEAR)
00126         self.btn_help = wx.Button(parent = self.panel, id = wx.ID_HELP)
00127         self.btn_run = wx.Button(parent = self.panel, id = wx.ID_ANY, label = _("&Run"))
00128         self.btn_run.SetForegroundColour(wx.Colour(35, 142, 35))
00129         self.btn_run.SetDefault()
00130         self.btn_close = wx.Button(parent = self.panel, id = wx.ID_CLOSE)
00131         self.btn_save = wx.Button(parent = self.panel, id = wx.ID_SAVE)
00132         self.btn_save.SetToolTipString(_('Save expression to file'))
00133         self.btn_load = wx.Button(parent = self.panel, id = wx.ID_ANY,
00134                                   label = _("&Load"))
00135         self.btn_load.SetToolTipString(_('Load expression from file'))
00136         
00137         self.btn = dict()        
00138         self.btn['pow'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "^")
00139         self.btn['pow'].SetToolTipString(_('exponent'))
00140         self.btn['div'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "/")
00141         self.btn['div'].SetToolTipString(_('divide'))
00142         self.btn['add'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "+")
00143         self.btn['add'].SetToolTipString(_('add'))
00144         self.btn['minus'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "-")
00145         self.btn['minus'].SetToolTipString(_('subtract'))
00146         self.btn['mod'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "%")
00147         self.btn['mod'].SetToolTipString(_('modulus'))
00148         self.btn['mult'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "*")
00149         self.btn['mult'].SetToolTipString(_('multiply'))
00150 
00151         self.btn['parenl'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "(") 
00152         self.btn['parenr'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ")")
00153         self.btn['lshift'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "<<")
00154         self.btn['lshift'].SetToolTipString(_('left shift'))
00155         self.btn['rshift'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ">>")
00156         self.btn['rshift'].SetToolTipString(_('right shift'))
00157         self.btn['rshiftu'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ">>>")
00158         self.btn['rshiftu'].SetToolTipString(_('right shift (unsigned)'))
00159         self.btn['gt'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ">")
00160         self.btn['gt'].SetToolTipString(_('greater than'))
00161         self.btn['gteq'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ">=")
00162         self.btn['gteq'].SetToolTipString(_('greater than or equal to'))
00163         self.btn['lt'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "<")
00164         self.btn['lt'].SetToolTipString(_('less than'))
00165         self.btn['lteq'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "<=")
00166         self.btn['lteq'].SetToolTipString(_('less than or equal to'))
00167         self.btn['eq'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "==")
00168         self.btn['eq'].SetToolTipString(_('equal to'))
00169         self.btn['noteq'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "!=")
00170         self.btn['noteq'].SetToolTipString(_('not equal to'))
00171 
00172         self.btn['compl'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "~")
00173         self.btn['compl'].SetToolTipString(_('one\'s complement'))
00174         self.btn['not'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "!")
00175         self.btn['not'].SetToolTipString(_('NOT'))
00176         self.btn['andbit'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = '&&')
00177         self.btn['andbit'].SetToolTipString(_('bitwise AND'))
00178         self.btn['orbit'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "|")
00179         self.btn['orbit'].SetToolTipString(_('bitwise OR'))
00180         self.btn['and'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "&&&&")
00181         self.btn['and'].SetToolTipString(_('logical AND'))
00182         self.btn['andnull'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "&&&&&&")
00183         self.btn['andnull'].SetToolTipString(_('logical AND (ignores NULLs)'))
00184         self.btn['or'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "||")
00185         self.btn['or'].SetToolTipString(_('logical OR'))
00186         self.btn['ornull'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "|||")
00187         self.btn['ornull'].SetToolTipString(_('logical OR (ignores NULLs)'))
00188         self.btn['cond'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "a ? b : c") 
00189         self.btn['cond'].SetToolTipString(_('conditional'))
00190         
00191         #
00192         # Text area
00193         #
00194         self.text_mcalc = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY, size = (-1, 75),
00195                                       style = wx.TE_MULTILINE)
00196         wx.CallAfter(self.text_mcalc.SetFocus)
00197         
00198         #
00199         # Map and function insertion text and ComboBoxes
00200         self.newmaplabel = wx.StaticText(parent = self.panel, id = wx.ID_ANY)
00201         if self.rast3d:
00202             self.newmaplabel.SetLabel(_('Name for new 3D raster map to create'))
00203         else:
00204             self.newmaplabel.SetLabel(_('Name for new raster map to create'))
00205         self.newmaptxt = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY, size=(250, -1))
00206         self.mapsellabel = wx.StaticText(parent = self.panel, id = wx.ID_ANY)
00207         if self.rast3d:
00208             self.mapsellabel.SetLabel(_('Insert existing 3D raster map'))
00209         else:
00210             self.mapsellabel.SetLabel(_('Insert existing raster map'))
00211         self.mapselect = Select(parent = self.panel, id = wx.ID_ANY, size = (250, -1),
00212                                 type = element, multiple = False)
00213         self.functlabel = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
00214                                         label = _('Insert mapcalc function'))
00215         self.function = wx.ComboBox(parent = self.panel, id = wx.ID_ANY, 
00216                                     size = (250, -1), choices = sorted(self.funct_dict.keys()),
00217                                     style = wx.CB_DROPDOWN |
00218                                     wx.CB_READONLY | wx.TE_PROCESS_ENTER)
00219         
00220         self.addbox = wx.CheckBox(parent=self.panel,
00221                                   label=_('Add created raster map into layer tree'), style = wx.NO_BORDER)
00222         self.addbox.SetValue(UserSettings.Get(group='cmd', key='addNewLayer', subkey='enabled'))
00223         if not self.parent or self.parent.GetName() != 'LayerManager':
00224             self.addbox.Hide()
00225         
00226         #
00227         # Bindings
00228         #
00229         for btn in self.btn.keys():
00230             self.btn[btn].Bind(wx.EVT_BUTTON, self.AddMark)
00231         
00232         self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
00233         self.btn_clear.Bind(wx.EVT_BUTTON, self.OnClear)
00234         self.btn_run.Bind(wx.EVT_BUTTON, self.OnMCalcRun)
00235         self.btn_help.Bind(wx.EVT_BUTTON, self.OnHelp)
00236         self.btn_save.Bind(wx.EVT_BUTTON, self.OnSaveExpression)
00237         self.btn_load.Bind(wx.EVT_BUTTON, self.OnLoadExpression)
00238         
00239         self.mapselect.Bind(wx.EVT_TEXT, self.OnSelect)
00240         self.function.Bind(wx.EVT_COMBOBOX, self._return_funct)
00241         self.function.Bind(wx.EVT_TEXT_ENTER, self.OnSelect)
00242         self.newmaptxt.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
00243         self.text_mcalc.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
00244 
00245         self._layout()
00246 
00247         self.SetMinSize(self.GetBestSize())
00248     
00249     def _return_funct(self,event):
00250         i = event.GetString()
00251         self._addSomething(self.funct_dict[i])
00252     
00253     def _layout(self):
00254         sizer = wx.BoxSizer(wx.VERTICAL)
00255         
00256         controlSizer = wx.BoxSizer(wx.HORIZONTAL)
00257         operatorSizer = wx.StaticBoxSizer(self.operatorBox, wx.HORIZONTAL)
00258 
00259         buttonSizer1 = wx.GridBagSizer(5, 1)
00260         buttonSizer1.Add(item = self.btn['add'], pos = (0,0))
00261         buttonSizer1.Add(item = self.btn['minus'], pos = (0,1))
00262         buttonSizer1.Add(item = self.btn['mod'], pos = (5,0))
00263         buttonSizer1.Add(item = self.btn['mult'], pos = (1,0))
00264         buttonSizer1.Add(item = self.btn['div'], pos = (1,1))
00265         buttonSizer1.Add(item = self.btn['pow'], pos = (5,1))
00266         buttonSizer1.Add(item = self.btn['gt'], pos = (2,0))
00267         buttonSizer1.Add(item = self.btn['gteq'], pos = (2,1))
00268         buttonSizer1.Add(item = self.btn['eq'], pos = (4,0))
00269         buttonSizer1.Add(item = self.btn['lt'], pos = (3,0))
00270         buttonSizer1.Add(item = self.btn['lteq'], pos = (3,1))
00271         buttonSizer1.Add(item = self.btn['noteq'], pos = (4,1))
00272 
00273         buttonSizer2 = wx.GridBagSizer(5, 1)
00274         buttonSizer2.Add(item = self.btn['and'], pos = (0,0))
00275         buttonSizer2.Add(item = self.btn['andbit'], pos = (1,0))
00276         buttonSizer2.Add(item = self.btn['andnull'], pos = (2,0))
00277         buttonSizer2.Add(item = self.btn['or'], pos = (0,1))
00278         buttonSizer2.Add(item = self.btn['orbit'], pos = (1,1))
00279         buttonSizer2.Add(item = self.btn['ornull'], pos = (2,1))
00280         buttonSizer2.Add(item = self.btn['lshift'], pos = (3,0))
00281         buttonSizer2.Add(item = self.btn['rshift'], pos = (3,1))
00282         buttonSizer2.Add(item = self.btn['rshiftu'], pos = (4,0))
00283         buttonSizer2.Add(item = self.btn['cond'], pos = (5,0))
00284         buttonSizer2.Add(item = self.btn['compl'], pos = (5,1))
00285         buttonSizer2.Add(item = self.btn['not'], pos = (4,1))
00286 
00287         operandSizer = wx.StaticBoxSizer(self.operandBox, wx.HORIZONTAL)
00288         buttonSizer3 = wx.GridBagSizer(7, 1)
00289         buttonSizer3.Add(item = self.newmaplabel, pos = (0,0),
00290                          span = (1, 2), flag = wx.ALIGN_CENTER)
00291         buttonSizer3.Add(item = self.newmaptxt, pos = (1,0),
00292                          span = (1, 2))
00293         buttonSizer3.Add(item = self.functlabel, pos = (2,0),
00294                          span = (1,2), flag = wx.ALIGN_CENTER)
00295         buttonSizer3.Add(item = self.function, pos = (3,0),
00296                          span = (1,2))                         
00297         buttonSizer3.Add(item = self.mapsellabel, pos = (4,0),
00298                          span = (1,2), flag = wx.ALIGN_CENTER)
00299         buttonSizer3.Add(item = self.mapselect, pos = (5,0),
00300                          span = (1,2))
00301         threebutton = wx.GridBagSizer(1, 2)
00302         threebutton.Add(item = self.btn['parenl'], pos = (0,0),
00303                          span = (1,1), flag = wx.ALIGN_LEFT)
00304         threebutton.Add(item = self.btn['parenr'], pos = (0,1),
00305                          span = (1,1), flag = wx.ALIGN_CENTER)
00306         threebutton.Add(item = self.btn_clear, pos = (0,2),
00307                          span = (1,1), flag = wx.ALIGN_RIGHT)
00308         buttonSizer3.Add(item = threebutton, pos = (6,0),
00309                          span = (1,1), flag = wx.ALIGN_CENTER)
00310 
00311         buttonSizer4 = wx.BoxSizer(wx.HORIZONTAL)
00312         buttonSizer4.AddSpacer(10)
00313         buttonSizer4.Add(item = self.btn_load,
00314                          flag = wx.ALL, border = 5)
00315         buttonSizer4.Add(item = self.btn_save,
00316                          flag = wx.ALL, border = 5)                         
00317         buttonSizer4.AddSpacer(30)
00318         buttonSizer4.Add(item = self.btn_help,
00319                          flag = wx.ALL, border = 5)
00320         buttonSizer4.Add(item = self.btn_run,
00321                          flag = wx.ALL, border = 5)
00322         buttonSizer4.Add(item = self.btn_close,
00323                          flag = wx.ALL, border = 5)
00324         
00325         operatorSizer.Add(item = buttonSizer1, proportion = 0,
00326                           flag = wx.ALL | wx.EXPAND, border = 5)
00327         operatorSizer.Add(item = buttonSizer2, proportion = 0,
00328                           flag = wx.TOP | wx.BOTTOM | wx.RIGHT | wx.EXPAND, border = 5)
00329         
00330         operandSizer.Add(item = buttonSizer3, proportion = 0,
00331                          flag = wx.TOP | wx.BOTTOM | wx.RIGHT, border = 5)
00332         
00333         controlSizer.Add(item = operatorSizer, proportion = 1,
00334                          flag = wx.RIGHT | wx.EXPAND, border = 5)
00335         controlSizer.Add(item = operandSizer, proportion = 0,
00336                          flag = wx.EXPAND)
00337 
00338         expressSizer = wx.StaticBoxSizer(self.expressBox, wx.HORIZONTAL)
00339         expressSizer.Add(item = self.text_mcalc, proportion = 1,
00340                          flag = wx.EXPAND)
00341 
00342         sizer.Add(item = controlSizer, proportion = 0,
00343                   flag = wx.EXPAND | wx.ALL,
00344                   border = 5)        
00345         sizer.Add(item = expressSizer, proportion = 1,
00346                   flag = wx.EXPAND | wx.LEFT | wx.RIGHT,
00347                   border = 5)
00348         sizer.Add(item = buttonSizer4, proportion = 0,
00349                   flag = wx.ALIGN_RIGHT | wx.ALL, border = 3)
00350         if self.addbox.IsShown():
00351             sizer.Add(item = self.addbox, proportion = 0,
00352                       flag = wx.LEFT | wx.RIGHT,
00353                       border = 5)
00354         
00355         self.panel.SetAutoLayout(True)
00356         self.panel.SetSizer(sizer)
00357         sizer.Fit(self.panel)
00358         
00359         self.Layout()
00360         
00361     def AddMark(self,event):
00362         """!Sends operators to insertion method
00363         """
00364         if event.GetId() == self.btn['compl'].GetId(): mark = "~"
00365         elif event.GetId() == self.btn['not'].GetId(): mark = "!"
00366         elif event.GetId() == self.btn['pow'].GetId(): mark = "^"
00367         elif event.GetId() == self.btn['div'].GetId(): mark = "/"
00368         elif event.GetId() == self.btn['add'].GetId(): mark = "+"
00369         elif event.GetId() == self.btn['minus'].GetId(): mark = "-"
00370         elif event.GetId() == self.btn['mod'].GetId(): mark = "%"
00371         elif event.GetId() == self.btn['mult'].GetId(): mark = "*"
00372         elif event.GetId() == self.btn['lshift'].GetId(): mark = "<<"
00373         elif event.GetId() == self.btn['rshift'].GetId(): mark = ">>"
00374         elif event.GetId() == self.btn['rshiftu'].GetId(): mark = ">>>"
00375         elif event.GetId() == self.btn['gt'].GetId(): mark = ">"
00376         elif event.GetId() == self.btn['gteq'].GetId(): mark = ">="
00377         elif event.GetId() == self.btn['lt'].GetId(): mark = "<"
00378         elif event.GetId() == self.btn['lteq'].GetId(): mark = "<="
00379         elif event.GetId() == self.btn['eq'].GetId(): mark = "=="
00380         elif event.GetId() == self.btn['noteq'].GetId(): mark = "!="
00381         elif event.GetId() == self.btn['andbit'].GetId(): mark = "&"
00382         elif event.GetId() == self.btn['orbit'].GetId(): mark = "|"
00383         elif event.GetId() == self.btn['or'].GetId(): mark =  "||"
00384         elif event.GetId() == self.btn['ornull'].GetId(): mark = "|||"
00385         elif event.GetId() == self.btn['and'].GetId(): mark = "&&"
00386         elif event.GetId() == self.btn['andnull'].GetId(): mark = "&&&"
00387         elif event.GetId() == self.btn['cond'].GetId(): mark = " ? : "
00388         elif event.GetId() == self.btn['parenl'].GetId(): mark = "("
00389         elif event.GetId() == self.btn['parenr'].GetId(): mark = ")"
00390         self._addSomething(mark)
00391         
00392     def OnSelect(self, event):
00393         """!Gets raster map or function selection and send it to
00394         insertion method
00395         """
00396         item = event.GetString()
00397         self._addSomething(item)
00398 
00399     def OnUpdateStatusBar(self, event):
00400         """!Update statusbar text"""
00401         expr = self.text_mcalc.GetValue().strip().replace("\n", " ")
00402         self.SetStatusText("r.mapcalc '%s = %s'" % (self.newmaptxt.GetValue(),
00403                                                     expr))
00404         event.Skip()
00405         
00406     def _addSomething(self, what):
00407         """!Inserts operators, map names, and functions into text area
00408         """
00409         self.text_mcalc.SetFocus()
00410         mcalcstr  = self.text_mcalc.GetValue()
00411         position  = self.text_mcalc.GetInsertionPoint()
00412         
00413         newmcalcstr = mcalcstr[:position]
00414         
00415         position_offset = 0
00416         try:
00417             if newmcalcstr[-1] != ' ':
00418                 newmcalcstr += ' '
00419                 position_offset += 1
00420         except:
00421             pass
00422         
00423         newmcalcstr += what + ' ' + mcalcstr[position:]
00424         position_offset += len(what)
00425         
00426         self.text_mcalc.SetValue(newmcalcstr)
00427         if len(what) > 1 and what[-2:] == '()':
00428             position_offset -= 1
00429         self.text_mcalc.SetInsertionPoint(position + position_offset)
00430         self.text_mcalc.Update()
00431         
00432     def OnMCalcRun(self,event):
00433         """!Builds and runs r.mapcalc statement
00434         """
00435         name = self.newmaptxt.GetValue().strip()
00436         if not name:
00437             GError(parent = self,
00438                    message = _("You must enter the name of "
00439                                "a new raster map to create."))
00440             return
00441         
00442         expr = self.text_mcalc.GetValue().strip().replace("\n", " ")
00443         if not expr:
00444             GError(parent = self,
00445                    message = _("You must enter an expression "
00446                                "to create a new raster map."))
00447             return
00448         
00449         if self.log:
00450             cmd = [self.cmd, str('%s = %s' % (name, expr))]
00451             self.log.RunCmd(cmd, onDone = self.OnDone)
00452             self.parent.Raise()
00453         else:
00454             RunCommand(self.cmd,
00455                        "%s=%s" % (name, expr))
00456         
00457     def OnDone(self, cmd, returncode):
00458         """!Add create map to the layer tree"""
00459         if not self.addbox.IsChecked():
00460             return
00461         name = self.newmaptxt.GetValue().strip() + '@' + grass.gisenv()['MAPSET']
00462         mapTree = self.parent.GetLayerTree()
00463         if not mapTree.GetMap().GetListOfLayers(l_name = name):
00464             mapTree.AddLayer(ltype = 'raster',
00465                              lname = name,
00466                              lcmd = ['d.rast', 'map=%s' % name],
00467                              multiple = False)
00468         
00469         display = self.parent.GetLayerTree().GetMapDisplay()
00470         if display and display.IsAutoRendered():
00471             display.GetWindow().UpdateMap(render = True)
00472         
00473     def OnSaveExpression(self, event):
00474         """!Saves expression to file
00475         """
00476         mctxt = self.newmaptxt.GetValue() + ' = ' + self.text_mcalc.GetValue() + os.linesep
00477         
00478         #dialog
00479         dlg = wx.FileDialog(parent = self,
00480                             message = _("Choose a file name to save the expression"),
00481                             wildcard = _("Expression file (*)|*"),
00482                             style = wx.SAVE | wx.FD_OVERWRITE_PROMPT)
00483         if dlg.ShowModal() == wx.ID_OK:
00484             path = dlg.GetPath()
00485             if not path:
00486                 dlg.Destroy()
00487                 return
00488             
00489             try:
00490                 fobj = open(path, 'w')
00491                 fobj.write(mctxt)
00492             finally:
00493                 fobj.close()
00494         
00495         dlg.Destroy()
00496 
00497     def OnLoadExpression(self, event):
00498         """!Load expression from file
00499         """
00500         dlg = wx.FileDialog(parent = self,
00501                             message = _("Choose a file name to load the expression"),
00502                             wildcard = _("Expression file (*)|*"),
00503                             style = wx.OPEN)
00504         if dlg.ShowModal() == wx.ID_OK:
00505             path = dlg.GetPath()
00506             if not path:
00507                 dlg.Destroy()
00508                 return
00509 
00510             try:
00511                 fobj = open(path,'r')
00512                 mctxt = fobj.read()
00513             finally:
00514                 fobj.close()
00515             
00516             try:
00517                 result, exp = mctxt.split('=', 1)
00518             except ValueError:
00519                 result = ''
00520                 exp = mctxt
00521             
00522             self.newmaptxt.SetValue(result.strip())
00523             self.text_mcalc.SetValue(exp.strip())
00524             self.text_mcalc.SetFocus()
00525             self.text_mcalc.SetInsertionPointEnd()
00526         
00527         dlg.Destroy()
00528                 
00529     def OnClear(self, event):
00530         """!Clears text area
00531         """
00532         self.text_mcalc.SetValue('')
00533         
00534     def OnHelp(self, event):
00535         """!Launches r.mapcalc help
00536         """
00537         RunCommand('g.manual', parent = self, entry = self.cmd)
00538         
00539     def OnClose(self,event):
00540         """!Close window"""
00541         self.Destroy()
00542         
00543 if __name__ == "__main__":
00544     import gettext
00545     gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode = True)
00546     
00547     app = wx.App(0)
00548     frame = MapCalcFrame(parent = None, cmd = 'r.mapcalc')
00549     frame.Show()
00550     app.MainLoop()