GRASS Programmer's Manual  6.4.2(2012)
psmap_dialogs.py
Go to the documentation of this file.
00001 """!
00002 @package psmap_dialogs.py
00003 
00004 @brief Map feature objects and dialogs for ps.map
00005 
00006 Classes:
00007  - UnitConversion
00008  - TCValidator
00009  - PenStyleComboBox
00010  - CheckListCtrl
00011  - Instruction
00012  - InstructionObject
00013  - InitMap
00014  - MapFrame
00015  - PageSetup
00016  - Mapinfo
00017  - Text
00018  - Scalebar
00019  - RasterLegend
00020  - VectorLegend
00021  - Raster
00022  - Vector
00023  - VProperties
00024  - PsmapDialog
00025  - PageSetupDialog
00026  - MapDialog
00027  - MapFramePanel
00028  - RasterPanel
00029  - VectorPanel
00030  - RasterDialog
00031  - MainVectorDialog
00032  - VPropertiesDialog
00033  - LegendDialog
00034  - MapinfoDialog
00035  - ScalebarDialog
00036  - TextDialog
00037 
00038 (C) 2011 by Anna Kratochvilova, and the GRASS Development Team
00039 This program is free software under the GNU General Public License
00040 (>=v2). Read the file COPYING that comes with GRASS for details.
00041 
00042 @author Anna Kratochvilova <anna.kratochvilova fsv.cvut.cz> (bachelor's project)
00043 @author Martin Landa <landa.martin gmail.com> (mentor)
00044 """
00045 
00046 
00047 import os
00048 import sys
00049 import string
00050 from math import ceil, floor
00051 from copy import deepcopy
00052 from time import strftime, localtime
00053 
00054 import grass.script as grass
00055 if int(grass.version()['version'].split('.')[0]) > 6:
00056     sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'gui', 'wxpython',
00057                                  'gui_modules'))
00058 else:
00059     sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'wxpython',
00060                                  'gui_modules'))
00061 import globalvar
00062 import dbm_base
00063 from   utils      import CmdToTuple, GetCmdString
00064 from   gselect    import Select
00065 from   gcmd       import RunCommand, GError, GMessage, GWarning
00066 
00067 import wx
00068 import wx.lib.scrolledpanel as scrolled
00069 import  wx.lib.filebrowsebutton as filebrowse
00070 from wx.lib.mixins.listctrl import CheckListCtrlMixin, ListCtrlAutoWidthMixin
00071 from wx.lib.expando import ExpandoTextCtrl, EVT_ETC_LAYOUT_NEEDED
00072 try:
00073     import wx.lib.agw.floatspin as fs
00074 except ImportError:
00075     fs = None
00076 
00077 grass.set_raise_on_error(True)
00078 
00079 PSMAP_COLORS = ['aqua', 'black', 'blue', 'brown', 'cyan', 'gray', 'grey', 'green', 'indigo',
00080                 'magenta','orange', 'purple', 'red', 'violet', 'white', 'yellow']
00081 class UnitConversion:
00082     """! Class for converting units"""
00083     def __init__(self, parent = None):
00084         self.parent = parent
00085         if self.parent:
00086             ppi = wx.ClientDC(self.parent).GetPPI()
00087         else: 
00088             ppi = (72, 72)
00089         self._unitsPage = { 'inch'          : {'val': 1.0, 'tr' : _("inch")},
00090                             'point'         : {'val': 72.0, 'tr' : _("point")},
00091                             'centimeter'    : {'val': 2.54, 'tr' : _("centimeter")},
00092                             'millimeter'    : {'val': 25.4, 'tr' : _("millimeter")}}
00093         self._unitsMap = {  'meters'        : {'val': 0.0254, 'tr' : _("meters")},
00094                             'kilometers'    : {'val': 2.54e-5, 'tr' : _("kilometers")},
00095                             'feet'          : {'val': 1./12, 'tr' : _("feet")},
00096                             'miles'         : {'val': 1./63360, 'tr' : _("miles")},
00097                             'nautical miles': {'val': 1/72913.386, 'tr' : _("nautical miles")}}
00098 
00099         self._units = { 'pixel'     : {'val': ppi[0], 'tr' : _("pixel")},
00100                         'meter'     : {'val': 0.0254, 'tr' : _("meter")},
00101                         'nautmiles' : {'val': 1/72913.386, 'tr' :_("nautical miles")},
00102                         'degrees'   : {'val': 0.0254 , 'tr' : _("degree")} #like 1 meter, incorrect
00103                         }
00104         self._units.update(self._unitsPage)
00105         self._units.update(self._unitsMap)
00106 
00107     def getPageUnitsNames(self):
00108         return sorted(self._unitsPage[unit]['tr'] for unit in self._unitsPage.keys())
00109     
00110     def getMapUnitsNames(self):
00111         return sorted(self._unitsMap[unit]['tr'] for unit in self._unitsMap.keys())
00112     
00113     def getAllUnits(self):
00114         return sorted(self._units.keys())
00115     
00116     def findUnit(self, name):
00117         """!Returns unit by its tr. string"""
00118         for unit in self._units.keys():
00119             if self._units[unit]['tr'] == name:
00120                 return unit
00121         return None
00122     
00123     def findName(self, unit):
00124         """!Returns tr. string of a unit"""
00125         try:
00126             return self._units[unit]['tr']
00127         except KeyError:
00128             return None
00129     
00130     def convert(self, value, fromUnit = None, toUnit = None):
00131         return float(value)/self._units[fromUnit]['val']*self._units[toUnit]['val']
00132     
00133     
00134 class TCValidator(wx.PyValidator):
00135     """!validates input in textctrls, combobox, taken from wxpython demo"""
00136     def __init__(self, flag = None):
00137         wx.PyValidator.__init__(self)
00138         self.flag = flag
00139         self.Bind(wx.EVT_CHAR, self.OnChar)
00140 
00141     def Clone(self):
00142         return TCValidator(self.flag)
00143 
00144     def Validate(self, win):
00145         
00146         tc = self.GetWindow()
00147         val = tc.GetValue()
00148 
00149         if self.flag == 'DIGIT_ONLY':
00150             for x in val:
00151                 if x not in string.digits:
00152                     return False
00153         return True
00154 
00155     def OnChar(self, event):
00156         key = event.GetKeyCode()
00157         if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255:
00158             event.Skip()
00159             return
00160         if self.flag == 'DIGIT_ONLY' and chr(key) in string.digits + '.':
00161             event.Skip()
00162             return
00163 ##        if self.flag == 'SCALE' and chr(key) in string.digits + ':':
00164 ##            event.Skip()
00165 ##            return
00166         if self.flag == 'ZERO_AND_ONE_ONLY' and chr(key) in '01':
00167             event.Skip()
00168             return
00169         if not wx.Validator_IsSilent():
00170             wx.Bell()
00171         # Returning without calling even.Skip eats the event before it
00172         # gets to the text control
00173         return  
00174 
00175 
00176 class PenStyleComboBox(wx.combo.OwnerDrawnComboBox):
00177     """!Combo for selecting line style, taken from wxpython demo"""
00178 
00179     # Overridden from OwnerDrawnComboBox, called to draw each
00180     # item in the list
00181     def OnDrawItem(self, dc, rect, item, flags):
00182         if item == wx.NOT_FOUND:
00183             # painting the control, but there is no valid item selected yet
00184             return
00185 
00186         r = wx.Rect(*rect)  # make a copy
00187         r.Deflate(3, 5)
00188 
00189         penStyle = wx.SOLID
00190         if item == 1:
00191             penStyle = wx.LONG_DASH
00192         elif item == 2:
00193             penStyle = wx.DOT
00194         elif item == 3:
00195             penStyle = wx.DOT_DASH
00196 
00197         pen = wx.Pen(dc.GetTextForeground(), 3, penStyle)
00198         dc.SetPen(pen)
00199 
00200         # for painting the items in the popup
00201         dc.DrawText(self.GetString(item ),
00202                     r.x + 3,
00203                     (r.y + 0) + ((r.height/2) - dc.GetCharHeight() )/2
00204                     )
00205         dc.DrawLine(r.x+5, r.y+((r.height/4)*3)+1, r.x+r.width - 5, r.y+((r.height/4)*3)+1 )
00206 
00207         
00208     def OnDrawBackground(self, dc, rect, item, flags):
00209         """!Overridden from OwnerDrawnComboBox, called for drawing the
00210         background area of each item."""
00211         # If the item is selected, or its item # iseven, or we are painting the
00212         # combo control itself, then use the default rendering.
00213         if (item & 1 == 0 or flags & (wx.combo.ODCB_PAINTING_CONTROL |
00214                                       wx.combo.ODCB_PAINTING_SELECTED)):
00215             wx.combo.OwnerDrawnComboBox.OnDrawBackground(self, dc, rect, item, flags)
00216             return
00217 
00218         # Otherwise, draw every other background with different colour.
00219         bgCol = wx.Colour(240,240,250)
00220         dc.SetBrush(wx.Brush(bgCol))
00221         dc.SetPen(wx.Pen(bgCol))
00222         dc.DrawRectangleRect(rect);
00223 
00224     def OnMeasureItem(self, item):
00225         """!Overridden from OwnerDrawnComboBox, should return the height
00226         needed to display an item in the popup, or -1 for default"""
00227         return 30
00228 
00229     def OnMeasureItemWidth(self, item):
00230         """!Overridden from OwnerDrawnComboBox.  Callback for item width, or
00231         -1 for default/undetermined"""
00232         return -1; # default - will be measured from text width  
00233     
00234     
00235 class CheckListCtrl(wx.ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin):
00236     """!List control for managing order and labels of vector maps in legend"""
00237     def __init__(self, parent):
00238         wx.ListCtrl.__init__(self, parent, id = wx.ID_ANY, 
00239                              style = wx.LC_REPORT|wx.LC_SINGLE_SEL|wx.BORDER_SUNKEN|wx.LC_VRULES|wx.LC_HRULES)
00240         CheckListCtrlMixin.__init__(self) 
00241         ListCtrlAutoWidthMixin.__init__(self)
00242         
00243 class Instruction:
00244     """!Class which represents instruction file"""
00245     def __init__(self, parent, objectsToDraw):
00246         
00247         self.parent = parent
00248         self.objectsToDraw = objectsToDraw
00249         #here are kept objects like mapinfo, rasterlegend, etc.
00250         self.instruction = list()
00251         
00252     def __str__(self):
00253         """!Returns text for instruction file"""
00254         comment = "# timestamp: " + strftime("%Y-%m-%d %H:%M", localtime()) + '\n'
00255         env = grass.gisenv()
00256         comment += "# location: %s\n" % env['LOCATION_NAME']
00257         comment += "# mapset: %s\n" % env['MAPSET']
00258         comment += "# page orientation: %s\n" % self.FindInstructionByType('page')['Orientation']
00259         border = ''
00260         if not self.FindInstructionByType('map'):
00261             border = 'border n\n'
00262         text = [str(each) for each in self.instruction]
00263         return comment + border + '\n'.join(text) + '\nend'
00264     
00265     def __getitem__(self, id):
00266         for each in self.instruction:
00267             if each.id == id:
00268                 return each
00269         return None
00270 
00271     def __contains__(self, id):
00272         """!Test if instruction is included"""
00273         for each in self.instruction:
00274             if each.id == id:
00275                 return True
00276         return False
00277     
00278     def __delitem__(self, id):
00279         """!Delete instruction"""
00280         for each in self.instruction:
00281             if each.id == id:
00282                 if each.type == 'map':
00283                     #must remove raster, vector layers too
00284                     vektor = self.FindInstructionByType('vector', list = True)
00285                     vProperties = self.FindInstructionByType('vProperties', list = True)
00286                     raster = self.FindInstructionByType('raster', list = True)
00287                     for item in vektor + vProperties + raster:
00288                         if item in self.instruction:
00289                             self.instruction.remove(item)
00290                             
00291                 self.instruction.remove(each)
00292                 if id in self.objectsToDraw:
00293                     self.objectsToDraw.remove(id)
00294                 return
00295             
00296     def AddInstruction(self, instruction):
00297         """!Add instruction"""
00298         # add to instructions
00299         if instruction.type == 'map':
00300             self.instruction.insert(0, instruction)
00301         else:
00302             self.instruction.append(instruction)
00303         # add to drawable objects
00304         if instruction.type not in ('page', 'raster', 'vector', 'vProperties', 'initMap'):
00305             if instruction.type == 'map':
00306                 self.objectsToDraw.insert(0, instruction.id) 
00307             else:
00308                 self.objectsToDraw.append(instruction.id) 
00309                 
00310             
00311     def FindInstructionByType(self, type, list = False):
00312         """!Find instruction(s) with the given type"""
00313         inst = []
00314         for each in self.instruction:
00315             if each.type == type:
00316                 inst.append(each)
00317         if len(inst) == 1 and not list:
00318             return inst[0]
00319         return inst
00320     
00321     def Read(self, filename):
00322         """!Reads instruction file and creates instruction objects"""
00323         self.filename = filename
00324         # open file
00325         try:
00326             file = open(filename, 'r')
00327         except IOError:
00328             GError(message = _("Unable to open file\n%s") % filename)
00329             return
00330         # first read file to get information about region and scaletype
00331         isRegionComment = False
00332         orientation = 'Portrait'
00333         for line in file:
00334             if '# g.region' in line:
00335                 self.SetRegion(regionInstruction = line)
00336                 isRegionComment = True
00337                 break
00338             if '# page orientation' in line:
00339                 orientation = line.split(':')[-1].strip()
00340                 
00341         if not isRegionComment:
00342             self.SetRegion(regionInstruction = None)
00343         # then run ps.map -b to get information for maploc
00344         # compute scale and center 
00345         map = self.FindInstructionByType('map')
00346         region = grass.region()
00347         map['center'] = (region['n'] + region['s']) / 2, (region['w'] + region['e']) / 2
00348         mapRect = GetMapBounds(self.filename, portrait = (orientation == 'Portrait'))
00349         map['rect'] = mapRect
00350         proj = projInfo()
00351         toM = 1.0
00352         if proj['units']:
00353             toM = float(proj['meters'])
00354         units = UnitConversion(self.parent)
00355         w = units.convert(value = mapRect.Get()[2], fromUnit = 'inch', toUnit = 'meter') / toM
00356         map['scale'] = w / abs((region['w'] - region['e']))
00357         
00358         SetResolution(dpi = 300, width = map['rect'].width, height = map['rect'].height)
00359         
00360         # read file again, now with information about map bounds
00361         isBuffer = False
00362         buffer = []
00363         instruction = None
00364         vectorMapNumber = 1
00365         file.seek(0)
00366         for line in file:
00367             if not line.strip(): 
00368                 continue
00369             line = line.strip()
00370             if isBuffer:
00371                 buffer.append(line)
00372                 if 'end' in line:
00373                     isBuffer = False
00374                     kwargs = {}
00375                     if instruction == 'scalebar':
00376                         kwargs['scale'] = map['scale']
00377                     elif instruction == 'text':
00378                         kwargs['mapInstruction'] = map
00379                     elif instruction in ('vpoints', 'vlines', 'vareas'):
00380                         kwargs['id'] = wx.NewId()
00381                         kwargs['vectorMapNumber'] = vectorMapNumber
00382                         vectorMapNumber += 1
00383                     elif instruction == 'paper':
00384                         kwargs['Orientation'] = orientation
00385                         
00386                     ok = self.SendToRead(instruction, buffer, **kwargs)
00387                     if not ok: return False
00388                     buffer = []
00389                 continue 
00390             
00391             elif line.startswith('paper'):
00392                 instruction = 'paper'
00393                 isBuffer = True
00394                 buffer.append(line)
00395             
00396             elif line.startswith('border'):
00397                 if line.split()[1].lower() in ('n', 'no', 'none'):
00398                     ok = self.SendToRead('border', [line])
00399                     if not ok: return False
00400                 elif line.split()[1].lower() in ('y', 'yes'):
00401                     instruction = 'border'
00402                     isBuffer = True
00403                     buffer.append(line)
00404             
00405             elif line.startswith('scale '):
00406                 ok = self.SendToRead('scale', line, isRegionComment = isRegionComment)
00407                 if not ok: return False
00408             
00409             elif line.startswith('maploc'):
00410                 ok = self.SendToRead(instruction = 'maploc', text = line)
00411                 if not ok: return False
00412                 
00413             elif line.startswith('raster'):
00414                 ok = self.SendToRead(instruction = 'raster', text = line)
00415                 if not ok: return False
00416             
00417             elif line.startswith('mapinfo'):
00418                 instruction = 'mapinfo'
00419                 isBuffer = True
00420                 buffer.append(line)
00421 
00422 
00423             elif line.startswith('scalebar'):
00424                 instruction = 'scalebar'
00425                 isBuffer = True
00426                 buffer.append(line) 
00427             
00428             elif line.startswith('text'):
00429                 instruction = 'text'
00430                 isBuffer = True
00431                 buffer.append(line) 
00432             
00433             elif line.startswith('colortable'):
00434                 if len(line.split()) == 2 and line.split()[1].lower() in ('n', 'no', 'none'):
00435                     break
00436                 instruction = 'colortable'
00437                 isBuffer = True
00438                 buffer.append(line) 
00439         
00440             elif line.startswith('vlegend'):
00441                 instruction = 'vlegend'
00442                 isBuffer = True
00443                 buffer.append(line) 
00444                 
00445             elif line.startswith('vpoints'):
00446                 instruction = 'vpoints'
00447                 isBuffer = True
00448                 buffer.append(line) 
00449                 
00450             elif line.startswith('vlines'):
00451                 instruction = 'vlines'
00452                 isBuffer = True
00453                 buffer.append(line)
00454                 
00455             elif line.startswith('vareas'):
00456                 instruction = 'vareas'
00457                 isBuffer = True
00458                 buffer.append(line)
00459 
00460 
00461         
00462         rasterLegend = self.FindInstructionByType('rasterLegend')
00463         raster = self.FindInstructionByType('raster')
00464         page = self.FindInstructionByType('page')
00465         vector = self.FindInstructionByType('vector')
00466         vectorLegend = self.FindInstructionByType('vectorLegend')
00467         vectorMaps = self.FindInstructionByType('vProperties', list = True)
00468 
00469         # check (in case of scaletype 0) if map is drawn also
00470         map['drawMap'] = False
00471         if map['scaleType'] == 0:
00472             mapForRegion = map['map']
00473             if map['mapType'] == 'raster' and raster:
00474                 if mapForRegion == raster['raster']:
00475                     map['drawMap'] = True
00476             elif map['mapType'] == 'vector' and vector:
00477                 for vmap in vector['list']:
00478                     if mapForRegion == vmap[0]:
00479                         map['drawMap'] = True
00480 
00481         # rasterLegend
00482         if rasterLegend:
00483             if rasterLegend['rasterDefault'] and raster:
00484                 rasterLegend['raster'] = raster['raster']
00485                 if not rasterLegend['discrete']:
00486                     rasterType = getRasterType(map = rasterLegend['raster'])
00487                     if rasterType == 'CELL':
00488                         rasterLegend['discrete'] = 'y'
00489                     else:
00490                         rasterLegend['discrete'] = 'n'
00491             
00492             #estimate size
00493             height = rasterLegend.EstimateHeight(raster = rasterLegend['raster'], discrete = rasterLegend['discrete'], 
00494                                                  fontsize = rasterLegend['fontsize'],
00495                                                  cols = rasterLegend['cols'], 
00496                                                  height = rasterLegend['height'])
00497             width = rasterLegend.EstimateWidth(raster = rasterLegend['raster'], discrete = rasterLegend['discrete'], 
00498                                                fontsize = rasterLegend['fontsize'],
00499                                                cols = rasterLegend['cols'] , 
00500                                                width = rasterLegend['width'],
00501                                                paperInstr = page)
00502             rasterLegend['rect'] = wx.Rect2D(x = float(rasterLegend['where'][0]), y = float(rasterLegend['where'][1]),
00503                                              w = width, h = height)
00504             
00505         # vectors, vlegend        
00506         
00507         if vector:
00508             for vmap in vectorMaps:
00509                 for i, each in enumerate(vector['list']):
00510                     if each[2] == vmap.id:
00511                         
00512                         vector['list'][i][4] = vmap['label']
00513                         vector['list'][i][3] = vmap['lpos']
00514             if vectorLegend:
00515                 size = vectorLegend.EstimateSize(vectorInstr = vector, fontsize = vectorLegend['fontsize'],
00516                                                  width = vectorLegend['width'], cols = vectorLegend['cols'])                            
00517                 vectorLegend['rect'] = wx.Rect2D(x = float(vectorLegend['where'][0]), y = float(vectorLegend['where'][1]),
00518                                                  w = size[0], h = size[1])
00519         
00520         
00521         page = self.FindInstructionByType('page')
00522         if not page:
00523             page = PageSetup(wx.NewId())
00524             self.AddInstruction(page)
00525         else:
00526             page['Orientation'] = orientation
00527 
00528 
00529         #
00530         return True
00531     
00532     def SendToRead(self, instruction, text, **kwargs):
00533         psmapInstrDict = dict(paper = ['page'],
00534                               maploc = ['map'],
00535                               scale = ['map'],
00536                               border = ['map'],
00537                               raster = ['raster'],
00538                               mapinfo = ['mapinfo'],
00539                               scalebar = ['scalebar'],
00540                               text = ['text'],
00541                               vpoints = ['vector', 'vProperties'],
00542                               vlines = ['vector', 'vProperties'],
00543                               vareas = ['vector', 'vProperties'],
00544                               colortable = ['rasterLegend'],
00545                               vlegend = ['vectorLegend']
00546                               )
00547         
00548         myInstrDict = dict(page = PageSetup,
00549                            map = MapFrame,
00550                            raster = Raster,
00551                            mapinfo = Mapinfo,
00552                            scalebar = Scalebar,
00553                            text = Text,
00554                            rasterLegend = RasterLegend,
00555                            vectorLegend = VectorLegend,
00556                            vector = Vector,
00557                            vProperties = VProperties
00558                            )
00559         
00560         myInstruction = psmapInstrDict[instruction]
00561         
00562         for i in myInstruction:
00563             instr = self.FindInstructionByType(i)
00564             if i in ('text', 'vProperties') or not instr:
00565                 
00566                 id = wx.NewId() #!vProperties expect subtype
00567                 if i == 'vProperties':
00568                     id = kwargs['id']
00569                     newInstr = myInstrDict[i](id, subType = instruction[1:])
00570                 else:
00571                     newInstr = myInstrDict[i](id)
00572                 ok = newInstr.Read(instruction, text, **kwargs)
00573                 if ok:
00574                     self.AddInstruction(newInstr)
00575                 else:
00576                     return False
00577 
00578             else:
00579                 ok = instr.Read(instruction, text, **kwargs)
00580 
00581                 if not ok:
00582                     return False
00583         return True
00584     
00585     def SetRegion(self, regionInstruction):
00586         """!Sets region from file comment or sets current region in case of no comment"""
00587         map = MapFrame(wx.NewId())
00588         self.AddInstruction(map)
00589         if regionInstruction:
00590             cmd = CmdToTuple(regionInstruction.strip('# ').split())
00591             
00592             # define scaleType
00593             if len(cmd[1]) <= 3:
00594                 if 'rast' in cmd[1]:
00595                     map['scaleType'] = 0
00596                     map['mapType'] = 'raster'   
00597                     map['map'] = cmd[1]['rast']  
00598                 elif 'vect' in cmd[1]:
00599                     map['scaleType'] = 0
00600                     map['mapType'] = 'vector' 
00601                     map['map'] = cmd[1]['vect']  
00602                 elif 'region' in cmd[1]:
00603                     map['scaleType'] = 1  
00604                     map['region'] = cmd[1]['region']
00605                     
00606             else:
00607                 map['scaleType'] = 2  
00608         else:
00609             map['scaleType'] = 2
00610             grass.del_temp_region()
00611             region = grass.region()
00612             grass.use_temp_region()    
00613             cmd = ['g.region', region]
00614         cmdString = GetCmdString(cmd).replace('g.region', '')
00615         GMessage(_("Instruction file will be loaded with following region: %s\n") % cmdString)
00616         try:
00617             RunCommand(cmd[0], **cmd[1])
00618             
00619         except grass.ScriptError, e:
00620             GError(_("Region cannot be set\n%s") % e)
00621             return False
00622         
00623 
00624 class InstructionObject:
00625     """!Abtract class representing single instruction"""
00626     def __init__(self, id): 
00627         self.id = id
00628         
00629         # default values
00630         self.defaultInstruction = dict()
00631         # current values
00632         self.instruction = self.defaultInstruction   
00633         # converting units
00634         self.unitConv = UnitConversion() 
00635     
00636     def __str__(self):
00637         """!Returns particular part of text instruction"""
00638         return ''
00639     
00640     def __getitem__(self, key):
00641         for each in self.instruction.keys():
00642             if each == key:
00643                 return self.instruction[key]
00644         return None
00645     
00646     def __setitem__(self, key, value):
00647         self.instruction[key] = value
00648     
00649     def GetInstruction(self):
00650         """!Get current values"""
00651         return self.instruction
00652     
00653     def SetInstruction(self, instruction):
00654         """!Set default values"""
00655         self.instruction = instruction
00656         
00657     def Read(self, instruction, text, **kwargs):
00658         """!Read instruction and save them"""
00659         pass
00660     
00661 class InitMap(InstructionObject):
00662     """!Class representing virtual map"""
00663     def __init__(self, id):
00664         InstructionObject.__init__(self, id = id)
00665         self.type = 'initMap'
00666         
00667         # default values
00668         self.defaultInstruction = dict(rect = None, scale =  None)
00669         # current values
00670         self.instruction = dict(self.defaultInstruction)
00671         
00672     
00673 class MapFrame(InstructionObject):
00674     """!Class representing map (instructions maploc, scale, border)"""
00675     def __init__(self, id):
00676         InstructionObject.__init__(self, id = id)
00677         self.type = 'map'
00678         # default values
00679         self.defaultInstruction = dict(map = None, mapType = None, drawMap = True, region = None,
00680                                        rect = wx.Rect2D(), scaleType = 0, scale = None, center = None,
00681                                        resolution = 300, border = 'y', width = 1, color = '0:0:0') 
00682         # current values
00683         self.instruction = dict(self.defaultInstruction)
00684         
00685     def __str__(self):
00686         instr = ''
00687         comment = ''
00688         
00689         #region settings
00690         region = grass.region()
00691         if self.instruction['scaleType'] == 0: #match map
00692             map = self.instruction['map']
00693             if self.instruction['mapType'] == 'raster':
00694                 comment = "# g.region rast=%s nsres=%s ewres=%s\n" % (map, region['nsres'], region['ewres'])
00695             else:
00696                 comment = "# g.region vect=%s\n" % (map)
00697         elif self.instruction['scaleType'] == 1:# saved region
00698             region = self.instruction['region']
00699             comment = "# g.region region=%s\n" % region
00700         elif self.instruction['scaleType'] in (2, 3): #current region, fixed scale
00701             comment = string.Template("# g.region n=$n s=$s e=$e w=$w rows=$rows cols=$cols \n").substitute(**region)
00702         
00703         instr += comment
00704         instr += '\n'
00705         # maploc
00706         maplocInstruction = "maploc %.3f %.3f" % (self.instruction['rect'].x, self.instruction['rect'].y)
00707         if self.instruction['scaleType'] != 3:
00708             maplocInstruction += "  %.3f %.3f"% (self.instruction['rect'].width, self.instruction['rect'].height)
00709         instr += maplocInstruction
00710         instr += '\n'
00711         
00712         # scale
00713         if self.instruction['scaleType'] == 3: #fixed scale
00714             scaleInstruction = "scale 1:%.0f" % (1/self.instruction['scale'])
00715             instr += scaleInstruction
00716             instr += '\n'
00717         # border
00718         borderInstruction = ''
00719         if self.instruction['border'] == 'n':
00720             borderInstruction = "border n"
00721         else:
00722             borderInstruction = "border y\n"
00723             borderInstruction += string.Template("    width $width\n    color $color\n").substitute(self.instruction)
00724             borderInstruction += "    end"
00725         instr += borderInstruction
00726         instr += '\n'
00727 
00728         return instr  
00729     
00730     def Read(self, instruction, text, **kwargs):
00731         """!Read instruction and save information"""
00732         if 'isRegionComment' in kwargs:
00733             isRegionComment = kwargs['isRegionComment']
00734         instr = {}
00735         
00736         if instruction == 'border':
00737             for line in text:
00738                 if line.startswith('end'):
00739                     break
00740                 try:
00741                     if line.split()[1].lower() in ('n', 'no', 'none'):
00742                         instr['border'] = 'n'
00743                         break
00744                     elif line.split()[1].lower() in ('y', 'yes'):
00745                         instr['border'] = 'y'
00746                     elif line.startswith('width'):
00747                         instr['width'] = line.split()[1]
00748                     elif line.startswith('color'):
00749                         instr['color'] = line.split()[1]
00750                 except IndexError:
00751                     GError(_("Failed to read instruction %s") % instruction)
00752                     return False
00753                 
00754         elif instruction == 'scale':
00755             try:
00756                 scaleText = text.strip('scale ').split(':')[1]
00757                 # when scale instruction given and region comment also, then scaletype is fixed scale
00758                 if not isRegionComment:
00759                     instr['scaleType'] = 2 
00760                 else:
00761                     instr['scaleType'] = 3
00762 
00763                 scale = 1/float(scaleText)
00764                 if abs(scale - self.instruction['scale']) > (0.01 * scale):
00765                     GWarning(_("Scale has changed, old value: %(old)s\nnew value: %(new)s") % \
00766                                  { 'old' : scale, 'new' : self.instruction['scale'] })
00767             except (ValueError, IndexError):
00768                 GError(_("Failed to read instruction %s.\nUse 1:25000 notation.") % instruction)
00769                 return False
00770         
00771         elif instruction == 'maploc':
00772             maploc = text.strip('maploc ').split()
00773             if len(maploc) >= 2:
00774                 if  abs(self.instruction['rect'].Get()[0] - float(maploc[0])) > 0.5 or \
00775                         abs(self.instruction['rect'].Get()[1] - float(maploc[1])) > 0.5:
00776                     GWarning(_("Map frame position changed, old value: %(old1)s %(old2)s\nnew value: %(new1)s %(new2)s") % \
00777                                  { 'old1' : maploc[0], 'old2' : maploc[1],
00778                                    'new1' : self.instruction['rect'].Get()[0], 'new2' : self.instruction['rect'].Get()[1] })
00779                     
00780                 #instr['rect'] = wx.Rect2D(float(maploc[0]), float(maploc[1]), self.instruction['rect'][2], self.instruction['rect'][3])
00781             if len(maploc) == 4:
00782                 if  abs(self.instruction['rect'].Get()[2] - float(maploc[2])) > 0.5 or \
00783                         abs(self.instruction['rect'].Get()[3] - float(maploc[3])) > 0.5:
00784                     GWarning(_("Map frame size changed, old value: %(old1)s %(old2)s\nnew value: %(new1)s %(new2)s") % \
00785                                  { 'old1' : maploc[2], 'old2' : maploc[3],
00786                                    'new1' : self.instruction['rect'].Get()[2], 'new2' : self.instruction['rect'].Get()[3] })
00787                 #instr['rect'] = wx.Rect2D(*map(float, maploc))
00788         self.instruction.update(instr)   
00789         return True 
00790     
00791 class PageSetup(InstructionObject):
00792     """!Class representing page instruction"""
00793     def __init__(self, id):
00794         InstructionObject.__init__(self, id = id)
00795         self.type = 'page'
00796         # default values
00797         self.defaultInstruction = dict(Units = 'inch', Format = 'a4', Orientation = 'Portrait',
00798                                        Width = 8.268, Height = 11.693, Left = 0.5, Right = 0.5, Top = 1, Bottom = 1)
00799         # current values
00800         self.instruction = dict(self.defaultInstruction)
00801         
00802     def __str__(self):
00803         if self.instruction['Format'] == 'custom':
00804             instr = string.Template("paper\n    width $Width\n    height $Height\n").substitute(self.instruction)
00805         else:
00806             instr = string.Template("paper $Format\n").substitute(self.instruction)
00807         instr += string.Template("    left $Left\n    right $Right\n    bottom $Bottom\n    top $Top\n    end").substitute(self.instruction)
00808 
00809         return instr
00810     
00811     def Read(self, instruction, text, **kwargs):
00812         """!Read instruction and save information"""
00813         instr = {}
00814         self.cats = ['Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
00815         self.subInstr = dict(zip(['width', 'height', 'left', 'right', 'top', 'bottom'], self.cats))
00816         
00817         if instruction == 'paper': # just for sure
00818             for line in text:
00819                 if line.startswith('paper'): 
00820                     if len(line.split()) > 1:
00821                         pformat = line.split()[1]
00822                         availableFormats = self._toDict(grass.read_command('ps.map', flags = 'p',
00823                                                                            quiet = True))
00824                         # e.g. paper a3 
00825                         try:
00826                             instr['Format'] = pformat
00827                             for key, value in availableFormats[pformat].iteritems():
00828                                 instr[key] = float(value)
00829                             break
00830                         except KeyError:
00831                             GError(_("Failed to read instruction %(file)s.\nUnknown format %(for)s") % \
00832                                        { 'file' : instruction, 'for' : format })
00833                             return False
00834                     else:
00835                         # paper
00836                         # width ...
00837                         instr['Format'] = 'custom'
00838                 # read subinstructions
00839                 elif instr['Format'] == 'custom' and not line.startswith('end'):
00840                     text = line.split()
00841                     try:
00842                         instr[self.subInstr[text[0]]] = float(text[1])
00843                     except  (IndexError, KeyError):
00844                         GError(_("Failed to read instruction %s.") % instruction)
00845                         return False
00846                     
00847             if 'Orientation' in kwargs and kwargs['Orientation'] == 'Landscape':
00848                 instr['Width'], instr['Height'] = instr['Height'], instr['Width']
00849                 
00850             self.instruction.update(instr)
00851         return True  
00852     
00853     def _toDict(self, paperStr):    
00854         sizeDict = dict()
00855 #     cats = self.subInstr[ 'Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
00856         for line in paperStr.strip().split('\n'):
00857             d = dict(zip(self.cats, line.split()[1:]))
00858             sizeDict[line.split()[0]] = d
00859             
00860         return sizeDict    
00861     
00862 class Mapinfo(InstructionObject):
00863     """!Class representing mapinfo instruction"""
00864     def __init__(self, id):
00865         InstructionObject.__init__(self, id = id)
00866         self.type = 'mapinfo'
00867         # default values
00868         self.defaultInstruction = dict(unit = 'inch', where = (0, 0),
00869                                        font = 'Helvetica', fontsize = 10, color = '0:0:0', background = 'none', 
00870                                        border = 'none', rect = None)
00871         # current values
00872         self.instruction = dict(self.defaultInstruction)
00873         
00874     def __str__(self):
00875         instr = "mapinfo\n"
00876         instr += "    where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
00877         instr += string.Template("    font $font\n    fontsize $fontsize\n    color $color\n").substitute(self.instruction)            
00878         instr += string.Template("    background $background\n    border $border\n").substitute(self.instruction)  
00879         instr += "    end"
00880         return instr
00881     
00882     def Read(self, instruction, text):
00883         """!Read instruction and save information"""
00884         instr = {}
00885         try:
00886             for line in text:
00887                 sub = line.split(None,1)
00888                 if sub[0] == 'font':
00889                     instr['font'] = sub[1]
00890                 elif sub[0] == 'fontsize':
00891                     instr['fontsize'] = int(sub[1])
00892                 elif sub[0] == 'color':
00893                     instr['color'] = sub[1]
00894                 elif sub[0] == 'background':
00895                     instr['background'] = sub[1]
00896                 elif sub[0] == 'border':
00897                     instr['border'] = sub[1]
00898                 elif sub[0] == 'where':
00899                     instr['where'] = float(sub[1].split()[0]), float(sub[1].split()[1])
00900         except (ValueError, IndexError):
00901             GError(_("Failed to read instruction %s") % instruction)
00902             return False
00903         self.instruction.update(instr)
00904         self.instruction['rect'] = self.EstimateRect(mapinfoDict = self.instruction)
00905         return True
00906     
00907     def EstimateRect(self, mapinfoDict):
00908         """!Estimate size to draw mapinfo"""
00909         w = mapinfoDict['fontsize'] * 20 # any better estimation? 
00910         h = mapinfoDict['fontsize'] * 7
00911         width = self.unitConv.convert(value = w, fromUnit = 'point', toUnit = 'inch')
00912         height = self.unitConv.convert(value = h, fromUnit = 'point', toUnit = 'inch')
00913         return wx.Rect2D(x = float(mapinfoDict['where'][0]), y = float(mapinfoDict['where'][1]), w = width, h = height)
00914     
00915 class Text(InstructionObject):
00916     """!Class representing text instruction"""
00917     def __init__(self, id):
00918         InstructionObject.__init__(self, id = id)
00919         self.type = 'text'
00920         # default values
00921         self.defaultInstruction = dict(text = "", font = "Helvetica", fontsize = 10, color = 'black', background = 'none',
00922                                        hcolor = 'none', hwidth = 1, border = 'none', width = '1', XY = True,
00923                                        where = (0,0), unit = 'inch', rotate = None, 
00924                                        ref = "center center", xoffset = 0, yoffset = 0, east = None, north = None)
00925         # current values
00926         self.instruction = dict(self.defaultInstruction)
00927         
00928     def __str__(self):
00929         text = self.instruction['text'].replace('\n','\\n')
00930         instr = "text %s %s" % (self.instruction['east'], self.instruction['north'])
00931         try:
00932             instr += " %s\n" % text.encode('latin_1')
00933         except UnicodeEncodeError, err:
00934             try:
00935                 pos = str(err).split('position')[1].split(':')[0].strip()
00936             except IndexError:
00937                 pos = ''
00938             if pos:
00939                 message = _("Characters on position %s are not supported "
00940                             "by ISO-8859-1 (Latin 1) encoding "
00941                             "which is required by module ps.map.") % pos
00942             else:
00943                 message = _("Not all characters are supported "
00944                             "by ISO-8859-1 (Latin 1) encoding "
00945                             "which is required by module ps.map.")
00946             GMessage(message = message)
00947             return ''
00948         instr += (string.Template("    font $font\n    fontsize $fontsize\n    color $color\n").
00949                                                                    substitute(self.instruction).
00950                                                                    encode('latin_1'))
00951         instr += string.Template("    hcolor $hcolor\n").substitute(self.instruction).encode('latin_1')
00952         if self.instruction['hcolor'] != 'none':
00953             instr += string.Template("    hwidth $hwidth\n").substitute(self.instruction).encode('latin_1')
00954         instr += string.Template("    border $border\n").substitute(self.instruction).encode('latin_1')
00955         if self.instruction['border'] != 'none':
00956             instr += string.Template("    width $width\n").substitute(self.instruction).encode('latin_1')
00957         instr += string.Template("    background $background\n").substitute(self.instruction).encode('latin_1')
00958         if self.instruction["ref"] != '0':
00959             instr += string.Template("    ref $ref\n").substitute(self.instruction).encode('latin_1')
00960         if self.instruction["rotate"]:
00961             instr += string.Template("    rotate $rotate\n").substitute(self.instruction).encode('latin_1')
00962         if float(self.instruction["xoffset"]) or float(self.instruction["yoffset"]):
00963             instr += (string.Template("    xoffset $xoffset\n    yoffset $yoffset\n").
00964                                                             substitute(self.instruction).encode('latin_1'))
00965         instr += "    end"
00966         return instr
00967     
00968     def Read(self, instruction, text, **kwargs):
00969         """!Read instruction and save information"""
00970         map = kwargs['mapInstruction']
00971         instr = {}
00972         for line in text:
00973             try:
00974                 sub = line.split(None, 1)[0]
00975                 if sub == 'text':
00976                     e, n = line.split(None, 3)[1:3]
00977                     if '%' in e and '%' in n:
00978                         instr['XY'] = True
00979                         instr['east'], instr['north'] = self.PercentToReal(e, n)
00980                     else:
00981                         instr['XY'] = False
00982                         instr['east'], instr['north'] = float(e), float(n)
00983                         
00984                     instr['text'] = line.split(None, 3)[3]
00985                 
00986                 elif sub == 'font':
00987                     instr['font'] = line.split(None, 1)[1]
00988                 elif sub == 'fontsize':
00989                     instr['fontsize'] = float(line.split(None, 1)[1])
00990                 elif sub == 'color':
00991                     instr['color'] = line.split(None, 1)[1]
00992                 elif sub == 'width':
00993                     instr['width'] = line.split(None, 1)[1]
00994                 elif sub == 'hcolor':
00995                     instr['hcolor'] = line.split(None, 1)[1]
00996                 elif sub == 'hwidth':
00997                     instr['hwidth'] = line.split(None, 1)[1]
00998                 elif sub == 'background':
00999                     instr['background'] = line.split(None, 1)[1]
01000                 elif sub == 'border':
01001                     instr['border'] = line.split(None, 1)[1]
01002                 elif sub == 'ref':
01003                     instr['ref'] = line.split(None, 1)[1]
01004                 elif sub == 'rotate':
01005                     instr['rotate'] = float(line.split(None, 1)[1])
01006                 elif sub == 'xoffset':
01007                     instr['xoffset'] = int(line.split(None, 1)[1])
01008                 elif sub == 'yoffset':
01009                     instr['yoffset'] = int(line.split(None, 1)[1])
01010                 elif sub == 'opaque':
01011                     if line.split(None, 1)[1].lower() in ('n', 'none'):
01012                         instr['background'] = 'none'
01013                         
01014             except(IndexError, ValueError):
01015                 GError(_("Failed to read instruction %s") % instruction)
01016                 return False
01017         instr['where'] = PaperMapCoordinates(map = map, x = instr['east'], y = instr['north'], paperToMap = False)       
01018         self.instruction.update(instr)
01019 
01020         return True 
01021     
01022     def PercentToReal(self, e, n):
01023         """!Converts text coordinates from percent of region to map coordinates"""
01024         e, n = float(e.strip('%')), float(n.strip('%'))
01025         region = grass.region()
01026         N = region['s'] + (region['n'] - region['s']) / 100 * n
01027         E = region['w'] + (region['e'] - region['w']) / 100 * e
01028         return E, N
01029     
01030 class Scalebar(InstructionObject):
01031     """!Class representing scalebar instruction"""
01032     def __init__(self, id):
01033         InstructionObject.__init__(self, id = id)
01034         self.type = 'scalebar'
01035         # default values
01036         self.defaultInstruction = dict(unit = 'inch', where = (1,1),
01037                                        unitsLength = 'auto', unitsHeight = 'inch',
01038                                        length = None, height = 0.1, rect = None,
01039                                        fontsize = 10, background = 'y',
01040                                        scalebar = 'f', segment = 4, numbers = 1)
01041         # current values
01042         self.instruction = dict(self.defaultInstruction)
01043         
01044     def __str__(self):
01045         instr = string.Template("scalebar $scalebar\n").substitute(self.instruction)
01046         instr += "    where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
01047         instr += string.Template("    length $length\n    units $unitsLength\n").substitute(self.instruction)
01048         instr += string.Template("    height $height\n").substitute(self.instruction)
01049         instr += string.Template("    segment $segment\n    numbers $numbers\n").substitute(self.instruction)
01050         instr += string.Template("    fontsize $fontsize\n    background $background\n").substitute(self.instruction)
01051         instr += "    end"
01052         return instr
01053     
01054     def Read(self, instruction, text, **kwargs):
01055         """!Read instruction and save information"""
01056         scale = kwargs['scale']
01057         instr = {}
01058         for line in text:
01059             try:
01060                 if line.startswith('scalebar'):
01061                     if 'scalebar s' in line:
01062                         instr['scalebar'] = 's'
01063                     else:
01064                         instr['scalebar'] = 'f'
01065                 elif line.startswith('where'):
01066                     instr['where'] = map(float, line.split()[1:3])
01067                 elif line.startswith('length'):
01068                     instr['length'] = float(line.split()[1])
01069                 elif line.startswith('units'):
01070                     if line.split()[1] in ['auto', 'meters', 'kilometers', 'feet', 'miles', 'nautmiles']:
01071                         instr['unitsLength'] = line.split()[1]
01072                 elif line.startswith('height'):
01073                     instr['height'] = float(line.split()[1])
01074                 elif line.startswith('fontsize'):
01075                     instr['fontsize'] = float(line.split()[1])
01076                 elif line.startswith('numbers'):
01077                     instr['numbers'] = int(line.split()[1])
01078                 elif line.startswith('segment'):
01079                     instr['segment'] = int(line.split()[1])
01080                 elif line.startswith('background'):
01081                     if line.split()[1].strip().lower() in ('y','yes'):
01082                         instr['background'] = 'y'
01083                     elif line.split()[1].strip().lower() in ('n','no', 'none'):
01084                         instr['background'] = 'n'
01085             except(IndexError, ValueError):
01086                 GError(_("Failed to read instruction %s") % instruction)
01087                 return False
01088             
01089         self.instruction.update(instr)
01090         w, h = self.EstimateSize(scalebarDict = self.instruction, scale = scale)
01091         x = self.instruction['where'][0] - w / 2 
01092         y = self.instruction['where'][1] - h / 2
01093         self.instruction['rect'] = wx.Rect2D(x, y, w, h)
01094         return True 
01095     
01096     def EstimateSize(self, scalebarDict, scale):
01097         """!Estimate size to draw scalebar"""
01098         units = projInfo()['units']
01099         if not units or units not in self.unitConv.getAllUnits():
01100             units = 'meters'
01101         if scalebarDict['unitsLength'] != 'auto':
01102             length = self.unitConv.convert(value = scalebarDict['length'], fromUnit = scalebarDict['unitsLength'], toUnit = 'inch')
01103         else:
01104             length = self.unitConv.convert(value = scalebarDict['length'], fromUnit = units, toUnit = 'inch')
01105             
01106         length *= scale
01107         length *= 1.1 #for numbers on the edge
01108         height = scalebarDict['height'] + 2 * self.unitConv.convert(value = scalebarDict['fontsize'], fromUnit = 'point', toUnit = 'inch')     
01109         return (length, height)
01110     
01111 class RasterLegend(InstructionObject):
01112     """!Class representing colortable instruction"""
01113     def __init__(self, id):
01114         InstructionObject.__init__(self, id = id)
01115         self.type = 'rasterLegend'
01116         # default values
01117         self.defaultInstruction = dict(rLegend = False, unit = 'inch', rasterDefault = True, raster = None,
01118                                        discrete = None, type = None,
01119                                        where = (0, 0),
01120                                        width = None, height = None, cols = 1, font = "Helvetica", fontsize = 10,
01121                                        #color = '0:0:0', tickbar = False, range = False, min = 0, max = 0,
01122                                        color = 'black', tickbar = 'n', range = False, min = 0, max = 0,
01123                                        nodata = 'n')
01124         # current values
01125         self.instruction = dict(self.defaultInstruction)
01126         
01127     def __str__(self):
01128         instr = "colortable y\n"
01129         instr += string.Template("    raster $raster\n").substitute(self.instruction)
01130         instr += "    where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
01131         if self.instruction['width']:
01132             instr += string.Template("    width $width\n").substitute(self.instruction)
01133         instr += string.Template("    discrete $discrete\n").substitute(self.instruction)
01134         if self.instruction['discrete'] == 'n':
01135             if self.instruction['height']:
01136                 instr += string.Template("    height $height\n").substitute(self.instruction)
01137             instr += string.Template("    tickbar $tickbar\n").substitute(self.instruction)
01138             if self.instruction['range']:
01139                 instr += string.Template("    range $min $max\n").substitute(self.instruction)
01140         else:
01141             instr += string.Template("    cols $cols\n").substitute(self.instruction)
01142             instr += string.Template("    nodata $nodata\n").substitute(self.instruction)
01143         instr += string.Template("    font $font\n    fontsize $fontsize\n    color $color\n")\
01144             .substitute(self.instruction)
01145         instr += "    end"
01146         return instr    
01147     
01148     
01149     def Read(self, instruction, text, **kwargs):
01150         """!Read instruction and save information"""
01151         instr = {}
01152         instr['rLegend'] = True
01153         for line in text:
01154             try:
01155                 if line.startswith('where'):
01156                     instr['where'] = map(float, line.split()[1:3])
01157                 elif line.startswith('font '):
01158                     instr['font'] = line.split()[1]
01159                 elif line.startswith('fontsize'):
01160                     instr['fontsize'] = float(line.split()[1])
01161                 elif line.startswith('color '):
01162                     instr['color'] = line.split()[1]
01163                 elif line.startswith('raster'):
01164                     instr['raster'] = line.split()[1]
01165                 elif line.startswith('width'):
01166                     instr['width'] = float(line.split()[1])
01167                 elif line.startswith('height'):
01168                     instr['height'] = float(line.split()[1])
01169                 elif line.startswith('cols'):
01170                     instr['cols'] = int(line.split()[1])                    
01171                 elif line.startswith('range'):
01172                     instr['range'] = True
01173                     instr['min'] = float(line.split()[1])
01174                     instr['max'] = float(line.split()[2])
01175                 elif line.startswith('nodata'):
01176                     if line.split()[1].strip().lower() in ('y','yes'):
01177                         instr['nodata'] = 'y'
01178                     elif line.split()[1].strip().lower() in ('n','no', 'none'):
01179                         instr['nodata'] = 'n'
01180                 elif line.startswith('tickbar'):
01181                     if line.split()[1].strip().lower() in ('y','yes'):
01182                         instr['tickbar'] = 'y'
01183                     elif line.split()[1].strip().lower() in ('n','no', 'none'):
01184                         instr['tickbar'] = 'n'
01185                 elif line.startswith('discrete'):
01186                     if line.split()[1].strip().lower() in ('y','yes'):
01187                         instr['discrete'] = 'y'
01188                     elif line.split()[1].strip().lower() in ('n','no', 'none'):
01189                         instr['discrete'] = 'n'            
01190 
01191             except(IndexError, ValueError):
01192                 GError(_("Failed to read instruction %s") % instruction)
01193                 return False
01194             
01195         if 'raster' in instr:
01196             instr['rasterDefault'] = False
01197             if 'discrete' not in instr:
01198                 rasterType = getRasterType(map = instr['raster'])
01199                 instr['type'] = rasterType
01200                 if rasterType == 'CELL':
01201                     instr['discrete'] = 'y'
01202                 else:
01203                     instr['discrete'] = 'n'
01204             
01205         else:
01206             instr['rasterDefault'] = True
01207         self.instruction.update(instr)
01208         # add 'rect' in the end
01209             
01210         return True 
01211     
01212     def EstimateHeight(self, raster, discrete, fontsize, cols = None,  height = None):
01213         """!Estimate height to draw raster legend"""
01214         if discrete == 'n':
01215             if height:
01216                 height = height
01217             else:
01218                 height = self.unitConv.convert(value = fontsize * 10,
01219                                                     fromUnit = 'point', toUnit = 'inch')
01220                                                     
01221         if discrete == 'y':
01222             if cols:
01223                 cols = cols 
01224             else:
01225                 cols = 1 
01226 
01227             rinfo = grass.raster_info(raster)
01228             if rinfo['datatype'] in ('DCELL', 'FCELL'):
01229                 minim, maxim = rinfo['min'], rinfo['max']
01230                 rows = ceil(maxim / cols )
01231             else:
01232                 cat = grass.read_command('r.category', map = raster,
01233                                     fs = ':').strip().split('\n')
01234                 rows = ceil(float(len(cat)) / cols )
01235                             
01236                 
01237             height = self.unitConv.convert(value =  1.5 * rows * fontsize, fromUnit = 'point', toUnit = 'inch')
01238             
01239         return height
01240         
01241     def EstimateWidth(self, raster, discrete, fontsize, cols = None, width = None, paperInstr = None):
01242         """!Estimate size to draw raster legend"""
01243         
01244         if discrete == 'n':
01245             rinfo = grass.raster_info(raster)
01246             minim, maxim = rinfo['min'], rinfo['max']
01247             if width:
01248                 width = width
01249             else:
01250                 width = self.unitConv.convert(value = fontsize * 2,
01251                                                     fromUnit = 'point', toUnit = 'inch')
01252             text = len(max(str(minim), str(maxim), key = len))
01253             textPart = self.unitConv.convert(value = text * fontsize / 2,
01254                                                     fromUnit = 'point', toUnit = 'inch')
01255             width += textPart
01256                                                     
01257         elif discrete == 'y':
01258             if cols:
01259                 cols = cols 
01260             else:
01261                 cols = 1    
01262 
01263             if width:
01264                 width = width
01265             else:
01266                 paperWidth = paperInstr['Width'] - paperInstr['Right'] - paperInstr['Left']
01267                 width = (paperWidth / cols) * (cols - 1) + 1
01268                 
01269         return width    
01270              
01271 class VectorLegend(InstructionObject):
01272     """!Class representing colortable instruction"""
01273     def __init__(self, id):
01274         InstructionObject.__init__(self, id = id)
01275         self.type = 'vectorLegend'
01276         # default values
01277         self.defaultInstruction = dict(vLegend = False, unit = 'inch', where = (0, 0),
01278                                                 defaultSize = True, width = 0.4, cols = 1, span = None,
01279                                                 font = "Helvetica", fontsize = 10,
01280                                                 border = 'none')
01281         # current values
01282         self.instruction = dict(self.defaultInstruction)
01283         
01284     def __str__(self):
01285         instr = "vlegend\n"
01286         instr += "    where %.3f %.3f\n" % (self.instruction['where'][0], self.instruction['where'][1])
01287         instr += string.Template("    font $font\n    fontsize $fontsize\n").substitute(self.instruction)
01288         instr += string.Template("    width $width\n    cols $cols\n").substitute(self.instruction)
01289         if self.instruction['span']:
01290             instr += string.Template("    span $span\n").substitute(self.instruction)
01291         instr += string.Template("    border $border\n").substitute(self.instruction)  
01292         instr += "    end"  
01293         return instr
01294 
01295     def Read(self, instruction, text, **kwargs):
01296         """!Read instruction and save information"""
01297         instr = {}
01298         instr['vLegend'] = True
01299         for line in text:
01300             try:
01301                 if line.startswith('where'):
01302                     instr['where'] = map(float, line.split()[1:3])
01303                 elif line.startswith('font '):
01304                     instr['font'] = line.split()[1]
01305                 elif line.startswith('fontsize'):
01306                     instr['fontsize'] = float(line.split()[1])
01307                 elif line.startswith('width'):
01308                     instr['width'] = float(line.split()[1])
01309                 elif line.startswith('cols'):
01310                     instr['cols'] = int(line.split()[1]) 
01311                 elif line.startswith('span'):
01312                     instr['span'] = float(line.split()[1])
01313                 elif line.startswith('border'):
01314                     instr['border'] = line.split()[1]
01315                     
01316             except(IndexError, ValueError):
01317                 GError(_("Failed to read instruction %s") % instruction)
01318                 return False
01319             
01320         self.instruction.update(instr)
01321             
01322         return True 
01323     
01324     def EstimateSize(self, vectorInstr, fontsize, width = None, cols = None):
01325         """!Estimate size to draw vector legend"""
01326         if width:
01327             width = width 
01328         else:
01329             width = fontsize/24.0
01330 
01331         if cols:
01332             cols = cols 
01333         else:
01334             cols = 1
01335 
01336         vectors = vectorInstr['list']
01337         labels = [vector[4] for vector in vectors if vector[3] != 0]
01338         extent = (len(max(labels, key = len)) * fontsize / 2, fontsize)
01339         wExtent = self.unitConv.convert(value = extent[0], fromUnit = 'point', toUnit = 'inch')
01340         hExtent = self.unitConv.convert(value = extent[1], fromUnit = 'point', toUnit = 'inch')
01341         w = (width + wExtent) * cols
01342         h = len(labels) * hExtent / cols
01343         h *= 1.1
01344         return (w, h)
01345             
01346    
01347 class Raster(InstructionObject):
01348     """!Class representing raster instruction"""
01349     def __init__(self, id):
01350         InstructionObject.__init__(self, id = id)
01351         self.type = 'raster'
01352         # default values
01353         self.defaultInstruction = dict(isRaster = False, raster = None)
01354         # current values
01355         self.instruction = dict(self.defaultInstruction)
01356         
01357     def __str__(self):
01358         instr = string.Template("raster $raster").substitute(self.instruction)
01359         return instr
01360     
01361     def Read(self, instruction, text):
01362         """!Read instruction and save information"""
01363         instr = {}
01364         instr['isRaster'] = True
01365         try:
01366             map = text.split()[1]
01367         except IndexError:
01368             GError(_("Failed to read instruction %s") % instruction)
01369             return False
01370         try:
01371             info = grass.find_file(map, element = 'cell')
01372         except grass.ScriptError, e:
01373             GError(message = e.value)
01374             return False
01375         instr['raster'] = info['fullname']
01376 
01377         
01378         self.instruction.update(instr)
01379         return True
01380     
01381 class Vector(InstructionObject):
01382     """!Class keeps vector layers"""
01383     def __init__(self, id):
01384         InstructionObject.__init__(self, id = id)
01385         self.type = 'vector'
01386         # default values
01387         self.defaultInstruction = dict(list = None)# [vmap, type, id, lpos, label] 
01388         # current values
01389         self.instruction = dict(self.defaultInstruction)
01390     def __str__(self):
01391         return ''
01392     
01393     def Read(self, instruction, text, **kwargs):
01394         """!Read instruction and save information"""
01395         instr = {}
01396         
01397         for line in text:
01398             if line.startswith('vpoints') or line.startswith('vlines') or line.startswith('vareas'):
01399                 # subtype
01400                 if line.startswith('vpoints'):
01401                     subType = 'points'
01402                 elif line.startswith('vlines'):
01403                     subType = 'lines'
01404                 elif line.startswith('vareas'):
01405                     subType = 'areas'
01406                 # name of vector map
01407                 vmap = line.split()[1]
01408                 try:
01409                     info = grass.find_file(vmap, element = 'vector')
01410                 except grass.ScriptError, e:
01411                     GError(message = e.value)
01412                     return False
01413                 vmap = info['fullname']
01414                 # id
01415                 id = kwargs['id']
01416                 # lpos
01417                 lpos = kwargs['vectorMapNumber']
01418                 #label
01419                 label = '('.join(vmap.split('@')) + ')'
01420                 break
01421         instr = [vmap, subType, id, lpos, label] 
01422         if not self.instruction['list']:
01423             self.instruction['list'] = []
01424         self.instruction['list'].append(instr)
01425         
01426         return True    
01427     
01428 class VProperties(InstructionObject):
01429     """!Class represents instructions vareas, vlines, vpoints"""
01430     def __init__(self, id, subType):
01431         InstructionObject.__init__(self, id = id)
01432         self.type = 'vProperties'
01433         self.subType = subType
01434         # default values
01435         if self.subType == 'points':
01436             dd = dict(subType  = 'points', name = None, type = 'point or centroid', connection = False, layer = '1',
01437                         masked = 'n', color = '0:0:0', width = 1,
01438                         fcolor = '255:0:0', rgbcolumn = None, symbol = os.path.join('basic', 'x'), eps = None,
01439                         size = 5, sizecolumn = None, scale = None,
01440                         rotation = False, rotate = 0, rotatecolumn = None, label = None, lpos = None)
01441         elif self.subType == 'lines':
01442             dd = dict(subType = 'lines', name = None, type = 'line or boundary', connection = False, layer = '1',
01443                         masked = 'n', color = '0:0:0', hwidth = 1,
01444                         hcolor = 'none', rgbcolumn = None,
01445                         width = 1, cwidth = None,
01446                         style = 'solid', linecap = 'butt', label = None, lpos = None)
01447         else: # areas
01448             dd = dict(subType = 'areas', name = None, connection = False, layer = '1',    
01449                         masked = 'n', color = '0:0:0', width = 1,
01450                         fcolor = 'none', rgbcolumn = None,
01451                         pat = None, pwidth = 1, scale = 1, label = None, lpos = None)
01452         self.defaultInstruction = dd
01453         # current values
01454         self.instruction = dict(self.defaultInstruction)
01455         
01456     def __str__(self):
01457         dic = self.instruction
01458         vInstruction = string.Template("v$subType $name\n").substitute(dic)
01459         #data selection
01460         if self.subType in ('points', 'lines'):
01461            vInstruction += string.Template("    type $type\n").substitute(dic) 
01462         if dic['connection']:
01463             vInstruction += string.Template("    layer $layer\n").substitute(dic)
01464             if dic.has_key('cats'):
01465                 vInstruction += string.Template("    cats $cats\n").substitute(dic)
01466             elif dic.has_key('where'):
01467                     vInstruction += string.Template("    where $where\n").substitute(dic)
01468         vInstruction += string.Template("    masked $masked\n").substitute(dic)
01469         #colors
01470         vInstruction += string.Template("    color $color\n").substitute(dic)
01471         if self.subType in ('points', 'areas'):
01472             if dic['color'] != 'none':
01473                 vInstruction += string.Template("    width $width\n").substitute(dic)
01474             if dic['rgbcolumn']:
01475                 vInstruction += string.Template("    rgbcolumn $rgbcolumn\n").substitute(dic)
01476             vInstruction += string.Template("    fcolor $fcolor\n").substitute(dic)
01477         else:
01478             if dic['rgbcolumn']:
01479                 vInstruction += string.Template("    rgbcolumn $rgbcolumn\n").substitute(dic)
01480             elif dic['hcolor'] != 'none':
01481                 vInstruction += string.Template("    hwidth $hwidth\n").substitute(dic)
01482                 vInstruction += string.Template("    hcolor $hcolor\n").substitute(dic)
01483         
01484         # size and style
01485         if self.subType == 'points':
01486             if dic['symbol']:
01487                 vInstruction += string.Template("    symbol $symbol\n").substitute(dic)
01488             else: #eps
01489                 vInstruction += string.Template("    eps $eps\n").substitute(dic)
01490             if dic['size']:
01491                 vInstruction += string.Template("    size $size\n").substitute(dic)            
01492             else: # sizecolumn
01493                 vInstruction += string.Template("    sizecolumn $sizecolumn\n").substitute(dic)
01494                 vInstruction += string.Template("    scale $scale\n").substitute(dic)
01495             if dic['rotation']:
01496                 if dic['rotate'] is not None:
01497                     vInstruction += string.Template("    rotate $rotate\n").substitute(dic)
01498                 else:
01499                     vInstruction += string.Template("    rotatecolumn $rotatecolumn\n").substitute(dic)
01500                     
01501         if self.subType == 'areas':
01502             if dic['pat'] is not None:
01503                 vInstruction += string.Template("    pat $pat\n").substitute(dic)
01504                 vInstruction += string.Template("    pwidth $pwidth\n").substitute(dic)
01505                 vInstruction += string.Template("    scale $scale\n").substitute(dic)
01506                 
01507         if self.subType == 'lines':
01508             if dic['width'] is not None:
01509                 vInstruction += string.Template("    width $width\n").substitute(dic)
01510             else:
01511                 vInstruction += string.Template("    cwidth $cwidth\n").substitute(dic)
01512             vInstruction += string.Template("    style $style\n").substitute(dic)
01513             vInstruction += string.Template("    linecap $linecap\n").substitute(dic)
01514         #position and label in vlegend
01515         vInstruction += string.Template("    label $label\n    lpos $lpos\n").substitute(dic)
01516         
01517         vInstruction += "    end"
01518         return vInstruction
01519     
01520     def Read(self, instruction, text, **kwargs):
01521         """!Read instruction and save information"""
01522         instr = {}
01523         try:
01524             info = grass.find_file(name = text[0].split()[1], element = 'vector')
01525         except grass.ScriptError, e:
01526             GError(message = e.value)
01527             return False
01528         instr['name'] = info['fullname']
01529         #connection
01530         instr['connection'] = True
01531         self.mapDBInfo = dbm_base.VectorDBInfo(instr['name'])
01532         self.layers = self.mapDBInfo.layers.keys()
01533         if not self.layers:
01534             instr['connection'] = False
01535             
01536         # points
01537         if text[0].startswith('vpoints'):
01538             for line in text[1:]:
01539                 if line.startswith('type'):
01540                     tp = []
01541                     if line.find('point') != -1:
01542                         tp.append('point')
01543                     if line.find('centroid') != -1:
01544                         tp.append('centroid')
01545                     instr['type'] = ' or '.join(tp)
01546                 elif line.startswith('fcolor'):
01547                     instr['fcolor'] = line.split()[1]
01548                 elif line.startswith('rgbcolumn'):
01549                     instr['rgbcolumn'] = line.split()[1]
01550                 elif line.startswith('symbol'):
01551                     instr['symbol'] = line.split()[1]
01552                 elif line.startswith('eps'):
01553                     instr['eps'] = line.split()[1]
01554                 elif line.startswith('size '):
01555                     instr['size'] = line.split()[1]
01556                 elif line.startswith('sizecolumn'):
01557                     instr['size'] = None
01558                     instr['sizecolumn'] = line.split()[1]
01559                 elif line.startswith('scale '):
01560                     instr['scale'] = float(line.split()[1])
01561                 elif line.startswith('rotate '):
01562                     instr['rotation'] = True
01563                     instr['rotate'] = line.split()[1]
01564                 elif line.startswith('rotatecolumn'):
01565                     instr['rotatecolumn'] = line.split()[1]
01566                     instr['rotation'] = True
01567                     instr['rotate'] = None
01568                     
01569         # lines            
01570         elif text[0].startswith('vlines'):
01571             for line in text[1:]:
01572                 if line.startswith('type'):
01573                     tp = []
01574                     if line.find('line') != -1:
01575                         tp.append('line')
01576                     if line.find('boundary') != -1:
01577                         tp.append('boundary')
01578                     instr['type'] = ' or '.join(tp)
01579                 elif line.startswith('hwidth'):
01580                     instr['hwidth'] = float(line.split()[1])
01581                 elif line.startswith('hcolor'):
01582                     instr['hcolor'] = line.split()[1]
01583                 elif line.startswith('rgbcolumn'):
01584                     instr['rgbcolumn'] = line.split()[1]                    
01585                 elif line.startswith('cwidth'):
01586                     instr['cwidth'] = float(line.split()[1])
01587                     instr['width'] = None
01588                 elif line.startswith('style'):
01589                     instr['style'] = line.split()[1]       
01590                 elif line.startswith('linecap'):
01591                     instr['linecap'] = line.split()[1]
01592          
01593         elif text[0].startswith('vareas'):
01594             for line in text[1:]:
01595                 if line.startswith('fcolor'):
01596                     instr['fcolor'] = line.split()[1]    
01597                 elif line.startswith('pat'):
01598                     instr['pat'] = line.split()[1]
01599                 elif line.startswith('pwidth'):
01600                     instr['pwidth'] = float(line.split()[1])
01601                 elif line.startswith('scale'):
01602                     instr['scale'] = float(line.split()[1])
01603             
01604             
01605         # same properties for all    
01606         for line in text[1:]:
01607             if line.startswith('lpos'):
01608                 instr['lpos'] = int(line.split()[1])
01609             elif line.startswith('label'):
01610                 instr['label'] = line.split(None, 1)[1]
01611             elif line.startswith('layer'):
01612                 instr['layer'] = line.split()[1]
01613             elif line.startswith('masked'):
01614                 if line.split()[1].lower() in ('y', 'yes'):
01615                     instr['masked'] = 'y'
01616                 else:
01617                     instr['masked'] = 'n'
01618             elif line.startswith('color'):
01619                 instr['color'] = line.split()[1]
01620             elif line.startswith('rgbcolumn'):
01621                 instr['rgbcolumn'] = line.split()[1] 
01622             elif line.startswith('width'):
01623                 instr['width'] = float(line.split()[1])
01624                 
01625         if 'label' not in instr:
01626             instr['label'] = '('.join(instr['name'].split('@')) + ')'
01627         if 'lpos' not in instr:
01628             instr['lpos'] = kwargs['vectorMapNumber']
01629         self.instruction.update(instr)
01630         
01631         return True
01632         
01633 class PsmapDialog(wx.Dialog):
01634     def __init__(self, parent, id,  title, settings, apply = True):
01635         wx.Dialog.__init__(self, parent = parent, id = wx.ID_ANY, 
01636                             title = title, size = wx.DefaultSize,
01637                             style = wx.CAPTION|wx.MINIMIZE_BOX|wx.CLOSE_BOX)
01638         self.apply = apply
01639         self.id = id
01640         self.parent = parent
01641         self.instruction = settings
01642         self.objectType = None
01643         self.unitConv = UnitConversion(self)
01644         self.spinCtrlSize = (50, -1)
01645         
01646         self.Bind(wx.EVT_CLOSE, self.OnClose)
01647         
01648     
01649         
01650     def AddUnits(self, parent, dialogDict):
01651         parent.units = dict()
01652         parent.units['unitsLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Units:"))
01653         choices = self.unitConv.getPageUnitsNames()
01654         parent.units['unitsCtrl'] = wx.Choice(parent, id = wx.ID_ANY, choices = choices)  
01655         parent.units['unitsCtrl'].SetStringSelection(self.unitConv.findName(dialogDict['unit']))
01656           
01657     def AddPosition(self, parent, dialogDict):
01658         parent.position = dict()
01659         parent.position['comment'] = wx.StaticText(parent, id = wx.ID_ANY,\
01660                     label = _("Position of the top left corner\nfrom the top left edge of the paper"))
01661         parent.position['xLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("X:"))
01662         parent.position['yLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Y:"))
01663         parent.position['xCtrl'] = wx.TextCtrl(parent, id = wx.ID_ANY, value = str(dialogDict['where'][0]), validator = TCValidator(flag = 'DIGIT_ONLY'))
01664         parent.position['yCtrl'] = wx.TextCtrl(parent, id = wx.ID_ANY, value = str(dialogDict['where'][1]), validator = TCValidator(flag = 'DIGIT_ONLY'))
01665         if dialogDict.has_key('unit'):
01666             x = self.unitConv.convert(value = dialogDict['where'][0], fromUnit = 'inch', toUnit = dialogDict['unit'])
01667             y = self.unitConv.convert(value = dialogDict['where'][1], fromUnit = 'inch', toUnit = dialogDict['unit'])
01668             parent.position['xCtrl'].SetValue("%5.3f" % x)
01669             parent.position['yCtrl'].SetValue("%5.3f" % y)
01670         
01671     def AddFont(self, parent, dialogDict, color = True):
01672         parent.font = dict()
01673 ##        parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose font:"))
01674 ##        parent.font['fontCtrl'] = wx.FontPickerCtrl(parent, id = wx.ID_ANY)
01675 ##        
01676 ##        parent.font['fontCtrl'].SetSelectedFont(
01677 ##                        wx.FontFromNativeInfoString(dialogDict['font'] + " " + str(dialogDict['fontsize'])))
01678 ##        parent.font['fontCtrl'].SetMaxPointSize(50)
01679 ##        
01680 ##        if color:
01681 ##            parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:"))
01682 ##            parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY, style=wx.FNTP_FONTDESC_AS_LABEL)
01683 ##            parent.font['colorCtrl'].SetColour(dialogDict['color'])
01684            
01685 ##        parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color'])) 
01686            
01687         parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Font:"))
01688         parent.font['fontSizeLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Font size:"))
01689         fontChoices = [ 'Times-Roman', 'Times-Italic', 'Times-Bold', 'Times-BoldItalic', 'Helvetica',\
01690                         'Helvetica-Oblique', 'Helvetica-Bold', 'Helvetica-BoldOblique', 'Courier',\
01691                         'Courier-Oblique', 'Courier-Bold', 'Courier-BoldOblique'] 
01692         parent.font['fontCtrl'] = wx.Choice(parent, id = wx.ID_ANY, choices = fontChoices)
01693         if dialogDict['font'] in fontChoices:
01694             parent.font['fontCtrl'].SetStringSelection(dialogDict['font'])
01695         else:
01696             parent.font['fontCtrl'].SetStringSelection('Helvetica')
01697         parent.font['fontSizeCtrl'] = wx.SpinCtrl(parent, id = wx.ID_ANY, min = 4, max = 50, initial = 10)
01698         parent.font['fontSizeCtrl'].SetValue(dialogDict['fontsize'])
01699          
01700         if color:
01701             parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:"))
01702             parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY)
01703             parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color']))
01704 ##            parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Color:"))
01705 ##            colorChoices = [  'aqua', 'black', 'blue', 'brown', 'cyan', 'gray', 'green', 'indigo', 'magenta',\
01706 ##                                'orange', 'purple', 'red', 'violet', 'white', 'yellow']
01707 ##            parent.colorCtrl = wx.Choice(parent, id = wx.ID_ANY, choices = colorChoices)
01708 ##            parent.colorCtrl.SetStringSelection(parent.rLegendDict['color'])
01709 ##            parent.font['colorCtrl'] = wx.ColourPickerCtrl(parent, id = wx.ID_ANY)
01710 ##            parent.font['colorCtrl'].SetColour(dialogDict['color'])   
01711     def OnApply(self, event):
01712         ok = self.update()
01713         if ok:
01714             self.parent.DialogDataChanged(id = self.id)
01715             return True 
01716         else:
01717             return False
01718         
01719     def OnOK(self, event):
01720         """!Apply changes, close dialog"""
01721         ok = self.OnApply(event)
01722         if ok:
01723             self.Close()
01724     
01725     def OnCancel(self, event):
01726         """!Close dialog"""
01727         self.Close()
01728 
01729     def OnClose(self, event):
01730         """!Destroy dialog and delete it from open dialogs"""
01731         if self.objectType:
01732             for each in  self.objectType:
01733                 if each in self.parent.openDialogs:
01734                     del self.parent.openDialogs[each]
01735         event.Skip()
01736         self.Destroy()
01737         
01738     def _layout(self, panel):
01739         #buttons
01740         btnCancel = wx.Button(self, wx.ID_CANCEL)
01741         btnOK = wx.Button(self, wx.ID_OK)
01742         btnOK.SetDefault()
01743         if self.apply:
01744             btnApply = wx.Button(self, wx.ID_APPLY)
01745         
01746 
01747         # bindigs
01748         btnOK.Bind(wx.EVT_BUTTON, self.OnOK)
01749         btnOK.SetToolTipString(_("Close dialog and apply changes"))
01750         #btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
01751         btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
01752         btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
01753         if self.apply:
01754             btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
01755             btnApply.SetToolTipString(_("Apply changes"))
01756         
01757         # sizers
01758         btnSizer = wx.StdDialogButtonSizer()
01759         btnSizer.AddButton(btnCancel)
01760         if self.apply:
01761             btnSizer.AddButton(btnApply)
01762         btnSizer.AddButton(btnOK)
01763         btnSizer.Realize()
01764         
01765         mainSizer = wx.BoxSizer(wx.VERTICAL)
01766         mainSizer.Add(item = panel, proportion = 1, flag = wx.EXPAND | wx.ALL, border = 5)
01767         mainSizer.Add(item = btnSizer, proportion = 0,
01768                       flag = wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border = 5)
01769         
01770         
01771         self.SetSizer(mainSizer)
01772         mainSizer.Layout()
01773         mainSizer.Fit(self) 
01774             
01775 class PageSetupDialog(PsmapDialog):
01776     def __init__(self, parent, id, settings):
01777         PsmapDialog.__init__(self, parent = parent, id = id, title = "Page setup",  settings = settings)
01778         
01779         self.cat = ['Units', 'Format', 'Orientation', 'Width', 'Height', 'Left', 'Right', 'Top', 'Bottom']
01780         labels = [_('Units'), _('Format'), _('Orientation'), _('Width'), _('Height'),
01781                   _('Left'), _('Right'), _('Top'), _('Bottom')]
01782         self.catsLabels = dict(zip(self.cat, labels))
01783         paperString = RunCommand('ps.map', flags = 'p', read = True, quiet = True)
01784         self.paperTable = self._toList(paperString) 
01785         self.unitsList = self.unitConv.getPageUnitsNames()
01786         self.pageSetupDict = settings[id].GetInstruction()
01787 
01788         self._layout()
01789         
01790         if self.pageSetupDict:
01791             self.getCtrl('Units').SetStringSelection(self.unitConv.findName(self.pageSetupDict['Units']))
01792             if self.pageSetupDict['Format'] == 'custom':
01793                 self.getCtrl('Format').SetSelection(self.getCtrl('Format').GetCount() - 1)
01794             else:
01795                 self.getCtrl('Format').SetStringSelection(self.pageSetupDict['Format'])
01796             if self.pageSetupDict['Orientation'] == 'Portrait':
01797                 self.getCtrl('Orientation').SetSelection(0)
01798             else:
01799                 self.getCtrl('Orientation').SetSelection(1)
01800                 
01801             for item in self.cat[3:]:
01802                 val = self.unitConv.convert(value = self.pageSetupDict[item],
01803                                             fromUnit = 'inch', toUnit = self.pageSetupDict['Units'])
01804                 self.getCtrl(item).SetValue("%4.3f" % val)
01805 
01806        
01807         if self.getCtrl('Format').GetSelection() != self.getCtrl('Format').GetCount() - 1: # custom
01808             self.getCtrl('Width').Disable()
01809             self.getCtrl('Height').Disable()
01810         else:
01811             self.getCtrl('Orientation').Disable()
01812         # events
01813         self.getCtrl('Units').Bind(wx.EVT_CHOICE, self.OnChoice)
01814         self.getCtrl('Format').Bind(wx.EVT_CHOICE, self.OnChoice)
01815         self.getCtrl('Orientation').Bind(wx.EVT_CHOICE, self.OnChoice)
01816         self.btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
01817 
01818     
01819     def update(self):
01820         self.pageSetupDict['Units'] = self.unitConv.findUnit(self.getCtrl('Units').GetStringSelection())
01821         self.pageSetupDict['Format'] = self.paperTable[self.getCtrl('Format').GetSelection()]['Format']
01822         if self.getCtrl('Orientation').GetSelection() == 0:
01823             self.pageSetupDict['Orientation'] = 'Portrait'
01824         else:
01825             self.pageSetupDict['Orientation'] = 'Landscape'
01826         for item in self.cat[3:]:
01827             self.pageSetupDict[item] = self.unitConv.convert(value = float(self.getCtrl(item).GetValue()),
01828                                         fromUnit = self.pageSetupDict['Units'], toUnit = 'inch')
01829             
01830 
01831             
01832     def OnOK(self, event):
01833         try:
01834             self.update()
01835         except ValueError:
01836                 wx.MessageBox(message = _("Literal is not allowed!"), caption = _('Invalid input'),
01837                                     style = wx.OK|wx.ICON_ERROR)
01838         else:
01839             event.Skip()
01840         
01841     def _layout(self):
01842         size = (110,-1)
01843         #sizers
01844         mainSizer = wx.BoxSizer(wx.VERTICAL)
01845         pageBox = wx.StaticBox(self, id = wx.ID_ANY, label = " %s " % _("Page size"))
01846         pageSizer = wx.StaticBoxSizer(pageBox, wx.VERTICAL)
01847         marginBox = wx.StaticBox(self, id = wx.ID_ANY, label = " %s " % _("Margins"))
01848         marginSizer = wx.StaticBoxSizer(marginBox, wx.VERTICAL)
01849         horSizer = wx.BoxSizer(wx.HORIZONTAL) 
01850         #staticText + choice
01851         choices = [self.unitsList, [item['Format'] for item in self.paperTable], [_('Portrait'), _('Landscape')]]
01852         propor = [0,1,1]
01853         border = [5,3,3]
01854         self.hBoxDict={}
01855         for i, item in enumerate(self.cat[:3]):
01856             hBox = wx.BoxSizer(wx.HORIZONTAL)
01857             stText = wx.StaticText(self, id = wx.ID_ANY, label = self.catsLabels[item] + ':')
01858             choice = wx.Choice(self, id = wx.ID_ANY, choices = choices[i], size = size)
01859             hBox.Add(stText, proportion = propor[i], flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = border[i])
01860             hBox.Add(choice, proportion = 0, flag = wx.ALL, border = border[i])
01861             if item == 'Units':
01862                 hBox.Add(size,1) 
01863             self.hBoxDict[item] = hBox    
01864 
01865         #staticText + TextCtrl
01866         for item in self.cat[3:]:
01867             hBox = wx.BoxSizer(wx.HORIZONTAL)
01868             label = wx.StaticText(self, id = wx.ID_ANY, label = self.catsLabels[item] + ':')
01869             textctrl = wx.TextCtrl(self, id = wx.ID_ANY, size = size, value = '')
01870             hBox.Add(label, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 3)
01871             hBox.Add(textctrl, proportion = 0, flag = wx.ALIGN_CENTRE|wx.ALL, border = 3)
01872             self.hBoxDict[item] = hBox
01873          
01874         sizer = list([mainSizer] + [pageSizer]*4 + [marginSizer]*4)
01875         for i, item in enumerate(self.cat):
01876                 sizer[i].Add(self.hBoxDict[item], 0, wx.GROW|wx.RIGHT|wx.LEFT,5)
01877         # OK button
01878         btnSizer = wx.StdDialogButtonSizer()
01879         self.btnOk = wx.Button(self, wx.ID_OK)
01880         self.btnOk.SetDefault()
01881         btnSizer.AddButton(self.btnOk)
01882         btn = wx.Button(self, wx.ID_CANCEL)
01883         btnSizer.AddButton(btn)
01884         btnSizer.Realize()
01885     
01886     
01887         horSizer.Add(pageSizer, proportion = 0, flag = wx.LEFT|wx.RIGHT|wx.BOTTOM, border = 10)
01888         horSizer.Add(marginSizer, proportion = 0, flag = wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, border = 10)
01889         mainSizer.Add(horSizer, proportion = 0, border = 10)  
01890         mainSizer.Add(btnSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT|wx.ALL,  border = 10)      
01891         self.SetSizer(mainSizer)
01892         mainSizer.Fit(self)
01893     
01894     def OnChoice(self, event):
01895         currPaper = self.paperTable[self.getCtrl('Format').GetSelection()]
01896         currUnit = self.unitConv.findUnit(self.getCtrl('Units').GetStringSelection())
01897         currOrientIdx = self.getCtrl('Orientation').GetSelection()
01898         newSize = dict()
01899         for item in self.cat[3:]:
01900             newSize[item] = self.unitConv.convert(float(currPaper[item]), fromUnit = 'inch', toUnit = currUnit)
01901 
01902         enable = True
01903         if currPaper['Format'] != _('custom'):
01904             if currOrientIdx == 1: # portrait
01905                 newSize['Width'], newSize['Height'] = newSize['Height'], newSize['Width']
01906             for item in self.cat[3:]:
01907                 self.getCtrl(item).ChangeValue("%4.3f" % newSize[item])
01908             enable = False
01909         self.getCtrl('Width').Enable(enable)
01910         self.getCtrl('Height').Enable(enable)
01911         self.getCtrl('Orientation').Enable(not enable)
01912 
01913 
01914     def getCtrl(self, item):
01915          return self.hBoxDict[item].GetItem(1).GetWindow()
01916         
01917     def _toList(self, paperStr):
01918         
01919         sizeList = list()
01920         for line in paperStr.strip().split('\n'):
01921             d = dict(zip([self.cat[1]]+ self.cat[3:],line.split()))
01922             sizeList.append(d)
01923         d = {}.fromkeys([self.cat[1]]+ self.cat[3:], 100)
01924         d.update(Format = _('custom'))
01925         sizeList.append(d)
01926         return sizeList
01927     
01928 class MapDialog(PsmapDialog):
01929     """!Dialog for map frame settings and optionally  raster and vector map selection"""
01930     def __init__(self, parent, id, settings,  rect = None, notebook = False):
01931         PsmapDialog.__init__(self, parent = parent, id = id, title = "", settings = settings)
01932  
01933         self.isNotebook = notebook
01934         if self.isNotebook:
01935             self.objectType = ('mapNotebook',) 
01936         else:
01937             self.objectType = ('map',)
01938 
01939         
01940         #notebook
01941         if self.isNotebook:
01942             self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
01943             self.mPanel = MapFramePanel(parent = self.notebook, id = self.id[0], settings = self.instruction, 
01944                                         rect = rect, notebook = True)
01945             self.id[0] = self.mPanel.getId()
01946             self.rPanel = RasterPanel(parent = self.notebook, id = self.id[1], settings = self.instruction, 
01947                                         notebook = True)
01948             self.id[1] = self.rPanel.getId()
01949             self.vPanel = VectorPanel(parent = self.notebook, id = self.id[2], settings = self.instruction,
01950                                         notebook = True)
01951             self.id[2] = self.vPanel.getId()
01952             self._layout(self.notebook)
01953             self.SetTitle(_("Map settings"))
01954         else:
01955             self.mPanel = MapFramePanel(parent = self, id = self.id[0], settings = self.instruction, 
01956                                         rect = rect, notebook = False)
01957             self.id[0] = self.mPanel.getId()
01958             self._layout(self.mPanel)
01959             self.SetTitle(_("Map frame settings"))
01960         
01961         
01962     def OnApply(self, event):
01963         """!Apply changes"""
01964         if self.isNotebook:
01965             okV = self.vPanel.update()
01966             okR = self.rPanel.update()
01967             if okV and self.id[2] in self.instruction:
01968                 self.parent.DialogDataChanged(id = self.id[2])
01969             if okR and self.id[1] in self.instruction:
01970                 self.parent.DialogDataChanged(id = self.id[1])
01971             if not okR or not okV:
01972                 return False
01973 
01974         ok = self.mPanel.update()
01975         if ok:
01976             self.parent.DialogDataChanged(id = self.id[0])
01977             return True 
01978         
01979         return False
01980     
01981     def OnCancel(self, event):
01982         """!Close dialog and remove tmp red box"""
01983         self.parent.canvas.pdcTmp.RemoveId(self.parent.canvas.idZoomBoxTmp)
01984         self.parent.canvas.Refresh() 
01985         self.Close()
01986         
01987     def updateDialog(self):
01988         """!Update raster and vector information"""
01989         if self.mPanel.scaleChoice.GetSelection() == 0:
01990             if self.mPanel.rasterTypeRadio.GetValue():
01991                 if 'raster' in self.parent.openDialogs:
01992                     if self.parent.openDialogs['raster'].rPanel.rasterYesRadio.GetValue() and \
01993                             self.parent.openDialogs['raster'].rPanel.rasterSelect.GetValue() == self.mPanel.select.GetValue():
01994                             self.mPanel.drawMap.SetValue(True)
01995                     else:
01996                         self.mPanel.drawMap.SetValue(False)
01997             else:
01998                 if 'vector' in self.parent.openDialogs:
01999                     found = False
02000                     for each in self.parent.openDialogs['vector'].vPanel.vectorList:
02001                         if each[0] == self.mPanel.select.GetValue():
02002                             found = True
02003                     self.mPanel.drawMap.SetValue(found)    
02004                         
02005 class MapFramePanel(wx.Panel):
02006     """!wx.Panel with map (scale, region, border) settings"""
02007     def __init__(self, parent, id, settings, rect, notebook = True):
02008         wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
02009 
02010         self.id = id
02011         self.instruction = settings
02012         
02013         if notebook:
02014             self.book = parent
02015             self.book.AddPage(page = self, text = _("Map frame"))
02016             self.mapDialog = self.book.GetParent()
02017         else:
02018             self.mapDialog = parent
02019             
02020         if self.id is not None:
02021             self.mapFrameDict = self.instruction[self.id].GetInstruction() 
02022         else:
02023             self.id = wx.NewId()
02024             mapFrame = MapFrame(self.id)
02025             self.mapFrameDict = mapFrame.GetInstruction()
02026             self.mapFrameDict['rect'] = rect
02027 
02028             
02029         self._layout()
02030 
02031         self.scale = [None]*4
02032         self.center = [None]*4
02033         
02034         
02035         
02036         self.selectedMap = self.mapFrameDict['map']
02037         self.selectedRegion = self.mapFrameDict['region']
02038         self.scaleType = self.mapFrameDict['scaleType']
02039         self.mapType = self.mapFrameDict['mapType']
02040         self.scaleChoice.SetSelection(self.mapFrameDict['scaleType'])
02041         if self.instruction[self.id]:
02042             self.drawMap.SetValue(self.mapFrameDict['drawMap'])
02043         else:
02044             self.drawMap.SetValue(True)
02045         if self.mapFrameDict['scaleType'] == 0 and self.mapFrameDict['map']:
02046             self.select.SetValue(self.mapFrameDict['map'])
02047             if self.mapFrameDict['mapType'] == 'raster':
02048                 self.rasterTypeRadio.SetValue(True)
02049                 self.vectorTypeRadio.SetValue(False)
02050             else:
02051                 self.rasterTypeRadio.SetValue(False)
02052                 self.vectorTypeRadio.SetValue(True)
02053         elif self.mapFrameDict['scaleType'] == 1 and self.mapFrameDict['region']:
02054             self.select.SetValue(self.mapFrameDict['region'])
02055         
02056         
02057         self.OnMap(None)
02058         self.scale[self.mapFrameDict['scaleType']] = self.mapFrameDict['scale']
02059         self.center[self.mapFrameDict['scaleType']] = self.mapFrameDict['center']
02060         self.OnScaleChoice(None)
02061         self.OnElementType(None)
02062         self.OnBorder(None)
02063         
02064         
02065         
02066     def _layout(self):
02067         """!Do layout"""
02068         border = wx.BoxSizer(wx.VERTICAL)
02069         
02070         box   = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Map frame"))
02071         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
02072         gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
02073 
02074 
02075         #scale options
02076         frameText = wx.StaticText(self, id = wx.ID_ANY, label = _("Map frame options:"))
02077         scaleChoices = [_("fit frame to match selected map"),
02078                         _("fit frame to match saved region"),
02079                         _("fit frame to match current computational region"),
02080                         _("fixed scale and map center")]
02081         self.scaleChoice = wx.Choice(self, id = wx.ID_ANY, choices = scaleChoices)
02082         
02083         
02084         gridBagSizer.Add(frameText, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02085         gridBagSizer.Add(self.scaleChoice, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02086         
02087         #map and region selection
02088         self.staticBox = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Map selection"))
02089         sizerM = wx.StaticBoxSizer(self.staticBox, wx.HORIZONTAL)
02090         self.mapSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
02091 
02092         self.rasterTypeRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("raster"), style = wx.RB_GROUP)
02093         self.vectorTypeRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("vector"))
02094         self.drawMap = wx.CheckBox(self, id = wx.ID_ANY, label = "add selected map")
02095         
02096         self.mapOrRegionText = [_("Map:"), _("Region:")] 
02097         dc = wx.ClientDC(self)# determine size of labels
02098         width = max(dc.GetTextExtent(self.mapOrRegionText[0])[0], dc.GetTextExtent(self.mapOrRegionText[1])[0])
02099         self.mapText = wx.StaticText(self, id = wx.ID_ANY, label = self.mapOrRegionText[0], size = (width, -1))
02100         self.select = Select(self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
02101                              type = 'raster', multiple = False,
02102                              updateOnPopup = True, onPopup = None)
02103                             
02104         self.mapSizer.Add(self.rasterTypeRadio, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02105         self.mapSizer.Add(self.vectorTypeRadio, pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02106         self.mapSizer.Add(self.drawMap, pos = (0, 3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
02107         self.mapSizer.Add(self.mapText, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02108         self.mapSizer.Add(self.select, pos = (1, 1), span = (1, 3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02109                  
02110         sizerM.Add(self.mapSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
02111         gridBagSizer.Add(sizerM, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02112         
02113 
02114         #map scale and center
02115         boxC   = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Map scale and center"))
02116         sizerC = wx.StaticBoxSizer(boxC, wx.HORIZONTAL)
02117         self.centerSizer = wx.FlexGridSizer(rows = 2, cols = 5, hgap = 5, vgap = 5)        
02118                 
02119                            
02120         centerText = wx.StaticText(self, id = wx.ID_ANY, label = _("Center:"))
02121         self.eastingText = wx.StaticText(self, id = wx.ID_ANY, label = _("E:"))
02122         self.northingText = wx.StaticText(self, id = wx.ID_ANY, label = _("N:"))
02123         self.eastingTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, style = wx.TE_RIGHT, validator = TCValidator(flag = 'DIGIT_ONLY'))
02124         self.northingTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, style = wx.TE_RIGHT, validator = TCValidator(flag = 'DIGIT_ONLY'))
02125         scaleText = wx.StaticText(self, id = wx.ID_ANY, label = _("Scale:"))
02126         scalePrefixText = wx.StaticText(self, id = wx.ID_ANY, label = _("1 :"))
02127         self.scaleTextCtrl = wx.TextCtrl(self, id = wx.ID_ANY, value = "", style = wx.TE_RIGHT, validator = TCValidator('DIGIT_ONLY'))
02128         
02129         self.centerSizer.Add(centerText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 10)
02130         self.centerSizer.Add(self.eastingText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
02131         self.centerSizer.Add(self.eastingTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02132         self.centerSizer.Add(self.northingText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
02133         self.centerSizer.Add(self.northingTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02134         
02135         self.centerSizer.Add(scaleText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border = 10)
02136         self.centerSizer.Add(scalePrefixText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
02137         self.centerSizer.Add(self.scaleTextCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02138         
02139         sizerC.Add(self.centerSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
02140         gridBagSizer.Add(sizerC, pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02141         
02142         
02143         #resolution
02144         flexSizer = wx.FlexGridSizer(rows = 1, cols = 2, hgap = 5, vgap = 5)
02145         
02146         resolutionText = wx.StaticText(self, id = wx.ID_ANY, label = _("Map max resolution (dpi):"))
02147         self.resolutionSpin = wx.SpinCtrl(self, id = wx.ID_ANY, min = 1, max = 1000, initial = 300)
02148         
02149         flexSizer.Add(resolutionText, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02150         flexSizer.Add(self.resolutionSpin, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02151         self.resolutionSpin.SetValue(self.mapFrameDict['resolution'])
02152         
02153         gridBagSizer.Add(flexSizer, pos = (4, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02154         
02155         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
02156         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
02157         
02158         # border
02159         box   = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Border"))        
02160         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
02161         gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
02162         
02163         self.borderCheck = wx.CheckBox(self, id = wx.ID_ANY, label = (_("draw border around map frame")))
02164         if self.mapFrameDict['border'] == 'y':
02165             self.borderCheck.SetValue(True)
02166         else: 
02167             self.borderCheck.SetValue(False)
02168         
02169         self.borderColorText = wx.StaticText(self, id = wx.ID_ANY, label = _("border color:"))
02170         self.borderWidthText = wx.StaticText(self, id = wx.ID_ANY, label = _("border width (pts):"))
02171         self.borderColourPicker = wx.ColourPickerCtrl(self, id = wx.ID_ANY)
02172         self.borderWidthCtrl = wx.SpinCtrl(self, id = wx.ID_ANY, min = 1, max = 100, initial = 1)
02173         
02174         if self.mapFrameDict['border'] == 'y':
02175             self.borderWidthCtrl.SetValue(int(self.mapFrameDict['width']))
02176             self.borderColourPicker.SetColour(convertRGB(self.mapFrameDict['color']))
02177         
02178         
02179         gridBagSizer.Add(self.borderCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02180         gridBagSizer.Add(self.borderColorText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02181         gridBagSizer.Add(self.borderWidthText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02182         gridBagSizer.Add(self.borderColourPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02183         gridBagSizer.Add(self.borderWidthCtrl, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02184         
02185         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
02186         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
02187         
02188         self.SetSizer(border)
02189         self.Fit()
02190         
02191         
02192         if projInfo()['proj'] == 'll':
02193             self.scaleChoice.SetItems(self.scaleChoice.GetItems()[0:3])
02194             boxC.Hide()
02195             for each in self.centerSizer.GetChildren():
02196                 each.GetWindow().Hide()
02197 
02198             
02199         # bindings
02200         self.scaleChoice.Bind(wx.EVT_CHOICE, self.OnScaleChoice)
02201         self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnMap)
02202         self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.vectorTypeRadio)
02203         self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.rasterTypeRadio)
02204         self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
02205         
02206         
02207      
02208     def OnMap(self, event):
02209         """!Selected map or region changing"""
02210         
02211         if self.select.GetValue():
02212             self.selected = self.select.GetValue() 
02213         else:
02214             self.selected = None
02215 
02216         if self.scaleChoice.GetSelection() == 0:
02217             self.selectedMap = self.selected
02218             if self.rasterTypeRadio.GetValue():
02219                 mapType = 'raster' 
02220             else:
02221                 mapType = 'vector'
02222 
02223             self.scale[0], self.center[0], foo = AutoAdjust(self, scaleType = 0, map = self.selected,
02224                                                 mapType = mapType, rect = self.mapFrameDict['rect'])
02225             #self.center[0] = self.RegionCenter(self.RegionDict(scaleType = 0))
02226 
02227         elif self.scaleChoice.GetSelection() == 1:
02228             self.selectedRegion = self.selected
02229             self.scale[1], self.center[1],  foo = AutoAdjust(self, scaleType = 1, region = self.selected, rect = self.mapFrameDict['rect'])
02230             #self.center[1] = self.RegionCenter(self.RegionDict(scaleType = 1))
02231         elif self.scaleChoice.GetSelection() == 2:
02232             self.scale[2], self.center[2], foo = AutoAdjust(self, scaleType = 2, rect = self.mapFrameDict['rect'])
02233             #self.center[2] = self.RegionCenter(self.RegionDict(scaleType = 2))
02234             
02235         else:
02236             self.scale[3] = None        
02237             self.center[3] = None
02238             
02239         self.OnScaleChoice(None)
02240         
02241             
02242     def OnScaleChoice(self, event):
02243         """!Selected scale type changing"""
02244         
02245         scaleType = self.scaleChoice.GetSelection()
02246         if self.scaleType != scaleType:
02247             self.scaleType = scaleType
02248             self.select.SetValue("")
02249         
02250         if scaleType in (0, 1): # automatic - region from raster map, saved region
02251             if scaleType == 0:
02252                 # set map selection
02253                 self.rasterTypeRadio.Show()
02254                 self.vectorTypeRadio.Show()
02255                 self.drawMap.Show()
02256                 self.staticBox.SetLabel(" %s " % _("Map selection"))
02257                 if self.rasterTypeRadio.GetValue():
02258                     stype = 'raster' 
02259                 else:
02260                     stype = 'vector'
02261 
02262                 self.select.SetElementList(type = stype)
02263                 self.mapText.SetLabel(self.mapOrRegionText[0])
02264                 self.select.SetToolTipString(_("Region is set to match this map,\nraster or vector map must be added later"))
02265                     
02266             if scaleType == 1:
02267                 # set region selection
02268                 self.rasterTypeRadio.Hide()
02269                 self.vectorTypeRadio.Hide()
02270                 self.drawMap.Hide()
02271                 self.staticBox.SetLabel(" %s " % _("Region selection"))
02272                 stype = 'region'
02273                 self.select.SetElementList(type = stype)
02274                 self.mapText.SetLabel(self.mapOrRegionText[1])
02275                 self.select.SetToolTipString("")
02276 
02277             for each in self.mapSizer.GetChildren():
02278                 each.GetWindow().Enable()
02279             for each in self.centerSizer.GetChildren():
02280                 each.GetWindow().Disable()
02281                     
02282             if self.scale[scaleType]:
02283                 
02284                 self.scaleTextCtrl.SetValue("%.0f" % (1/self.scale[scaleType]))
02285             if self.center[scaleType]:
02286                 self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
02287                 self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
02288         elif scaleType == 2:
02289             for each in self.mapSizer.GetChildren():
02290                 each.GetWindow().Disable()
02291             for each in self.centerSizer.GetChildren():
02292                 each.GetWindow().Disable()
02293                 
02294             if self.scale[scaleType]:
02295                 self.scaleTextCtrl.SetValue("%.0f" % (1/self.scale[scaleType]))
02296             if self.center[scaleType]:
02297                 self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
02298                 self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
02299         else: # fixed
02300             for each in self.mapSizer.GetChildren():
02301                 each.GetWindow().Disable()
02302             for each in self.centerSizer.GetChildren():
02303                 each.GetWindow().Enable()
02304                     
02305             if self.scale[scaleType]:
02306                 self.scaleTextCtrl.SetValue("%.0f" % (1/self.scale[scaleType]))
02307             if self.center[scaleType]:
02308                 self.eastingTextCtrl.SetValue(str(self.center[scaleType][0]))
02309                 self.northingTextCtrl.SetValue(str(self.center[scaleType][1]))
02310                 
02311     def OnElementType(self, event):
02312         """!Changes data in map selection tree ctrl popup"""
02313         if self.rasterTypeRadio.GetValue():
02314             mapType = 'raster'
02315         else:
02316             mapType = 'vector'
02317         self.select.SetElementList(type  = mapType)
02318         if self.mapType != mapType and event is not None:
02319             self.mapType = mapType
02320             self.select.SetValue('')
02321         self.mapType = mapType    
02322         
02323     def OnBorder(self, event):
02324         """!Enables/disable the part relating to border of map frame"""
02325         for each in (self.borderColorText, self.borderWidthText, self.borderColourPicker, self.borderWidthCtrl):
02326             each.Enable(self.borderCheck.GetValue())
02327             
02328     def getId(self):
02329         """!Returns id of raster map"""
02330         return self.id
02331             
02332     def update(self):
02333         """!Save changes"""
02334         mapFrameDict = dict(self.mapFrameDict)
02335         # resolution
02336         mapFrameDict['resolution'] = self.resolutionSpin.GetValue()
02337         #scale
02338         scaleType = self.scaleType
02339         mapFrameDict['scaleType'] = scaleType
02340         
02341         if mapFrameDict['scaleType'] == 0:
02342             if self.select.GetValue():
02343                 mapFrameDict['drawMap'] = self.drawMap.GetValue()
02344                 mapFrameDict['map'] = self.select.GetValue()
02345                 mapFrameDict['mapType'] = self.mapType
02346                 mapFrameDict['region'] = None
02347                 
02348                 if mapFrameDict['drawMap']:
02349 
02350                     if mapFrameDict['mapType'] == 'raster':
02351                         mapFile = grass.find_file(mapFrameDict['map'], element = 'cell')
02352                         if mapFile['file'] == '':
02353                             GMessage("Raster %s not found" % mapFrameDict['map'])
02354                             return False
02355                         raster = self.instruction.FindInstructionByType('raster')
02356                         if raster:
02357                             raster['raster'] = mapFrameDict['map']
02358                         else:
02359                             raster = Raster(wx.NewId())
02360                             raster['raster'] = mapFrameDict['map']
02361                             raster['isRaster'] = True
02362                             self.instruction.AddInstruction(raster)
02363 
02364                     elif mapFrameDict['mapType'] == 'vector':
02365                         
02366                         mapFile = grass.find_file(mapFrameDict['map'], element = 'vector')
02367                         if mapFile['file'] == '':
02368                             GMessage("Vector %s not found" % mapFrameDict['map'])
02369                             return False
02370                         
02371                         vector = self.instruction.FindInstructionByType('vector')
02372                         isAdded = False
02373                         if vector:
02374                             for each in vector['list']:
02375                                 if each[0] == mapFrameDict['map']:
02376                                     isAdded = True
02377                         if not isAdded:
02378                             topoInfo = grass.vector_info_topo(map = mapFrameDict['map'])
02379                             if topoInfo:
02380                                 if bool(topoInfo['areas']):
02381                                     topoType = 'areas'
02382                                 elif bool(topoInfo['lines']):
02383                                     topoType = 'lines'
02384                                 else:
02385                                     topoType = 'points'
02386                                 label = '('.join(mapFrameDict['map'].split('@')) + ')'
02387                            
02388                                 if not vector:
02389                                     vector = Vector(wx.NewId())
02390                                     vector['list'] = []
02391                                     self.instruction.AddInstruction(vector)
02392                                 id = wx.NewId()
02393                                 vector['list'].insert(0, [mapFrameDict['map'], topoType, id, 1, label])
02394                                 vProp = VProperties(id, topoType)
02395                                 vProp['name'], vProp['label'], vProp['lpos'] = mapFrameDict['map'], label, 1
02396                                 self.instruction.AddInstruction(vProp)
02397                             else:
02398                                 return False
02399                             
02400                 self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust(self, scaleType = 0, map = mapFrameDict['map'],
02401                                                                    mapType = self.mapType, rect = self.mapFrameDict['rect'])
02402                                                
02403                 if self.rectAdjusted:
02404                     mapFrameDict['rect'] = self.rectAdjusted 
02405                 else:
02406                     mapFrameDict['rect'] = self.mapFrameDict['rect']
02407 
02408                 mapFrameDict['scale'] = self.scale[0]
02409                 
02410                 mapFrameDict['center'] = self.center[0]
02411                 # set region
02412                 if self.mapType == 'raster':
02413                     RunCommand('g.region', rast = mapFrameDict['map'])
02414                 if self.mapType == 'vector':
02415                     raster = self.instruction.FindInstructionByType('raster')
02416                     if raster:
02417                         rasterId = raster.id 
02418                     else:
02419                         rasterId = None
02420 
02421                     if rasterId:
02422                         
02423                         RunCommand('g.region', vect = mapFrameDict['map'], rast = self.instruction[rasterId]['raster'])
02424                     else:
02425                         RunCommand('g.region', vect = mapFrameDict['map'])
02426                 
02427                     
02428                 
02429             else:
02430                 wx.MessageBox(message = _("No map selected!"),
02431                                     caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
02432                 return False    
02433             
02434         elif mapFrameDict['scaleType'] == 1:
02435             if self.select.GetValue():
02436                 mapFrameDict['drawMap'] = False
02437                 mapFrameDict['map'] = None
02438                 mapFrameDict['mapType'] = None
02439                 mapFrameDict['region'] = self.select.GetValue()
02440                 self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust(self, scaleType = 1, region = mapFrameDict['region'],
02441                                                                                 rect = self.mapFrameDict['rect'])
02442                 if self.rectAdjusted:
02443                     mapFrameDict['rect'] = self.rectAdjusted 
02444                 else:
02445                     mapFrameDict['rect'] = self.mapFrameDict['rect']
02446 
02447                 mapFrameDict['scale'] = self.scale[1]
02448                 mapFrameDict['center'] = self.center[1]
02449                 # set region
02450                 RunCommand('g.region', region = mapFrameDict['region'])
02451             else:
02452                 wx.MessageBox(message = _("No region selected!"),
02453                                     caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
02454                 return False 
02455                                
02456         elif scaleType == 2:
02457             mapFrameDict['drawMap'] = False
02458             mapFrameDict['map'] = None
02459             mapFrameDict['mapType'] = None
02460             mapFrameDict['region'] = None
02461             self.scale[2], self.center[2], self.rectAdjusted = AutoAdjust(self, scaleType = 2, rect = self.mapFrameDict['rect'])
02462             if self.rectAdjusted:
02463                 mapFrameDict['rect'] = self.rectAdjusted 
02464             else:
02465                 mapFrameDict['rect'] = self.mapFrameDict['rect']
02466 
02467             mapFrameDict['scale'] = self.scale[2]
02468             mapFrameDict['center'] = self.center[2]
02469             
02470             env = grass.gisenv()
02471             windFilePath = os.path.join(env['GISDBASE'], env['LOCATION_NAME'], env['MAPSET'], 'WIND')
02472             try:
02473                 windFile = open(windFilePath, 'r').read()
02474                 region = grass.parse_key_val(windFile, sep = ':', val_type = float)
02475             except IOError:
02476                 region = grass.region()
02477             
02478             raster = self.instruction.FindInstructionByType('raster')
02479             if raster:
02480                 rasterId = raster.id 
02481             else:
02482                 rasterId = None
02483 
02484             if rasterId: # because of resolution
02485                 RunCommand('g.region', n = region['north'], s = region['south'],
02486                             e = region['east'], w = region['west'], rast = self.instruction[rasterId]['raster'])
02487             else:
02488                 RunCommand('g.region', n = region['north'], s = region['south'],
02489                            e = region['east'], w = region['west'])
02490             
02491         elif scaleType == 3:
02492             mapFrameDict['drawMap'] = False
02493             mapFrameDict['map'] = None
02494             mapFrameDict['mapType'] = None
02495             mapFrameDict['region'] = None
02496             mapFrameDict['rect'] = self.mapFrameDict['rect']
02497             try:
02498                 scaleNumber = float(self.scaleTextCtrl.GetValue())
02499                 centerE = float(self.eastingTextCtrl.GetValue()) 
02500                 centerN = float(self.northingTextCtrl.GetValue())
02501             except (ValueError, SyntaxError):
02502                 wx.MessageBox(message = _("Invalid scale or map center!"),
02503                                     caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
02504                 return False  
02505             mapFrameDict['scale'] = 1/scaleNumber
02506             mapFrameDict['center'] = centerE, centerN
02507         
02508             ComputeSetRegion(self, mapDict = mapFrameDict)
02509         
02510         # check resolution
02511         SetResolution(dpi = mapFrameDict['resolution'], width = mapFrameDict['rect'].width,
02512                                                         height = mapFrameDict['rect'].height)
02513         # border
02514         if self.borderCheck.GetValue():
02515             mapFrameDict['border'] = 'y' 
02516         else:
02517             mapFrameDict['border'] = 'n'
02518 
02519         if mapFrameDict['border'] == 'y':
02520             mapFrameDict['width'] = self.borderWidthCtrl.GetValue()
02521             mapFrameDict['color'] = convertRGB(self.borderColourPicker.GetColour())
02522             
02523         if self.id not in self.instruction:
02524             mapFrame = MapFrame(self.id)
02525             self.instruction.AddInstruction(mapFrame)
02526         self.instruction[self.id].SetInstruction(mapFrameDict)
02527 
02528         if self.id not in self.mapDialog.parent.objectId:
02529             self.mapDialog.parent.objectId.insert(0, self.id)# map frame is drawn first
02530         return True
02531         
02532 class RasterPanel(wx.Panel):
02533     """!Panel for raster map settings"""
02534     def __init__(self, parent, id, settings,  notebook = True):
02535         wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
02536         self.instruction = settings
02537         
02538         if notebook:
02539             self.book = parent
02540             self.book.AddPage(page = self, text = _("Raster map"))
02541             self.mainDialog = self.book.GetParent()
02542         else:
02543             self.mainDialog = parent
02544         if id:
02545             self.id = id
02546             self.rasterDict = self.instruction[self.id].GetInstruction()
02547         else:
02548             self.id = wx.NewId()
02549             raster = Raster(self.id)
02550             self.rasterDict = raster.GetInstruction()
02551             
02552             
02553         self._layout()
02554         self.OnRaster(None)
02555             
02556     def _layout(self):
02557         """!Do layout"""
02558         border = wx.BoxSizer(wx.VERTICAL)
02559         
02560         # choose raster map
02561         
02562         box   = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Choose raster map"))
02563         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
02564         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
02565         
02566         self.rasterNoRadio = wx.RadioButton(self, id = wx.ID_ANY, label = _("no raster map"), style = wx.RB_GROUP)
02567         self.rasterYesRadio = wx.RadioButton(self, id = wx.ID_ANY, label = _("raster:"))
02568         
02569         self.rasterSelect = Select(self, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
02570                              type = 'raster', multiple = False,
02571                              updateOnPopup = True, onPopup = None)
02572         if self.rasterDict['isRaster']:
02573             self.rasterYesRadio.SetValue(True)
02574             self.rasterNoRadio.SetValue(False)
02575             self.rasterSelect.SetValue(self.rasterDict['raster'])
02576         else:
02577             self.rasterYesRadio.SetValue(False)
02578             self.rasterNoRadio.SetValue(True)
02579             mapId = self.instruction.FindInstructionByType('map').id
02580 
02581             if self.instruction[mapId]['map'] and self.instruction[mapId]['mapType'] == 'raster':
02582                 self.rasterSelect.SetValue(self.instruction[mapId]['map'])# raster map from map frame dialog if possible
02583             else:
02584                 self.rasterSelect.SetValue('')                
02585         gridBagSizer.Add(self.rasterNoRadio, pos = (0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)            
02586         gridBagSizer.Add(self.rasterYesRadio, pos = (1, 0),  flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02587         gridBagSizer.Add(self.rasterSelect, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02588         
02589         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
02590         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
02591         
02592         #self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
02593         self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterNoRadio)
02594         self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterYesRadio)
02595         
02596         self.SetSizer(border)
02597         self.Fit()
02598         
02599     def OnRaster(self, event):
02600         """!Enable/disable raster selection"""
02601         self.rasterSelect.Enable(self.rasterYesRadio.GetValue())
02602         
02603     def update(self):
02604         #draw raster
02605         map = self.instruction.FindInstructionByType('map')
02606         if self.rasterNoRadio.GetValue() or not self.rasterSelect.GetValue():
02607             self.rasterDict['isRaster'] = False
02608             self.rasterDict['raster'] = None
02609             map['drawMap'] = False
02610             if self.id in self.instruction:
02611                 del self.instruction[self.id]
02612 
02613         else:
02614             self.rasterDict['isRaster'] = True
02615             self.rasterDict['raster'] = self.rasterSelect.GetValue()
02616             if self.rasterDict['raster'] != map['drawMap']:
02617                 map['drawMap'] = False
02618             
02619             if self.id not in self.instruction:
02620                 raster = Raster(self.id)
02621                 self.instruction.AddInstruction(raster)
02622             self.instruction[self.id].SetInstruction(self.rasterDict)
02623             
02624         if 'map' in self.mainDialog.parent.openDialogs:
02625             self.mainDialog.parent.openDialogs['map'].updateDialog()
02626         return True
02627         
02628     def getId(self):
02629         return self.id
02630   
02631 class VectorPanel(wx.Panel):
02632     """!Panel for vector maps settings"""
02633     def __init__(self, parent, id, settings, notebook = True):
02634         wx.Panel.__init__(self, parent, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
02635         
02636         self.parent = parent
02637         self.instruction = settings
02638         self.tmpDialogDict = {}
02639         vectors = self.instruction.FindInstructionByType('vProperties', list = True)
02640         for vector in vectors:
02641             self.tmpDialogDict[vector.id] = dict(self.instruction[vector.id].GetInstruction())
02642         
02643         if id:
02644             self.id = id
02645             self.vectorList = deepcopy(self.instruction[id]['list'])
02646         else:
02647             self.id = wx.NewId()
02648             self.vectorList = []
02649 
02650         vLegend = self.instruction.FindInstructionByType('vectorLegend')
02651         if vLegend:
02652             self.vLegendId = vLegend.id 
02653         else:
02654             self.vLegendId = None
02655 
02656          
02657         self._layout()
02658         
02659         if notebook:
02660             self.parent.AddPage(page = self, text = _("Vector maps"))
02661             self.parent = self.parent.GetParent()
02662             
02663     def _layout(self):
02664         """!Do layout"""
02665         border = wx.BoxSizer(wx.VERTICAL)
02666         
02667         # choose vector map
02668         
02669         box   = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Add map"))
02670         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
02671         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
02672         
02673         text = wx.StaticText(self, id = wx.ID_ANY, label = _("Map:"))
02674         self.select = Select(self, id = wx.ID_ANY,# size = globalvar.DIALOG_GSELECT_SIZE,
02675                              type = 'vector', multiple = False,
02676                              updateOnPopup = True, onPopup = None)
02677         topologyTypeTr = [_("points"), _("lines"), _("areas")]
02678         self.topologyTypeList = ["points", "lines", "areas"]
02679         self.vectorType = wx.RadioBox(self, id = wx.ID_ANY, label = " %s " % _("Data Type"), choices = topologyTypeTr,
02680                                       majorDimension = 3, style = wx.RA_SPECIFY_COLS)
02681         
02682         self.AddVector = wx.Button(self, id = wx.ID_ANY, label = _("Add"))
02683         
02684         gridBagSizer.Add(text, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02685         gridBagSizer.Add(self.select, pos = (0,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02686         gridBagSizer.Add(self.vectorType, pos = (1,1), flag = wx.ALIGN_CENTER, border = 0)
02687         gridBagSizer.Add(self.AddVector, pos = (1,2), flag = wx.ALIGN_BOTTOM|wx.ALIGN_RIGHT, border = 0)
02688         
02689         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
02690         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
02691         
02692         # manage vector layers
02693         
02694         box   = wx.StaticBox (parent = self, id = wx.ID_ANY, label = " %s " % _("Manage vector maps"))
02695         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
02696         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
02697         gridBagSizer.AddGrowableCol(0,2)
02698         gridBagSizer.AddGrowableCol(1,1)
02699 
02700         
02701         
02702         text = wx.StaticText(self, id = wx.ID_ANY, label = _("The topmost vector map overlaps the others"))
02703         self.listbox = wx.ListBox(self, id = wx.ID_ANY, choices = [], style = wx.LB_SINGLE|wx.LB_NEEDED_SB)
02704         self.btnUp = wx.Button(self, id = wx.ID_ANY, label = _("Up"))
02705         self.btnDown = wx.Button(self, id = wx.ID_ANY, label = _("Down"))
02706         self.btnDel = wx.Button(self, id = wx.ID_ANY, label = _("Delete"))
02707         self.btnProp = wx.Button(self, id = wx.ID_ANY, label = _("Properties..."))
02708         
02709         self.updateListBox(selected=0)
02710         
02711         
02712         gridBagSizer.Add(text, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
02713         gridBagSizer.Add(self.listbox, pos = (1,0), span = (4, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02714         gridBagSizer.Add(self.btnUp, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02715         gridBagSizer.Add(self.btnDown, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02716         gridBagSizer.Add(self.btnDel, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02717         gridBagSizer.Add(self.btnProp, pos = (4,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
02718         
02719         sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALL, border = 5)
02720         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
02721         
02722         self.Bind(wx.EVT_BUTTON, self.OnAddVector, self.AddVector)
02723         self.Bind(wx.EVT_BUTTON, self.OnDelete, self.btnDel)
02724         self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
02725         self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)
02726         self.Bind(wx.EVT_BUTTON, self.OnProperties, self.btnProp)
02727         self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnVector)
02728         
02729         self.SetSizer(border)
02730         self.Fit()
02731         
02732         self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnProperties, self.listbox)
02733 
02734     def OnVector(self, event):
02735         """!Gets info about toplogy and enables/disables choices point/line/area"""
02736         vmap = self.select.GetValue()   
02737         try:     
02738             topoInfo = grass.vector_info_topo(map = vmap)
02739         except grass.ScriptError:
02740             return
02741         
02742         if topoInfo:
02743             self.vectorType.EnableItem(2, bool(topoInfo['areas']))
02744             self.vectorType.EnableItem(1, bool(topoInfo['boundaries']) or bool(topoInfo['lines']))
02745             self.vectorType.EnableItem(0, bool(topoInfo['centroids'] or bool(topoInfo['points']) ))
02746             for item in range(2,-1,-1):
02747                 if self.vectorType.IsItemEnabled(item):
02748                     self.vectorType.SetSelection(item)
02749                     break
02750             
02751             self.AddVector.SetFocus()        
02752             
02753     def OnAddVector(self, event):
02754         """!Adds vector map to list"""
02755         vmap = self.select.GetValue()
02756         if vmap:
02757             mapname = vmap.split('@')[0]
02758             try:
02759                 mapset = '(' + vmap.split('@')[1] + ')'
02760             except IndexError:
02761                 mapset = ''
02762             idx = self.vectorType.GetSelection()
02763             ttype = self.topologyTypeList[idx]
02764             record = "%s - %s" % (vmap, ttype)
02765             id = wx.NewId()
02766             lpos = 1
02767             label = mapname + mapset 
02768             self.vectorList.insert(0, [vmap, ttype, id, lpos, label])
02769             self.reposition()
02770             self.listbox.InsertItems([record], 0)
02771             
02772             vector = VProperties(id, ttype)
02773             self.tmpDialogDict[id] = vector.GetInstruction()
02774             self.tmpDialogDict[id]['name'] = vmap
02775 
02776             
02777             self.listbox.SetSelection(0)  
02778             self.listbox.EnsureVisible(0)
02779             self.btnProp.SetFocus()
02780             self.enableButtons()
02781             
02782     def OnDelete(self, event):
02783         """!Deletes vector map from the list"""
02784         if self.listbox.GetSelections():
02785             pos = self.listbox.GetSelection()
02786             id = self.vectorList[pos][2]
02787             del self.vectorList[pos]
02788             del self.tmpDialogDict[id]
02789             
02790             for i in range(pos, len(self.vectorList)):
02791                 if self.vectorList[i][3]:# can be 0
02792                     self.vectorList[i][3] -= 1
02793             
02794             if pos < len(self.vectorList) -1:
02795                 selected = pos
02796             else:
02797                 selected = len(self.vectorList) -1
02798             self.updateListBox(selected = selected)
02799             if self.listbox.IsEmpty():
02800                 self.enableButtons(False)
02801             
02802             
02803     def OnUp(self, event):
02804         """!Moves selected map to top"""
02805         if self.listbox.GetSelections():
02806             pos = self.listbox.GetSelection()
02807             if pos:
02808                 self.vectorList.insert(pos - 1, self.vectorList.pop(pos))
02809             if not self.vLegendId:
02810                 self.reposition()
02811                 
02812             if pos > 0:
02813                 self.updateListBox(selected = (pos - 1)) 
02814             else:
02815                 self.updateListBox(selected = 0)
02816 
02817             
02818     def OnDown(self, event):
02819         """!Moves selected map to bottom"""
02820         if self.listbox.GetSelections():
02821             pos = self.listbox.GetSelection()
02822             if pos != len(self.vectorList) - 1:
02823                 self.vectorList.insert(pos + 1, self.vectorList.pop(pos))
02824                 if not self.vLegendId:
02825                     self.reposition()
02826             if pos < len(self.vectorList) -1:
02827                 self.updateListBox(selected = (pos + 1)) 
02828             else:
02829                 self.updateListBox(selected = len(self.vectorList) -1)
02830 
02831     
02832     def OnProperties(self, event):
02833         """!Opens vector map properties dialog"""
02834         if self.listbox.GetSelections():
02835             pos = self.listbox.GetSelection()
02836             id = self.vectorList[pos][2]
02837 
02838             dlg = VPropertiesDialog(self, id = id, settings = self.instruction, 
02839                                     vectors = self.vectorList, tmpSettings = self.tmpDialogDict[id])
02840             dlg.ShowModal()
02841             
02842             self.parent.FindWindowById(wx.ID_OK).SetFocus()
02843            
02844     def enableButtons(self, enable = True):
02845         """!Enable/disable up, down, properties, delete buttons"""
02846         self.btnUp.Enable(enable)
02847         self.btnDown.Enable(enable)
02848         self.btnProp.Enable(enable)
02849         self.btnDel.Enable(enable)
02850     
02851     def updateListBox(self, selected = None):
02852         mapList = ["%s - %s" % (item[0], item[1]) for item in self.vectorList]
02853         self.listbox.Set(mapList)
02854         if self.listbox.IsEmpty():
02855             self.enableButtons(False)
02856         else:
02857             self.enableButtons(True)
02858             if selected is not None:
02859                 self.listbox.SetSelection(selected)  
02860                 self.listbox.EnsureVisible(selected)  
02861               
02862     def reposition(self):
02863         """!Update position in legend, used only if there is no vlegend yet"""
02864         for i in range(len(self.vectorList)):
02865             if self.vectorList[i][3]:
02866                 self.vectorList[i][3] = i + 1
02867                 
02868     def getId(self):
02869         return self.id
02870         
02871     def update(self):
02872         vectors = self.instruction.FindInstructionByType('vProperties', list = True)
02873         
02874         for vector in vectors:
02875             del self.instruction[vector.id]
02876         if self.id in self.instruction:
02877             del self.instruction[self.id] 
02878 
02879         if len(self.vectorList) > 0:
02880             vector = Vector(self.id)
02881             self.instruction.AddInstruction(vector)
02882 
02883             vector.SetInstruction({'list': deepcopy(self.vectorList)})
02884             
02885             # save new vectors
02886             for item in self.vectorList:
02887                 id = item[2]
02888 
02889                 vLayer = VProperties(id, item[1])
02890                 self.instruction.AddInstruction(vLayer)
02891                 vLayer.SetInstruction(self.tmpDialogDict[id])
02892                 vLayer['name'] = item[0]
02893                 vLayer['label'] = item[4]
02894                 vLayer['lpos'] = item[3]
02895             
02896         else:
02897             if self.id in self.instruction:
02898                 del self.instruction[self.id]
02899                 
02900         if 'map' in self.parent.parent.openDialogs:
02901             self.parent.parent.openDialogs['map'].updateDialog()
02902 
02903         return True
02904     
02905 class RasterDialog(PsmapDialog):
02906     def __init__(self, parent, id, settings):
02907         PsmapDialog.__init__(self, parent = parent, id = id, title = _("Raster map settings"), settings = settings)
02908         self.objectType = ('raster',)
02909         
02910         self.rPanel = RasterPanel(parent = self, id = self.id, settings = self.instruction, notebook = False)
02911 
02912         self.id = self.rPanel.getId()
02913         self._layout(self.rPanel)
02914     
02915     def update(self):
02916         ok = self.rPanel.update()
02917         if ok:
02918             return True
02919         return False
02920     
02921     def OnApply(self, event):
02922         ok = self.update()
02923         if not ok:
02924             return False
02925 
02926         if self.id in self.instruction:
02927             self.parent.DialogDataChanged(id = self.id)
02928         else:
02929             mapId = self.instruction.FindInstructionByType('map').id
02930             self.parent.DialogDataChanged(id = mapId)
02931         return True
02932     
02933     def updateDialog(self):
02934         """!Update information (not used)"""
02935         pass
02936 ##        if 'map' in self.parent.openDialogs:
02937 ##            if self.parent.openDialogs['map'].mPanel.rasterTypeRadio.GetValue()\
02938 ##                    and self.parent.openDialogs['map'].mPanel.select.GetValue():
02939 ##                if self.parent.openDialogs['map'].mPanel.drawMap.IsChecked():
02940 ##                    self.rPanel.rasterSelect.SetValue(self.parent.openDialogs['map'].mPanel.select.GetValue())   
02941                 
02942 class MainVectorDialog(PsmapDialog):
02943     def __init__(self, parent, id, settings):
02944         PsmapDialog.__init__(self, parent = parent, id = id, title = _("Vector maps settings"), settings = settings)
02945         self.objectType = ('vector',)
02946         self.vPanel = VectorPanel(parent = self, id = self.id, settings = self.instruction, notebook = False)
02947 
02948         self.id = self.vPanel.getId()
02949         self._layout(self.vPanel)
02950     
02951     def update(self):
02952         self.vPanel.update()
02953         
02954     def OnApply(self, event):
02955         self.update()
02956         if self.id in self.instruction:
02957             self.parent.DialogDataChanged(id = self.id)
02958         else:
02959             mapId = self.instruction.FindInstructionByType('map').id
02960             self.parent.DialogDataChanged(id = mapId)
02961         return True
02962         
02963     def updateDialog(self):
02964         """!Update information (not used)"""
02965         pass
02966         
02967 class VPropertiesDialog(PsmapDialog):
02968     def __init__(self, parent, id, settings, vectors, tmpSettings):
02969         PsmapDialog.__init__(self, parent = parent, id = id, title = "", settings = settings, apply = False)
02970         
02971         vectorList = vectors
02972         self.vPropertiesDict = tmpSettings
02973         
02974         # determine map and its type
02975         for item in vectorList:
02976             if id == item[2]:
02977                 self.vectorName = item[0]
02978                 self.type = item[1]
02979         self.SetTitle(_("%s properties") % self.vectorName)
02980         
02981         #vector map info
02982         self.connection = True
02983         try:
02984             self.mapDBInfo = dbm_base.VectorDBInfo(self.vectorName)
02985             self.layers = self.mapDBInfo.layers.keys()
02986         except grass.ScriptError:
02987             self.connection = False
02988             self.layers = []
02989         if not self.layers:
02990             self.connection = False
02991             self.layers = []
02992             
02993         self.currLayer = self.vPropertiesDict['layer']
02994         
02995         #path to symbols, patterns
02996         gisbase = os.getenv("GISBASE")
02997         self.symbolPath = os.path.join(gisbase, 'etc', 'symbol')
02998         self.symbols = []
02999         for dir in os.listdir(self.symbolPath):
03000             for symbol in os.listdir(os.path.join(self.symbolPath, dir)):
03001                 self.symbols.append(os.path.join(dir, symbol))
03002         self.patternPath = os.path.join(gisbase, 'etc', 'paint', 'patterns')
03003 
03004         #notebook
03005         notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
03006         self.DSpanel = self._DataSelectionPanel(notebook)
03007         self.EnableLayerSelection(enable = self.connection)
03008         selectPanel = { 'points': [self._ColorsPointAreaPanel, self._StylePointPanel], 
03009                         'lines': [self._ColorsLinePanel, self._StyleLinePanel], 
03010                         'areas': [self._ColorsPointAreaPanel, self._StyleAreaPanel]}
03011         self.ColorsPanel = selectPanel[self.type][0](notebook)
03012         
03013         self.OnOutline(None)
03014         if self.type in ('points', 'areas'):
03015             self.OnFill(None)
03016         self.OnColor(None)
03017         
03018         self.StylePanel = selectPanel[self.type][1](notebook)
03019         if self.type == 'points':
03020             self.OnSize(None)
03021             self.OnRotation(None)
03022         if self.type == 'areas':
03023             self.OnPattern(None)
03024         
03025         self._layout(notebook)
03026         
03027     def _DataSelectionPanel(self, notebook):
03028         panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
03029         notebook.AddPage(page = panel, text = _("Data selection"))
03030         
03031         border = wx.BoxSizer(wx.VERTICAL)
03032         
03033         # data type
03034         self.checkType1 = self.checkType2 = None
03035         if self.type in ('lines', 'points'):
03036             box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Feature type"))
03037             sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03038             gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
03039             if self.type == 'points':
03040                 label = (_("points"), _("centroids"))
03041             else: 
03042                 label = (_("lines"), _("boundaries"))
03043             if self.type == 'points':
03044                 name = ("point", "centroid")
03045             else:
03046                 name = ("line", "boundary")
03047             self.checkType1 = wx.CheckBox(panel, id = wx.ID_ANY, label = label[0], name = name[0])
03048             self.checkType2 = wx.CheckBox(panel, id = wx.ID_ANY, label = label[1], name = name[1])
03049             self.checkType1.SetValue(self.vPropertiesDict['type'].find(name[0]) >= 0)
03050             self.checkType2.SetValue(self.vPropertiesDict['type'].find(name[1]) >= 0)
03051             
03052             gridBagSizer.Add(self.checkType1, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03053             gridBagSizer.Add(self.checkType2, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03054             sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03055             border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03056         
03057         # layer selection
03058         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Layer selection"))
03059         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03060         self.gridBagSizerL = wx.GridBagSizer(hgap = 5, vgap = 5)
03061         
03062         self.warning =  wx.StaticText(panel, id = wx.ID_ANY, label = "")
03063         if not self.connection:
03064             self.warning = wx.StaticText(panel, id = wx.ID_ANY, label = _("Database connection is not defined in DB file."))
03065         text = wx.StaticText(panel, id = wx.ID_ANY, label = _("Select layer:"))
03066         self.layerChoice = wx.Choice(panel, id = wx.ID_ANY, choices = map(str, self.layers), size = self.spinCtrlSize)
03067         
03068         self.layerChoice.SetStringSelection(self.currLayer)
03069                 
03070         if self.connection:
03071             table = self.mapDBInfo.layers[int(self.currLayer)]['table'] 
03072         else:
03073             table = ""
03074 
03075         self.radioWhere = wx.RadioButton(panel, id = wx.ID_ANY, label = "SELECT * FROM %s WHERE" % table, style = wx.RB_GROUP)
03076         self.textCtrlWhere = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
03077         
03078         
03079         if self.connection:
03080             cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table']) 
03081         else:
03082             cols = []
03083 
03084         self.choiceColumns = wx.Choice(panel, id = wx.ID_ANY, choices = cols)
03085         
03086         self.radioCats = wx.RadioButton(panel, id = wx.ID_ANY, label = "Choose categories ")
03087         self.textCtrlCats = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
03088         self.textCtrlCats.SetToolTipString(_("list of categories (e.g. 1,3,5-7)"))
03089         
03090         if self.vPropertiesDict.has_key('cats'):
03091             self.radioCats.SetValue(True)
03092             self.textCtrlCats.SetValue(self.vPropertiesDict['cats'])
03093         if self.vPropertiesDict.has_key('where'):
03094             self.radioWhere.SetValue(True)
03095             where = self.vPropertiesDict['where'].strip().split(" ",1)
03096             self.choiceColumns.SetStringSelection(where[0])
03097             self.textCtrlWhere.SetValue(where[1])
03098             
03099         row = 0
03100         if not self.connection:
03101             self.gridBagSizerL.Add(self.warning, pos = (0,0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03102             row = 1
03103         self.gridBagSizerL.Add(text, pos = (0 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03104         self.gridBagSizerL.Add(self.layerChoice, pos = (0 + row,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
03105         self.gridBagSizerL.Add(self.radioWhere, pos = (1 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03106         self.gridBagSizerL.Add(self.choiceColumns, pos = (1 + row,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03107         self.gridBagSizerL.Add(self.textCtrlWhere, pos = (1 + row,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03108         self.gridBagSizerL.Add(self.radioCats, pos = (2 + row,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03109         self.gridBagSizerL.Add(self.textCtrlCats, pos = (2 + row,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
03110         
03111         sizer.Add(self.gridBagSizerL, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03112         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03113         
03114         #mask
03115         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Mask"))
03116         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03117         
03118         self.mask = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use current mask"))
03119         if self.vPropertiesDict['masked'] == 'y':
03120             self.mask.SetValue(True) 
03121         else:
03122             self.mask.SetValue(False)
03123         
03124         sizer.Add(self.mask, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03125         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03126 
03127         self.Bind(wx.EVT_CHOICE, self.OnLayer, self.layerChoice)
03128         
03129         panel.SetSizer(border)
03130         panel.Fit()
03131         return panel
03132     
03133     def _ColorsPointAreaPanel(self, notebook):
03134         panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
03135         notebook.AddPage(page = panel, text = _("Colors"))
03136         
03137         border = wx.BoxSizer(wx.VERTICAL)
03138         
03139         #colors - outline
03140         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Outline"))
03141         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03142         self.gridBagSizerO = wx.GridBagSizer(hgap = 5, vgap = 2)
03143         
03144         self.outlineCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw outline"))
03145         self.outlineCheck.SetValue(self.vPropertiesDict['color'] != 'none')
03146         
03147         widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
03148         if fs:
03149             self.widthSpin = fs.FloatSpin(panel, id = wx.ID_ANY, min_val = 0, max_val = 30,
03150                                           increment = 0.5, value = 1, style = fs.FS_RIGHT)
03151             self.widthSpin.SetFormat("%f")
03152             self.widthSpin.SetDigits(2)
03153         else:
03154             self.widthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1,
03155                                          size = self.spinCtrlSize)
03156                                         
03157         if self.vPropertiesDict['color'] == None:
03158             self.vPropertiesDict['color'] = 'none'
03159  
03160         if self.vPropertiesDict['color'] != 'none':
03161             self.widthSpin.SetValue(self.vPropertiesDict['width'] )
03162         else:
03163             self.widthSpin.SetValue(1)
03164 
03165         colorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:"))
03166         self.colorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
03167         if self.vPropertiesDict['color'] != 'none':
03168             self.colorPicker.SetColour(convertRGB(self.vPropertiesDict['color'])) 
03169         else:
03170             self.colorPicker.SetColour(convertRGB('black'))
03171 
03172         self.gridBagSizerO.Add(self.outlineCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03173         self.gridBagSizerO.Add(widthText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03174         self.gridBagSizerO.Add(self.widthSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)        
03175         self.gridBagSizerO.Add(colorText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)                
03176         self.gridBagSizerO.Add(self.colorPicker, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03177         
03178         sizer.Add(self.gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03179         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03180         
03181         self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
03182         
03183         #colors - fill
03184         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Fill")) 
03185         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03186         self.gridBagSizerF = wx.GridBagSizer(hgap = 5, vgap = 2)
03187        
03188         self.fillCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("fill color"))
03189         self.fillCheck.SetValue(self.vPropertiesDict['fcolor'] != 'none' or self.vPropertiesDict['rgbcolumn'] is not None)
03190 
03191         self.colorPickerRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("choose color:"), style = wx.RB_GROUP)
03192         #set choose color option if there is no db connection
03193         if self.connection:
03194             self.colorPickerRadio.SetValue(not self.vPropertiesDict['rgbcolumn'])
03195         else:
03196             self.colorPickerRadio.SetValue(False)            
03197         self.fillColorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
03198         if self.vPropertiesDict['fcolor'] != 'none':
03199             self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict['fcolor'])) 
03200         else:
03201             self.fillColorPicker.SetColour(convertRGB('red'))        
03202         
03203         self.colorColRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("color from map table column:"))
03204         self.colorColChoice = self.getColsChoice(parent = panel)
03205         if self.connection:
03206             if self.vPropertiesDict['rgbcolumn']:
03207                 self.colorColRadio.SetValue(True)
03208                 self.colorColChoice.SetStringSelection(self.vPropertiesDict['rgbcolumn'])
03209             else:
03210                 self.colorColRadio.SetValue(False)
03211                 self.colorColChoice.SetSelection(0)
03212         self.colorColChoice.Enable(self.connection)
03213         self.colorColRadio.Enable(self.connection)
03214         
03215         self.gridBagSizerF.Add(self.fillCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03216         self.gridBagSizerF.Add(self.colorPickerRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03217         self.gridBagSizerF.Add(self.fillColorPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03218         self.gridBagSizerF.Add(self.colorColRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03219         self.gridBagSizerF.Add(self.colorColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)        
03220         
03221         sizer.Add(self.gridBagSizerF, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03222         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03223 
03224         self.Bind(wx.EVT_CHECKBOX, self.OnFill, self.fillCheck)
03225         self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
03226         self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
03227         
03228         panel.SetSizer(border)
03229         panel.Fit()
03230         return panel
03231     
03232     def _ColorsLinePanel(self, notebook):
03233         panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
03234         notebook.AddPage(page = panel, text = _("Colors"))
03235         
03236         border = wx.BoxSizer(wx.VERTICAL)
03237         
03238         #colors - outline
03239         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Outline"))
03240         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03241         self.gridBagSizerO = wx.GridBagSizer(hgap = 5, vgap = 2)
03242         
03243         if self.vPropertiesDict['hcolor'] == None:
03244             self.vPropertiesDict['hcolor'] = 'none'
03245         if self.vPropertiesDict['color'] == None:
03246             self.vPropertiesDict['color'] = 'none'
03247         
03248         self.outlineCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw outline"))
03249         self.outlineCheck.SetValue(self.vPropertiesDict['hcolor'] != 'none')
03250         self.outlineCheck.SetToolTipString(_("No effect for fill color from table column"))
03251         
03252         widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
03253         
03254         if fs:
03255             self.outWidthSpin = fs.FloatSpin(panel, id = wx.ID_ANY, min_val = 0, max_val = 30,
03256                                              increment = 0.5, value = 1, style = fs.FS_RIGHT)
03257             self.outWidthSpin.SetFormat("%f")
03258             self.outWidthSpin.SetDigits(1)
03259         else:
03260             self.outWidthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1,
03261                                          size = self.spinCtrlSize)
03262         
03263         if self.vPropertiesDict['hcolor'] != 'none':
03264             self.outWidthSpin.SetValue(self.vPropertiesDict['hwidth'] )
03265         else:
03266             self.outWidthSpin.SetValue(1)
03267 
03268         colorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color:"))
03269         self.colorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
03270         if self.vPropertiesDict['hcolor'] != 'none':
03271             self.colorPicker.SetColour(convertRGB(self.vPropertiesDict['hcolor']) )
03272         else:
03273             self.colorPicker.SetColour(convertRGB('black'))
03274 
03275         
03276         self.gridBagSizerO.Add(self.outlineCheck, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03277         self.gridBagSizerO.Add(widthText, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03278         self.gridBagSizerO.Add(self.outWidthSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)        
03279         self.gridBagSizerO.Add(colorText, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)                
03280         self.gridBagSizerO.Add(self.colorPicker, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03281         
03282         sizer.Add(self.gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03283         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03284         
03285         self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck)
03286         
03287         #colors - fill
03288         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Fill"))
03289         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03290         self.gridBagSizerF = wx.GridBagSizer(hgap = 5, vgap = 2)
03291        
03292         fillText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Color of lines:"))
03293 
03294         self.colorPickerRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("choose color:"), style = wx.RB_GROUP)
03295 
03296         #set choose color option if there is no db connection
03297         if self.connection:
03298             self.colorPickerRadio.SetValue(not self.vPropertiesDict['rgbcolumn'])
03299         else:
03300             self.colorPickerRadio.SetValue(False)            
03301         self.fillColorPicker = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
03302         if self.vPropertiesDict['color'] != 'none':
03303             self.fillColorPicker.SetColour(convertRGB(self.vPropertiesDict['color']) )
03304         else:
03305             self.fillColorPicker.SetColour(convertRGB('black'))
03306         
03307         self.colorColRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("color from map table column:"))
03308         self.colorColChoice = self.getColsChoice(parent = panel)
03309         if self.connection:
03310             if self.vPropertiesDict['rgbcolumn']:
03311                 self.colorColRadio.SetValue(True)
03312                 self.colorColChoice.SetStringSelection(self.vPropertiesDict['rgbcolumn'])
03313             else:
03314                 self.colorColRadio.SetValue(False)
03315                 self.colorColChoice.SetSelection(0)
03316         self.colorColChoice.Enable(self.connection)
03317         self.colorColRadio.Enable(self.connection)
03318         
03319         self.gridBagSizerF.Add(fillText, pos = (0, 0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03320         self.gridBagSizerF.Add(self.colorPickerRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03321         self.gridBagSizerF.Add(self.fillColorPicker, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03322         self.gridBagSizerF.Add(self.colorColRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
03323         self.gridBagSizerF.Add(self.colorColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)        
03324         
03325         sizer.Add(self.gridBagSizerF, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03326         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03327 
03328         self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio)
03329         self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio)
03330 
03331         panel.SetSizer(border)
03332         panel.Fit()
03333         return panel
03334     
03335     def _StylePointPanel(self, notebook):
03336         panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
03337         notebook.AddPage(page = panel, text = _("Size and style"))
03338         
03339         border = wx.BoxSizer(wx.VERTICAL)
03340         
03341         #symbology
03342         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Symbology"))        
03343         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03344         gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
03345         gridBagSizer.AddGrowableCol(1)
03346     
03347         self.symbolRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("symbol:"), style = wx.RB_GROUP)
03348         self.symbolRadio.SetValue(bool(self.vPropertiesDict['symbol']))
03349             
03350          
03351         self.symbolChoice = wx.Choice(panel, id = wx.ID_ANY, choices = self.symbols)
03352             
03353         self.epsRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("eps file:"))
03354         self.epsRadio.SetValue(bool(self.vPropertiesDict['eps']))
03355         
03356         self.epsFileCtrl = filebrowse.FileBrowseButton(panel, id = wx.ID_ANY, labelText = '',
03357                                 buttonText =  _("Browse"), toolTip = _("Type filename or click browse to choose file"), 
03358                                 dialogTitle = _("Choose a file"), startDirectory = '', initialValue = '',
03359                                 fileMask = "Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", fileMode = wx.OPEN)
03360         if self.vPropertiesDict['symbol']:
03361             self.symbolChoice.SetStringSelection(self.vPropertiesDict['symbol'])
03362             self.epsFileCtrl.SetValue('')
03363         else: #eps chosen
03364             self.epsFileCtrl.SetValue(self.vPropertiesDict['eps'])
03365             self.symbolChoice.SetSelection(0)
03366             
03367         gridBagSizer.Add(self.symbolRadio, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03368         gridBagSizer.Add(self.symbolChoice, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03369         gridBagSizer.Add(self.epsRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03370         gridBagSizer.Add(self.epsFileCtrl, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
03371         
03372         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03373         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03374         
03375         #size
03376         
03377         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size"))        
03378         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03379         gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
03380         gridBagSizer.AddGrowableCol(0)
03381         
03382         self.sizeRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("size:"), style = wx.RB_GROUP)
03383         self.sizeSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 50, initial = 1)
03384         self.sizecolumnRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("size from map table column:"))
03385         self.sizeColChoice = self.getColsChoice(panel)
03386         self.scaleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("scale:"))
03387         self.scaleSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
03388         
03389         self.sizeRadio.SetValue(self.vPropertiesDict['size'] is not None)
03390         self.sizecolumnRadio.SetValue(bool(self.vPropertiesDict['sizecolumn']))
03391         if self.vPropertiesDict['size']:
03392             self.sizeSpin.SetValue(self.vPropertiesDict['size'])
03393         else: self.sizeSpin.SetValue(5)
03394         if self.vPropertiesDict['sizecolumn']:
03395             self.scaleSpin.SetValue(self.vPropertiesDict['scale'])
03396             self.sizeColChoice.SetStringSelection(self.vPropertiesDict['sizecolumn'])
03397         else:
03398             self.scaleSpin.SetValue(1)
03399             self.sizeColChoice.SetSelection(0)
03400         if not self.connection:   
03401             for each in (self.sizecolumnRadio, self.sizeColChoice, self.scaleSpin, self.scaleText):
03402                 each.Disable()
03403             
03404         gridBagSizer.Add(self.sizeRadio, pos = (0, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03405         gridBagSizer.Add(self.sizeSpin, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03406         gridBagSizer.Add(self.sizecolumnRadio, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03407         gridBagSizer.Add(self.sizeColChoice, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
03408         gridBagSizer.Add(self.scaleText, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
03409         gridBagSizer.Add(self.scaleSpin, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03410         
03411         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03412         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03413         
03414         self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizeRadio)
03415         self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizecolumnRadio)
03416         
03417         #rotation
03418         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Rotation"))
03419         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03420         gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
03421         gridBagSizer.AddGrowableCol(1)
03422 
03423         
03424         self.rotateCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("rotate symbols:"))
03425         self.rotateRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("counterclockwise in degrees:"), style = wx.RB_GROUP)
03426         self.rotateSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 0, max = 360, initial = 0)
03427         self.rotatecolumnRadio = wx.RadioButton(panel, id = wx.ID_ANY, label = _("from map table column:"))
03428         self.rotateColChoice = self.getColsChoice(panel)
03429         
03430         self.rotateCheck.SetValue(self.vPropertiesDict['rotation'])
03431         self.rotateRadio.SetValue(self.vPropertiesDict['rotate'] is not None)
03432         self.rotatecolumnRadio.SetValue(bool(self.vPropertiesDict['rotatecolumn']))
03433         if self.vPropertiesDict['rotate']:
03434             self.rotateSpin.SetValue(self.vPropertiesDict['rotate'])
03435         else:
03436             self.rotateSpin.SetValue(0)
03437         if self.vPropertiesDict['rotatecolumn']:
03438             self.rotateColChoice.SetStringSelection(self.vPropertiesDict['rotatecolumn'])
03439         else:
03440             self.rotateColChoice.SetSelection(0)
03441             
03442         gridBagSizer.Add(self.rotateCheck, pos = (0, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03443         gridBagSizer.Add(self.rotateRadio, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03444         gridBagSizer.Add(self.rotateSpin, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03445         gridBagSizer.Add(self.rotatecolumnRadio, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03446         gridBagSizer.Add(self.rotateColChoice, pos = (2, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
03447         
03448         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03449         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03450         
03451         self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotateCheck)
03452         self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotateRadio)
03453         self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotatecolumnRadio)
03454         
03455         panel.SetSizer(border)
03456         panel.Fit()
03457         return panel
03458     
03459     def _StyleLinePanel(self, notebook):
03460         panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
03461         notebook.AddPage(page = panel, text = _("Size and style"))
03462         
03463         border = wx.BoxSizer(wx.VERTICAL)
03464         
03465         #width
03466         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Width"))       
03467         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03468         gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
03469         
03470         widthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Set width (pts):"))
03471         if fs:
03472             self.widthSpin = fs.FloatSpin(panel, id = wx.ID_ANY, min_val = 0, max_val = 30,
03473                                         increment = 0.5, value = 1, style = fs.FS_RIGHT)
03474             self.widthSpin.SetFormat("%f")
03475             self.widthSpin.SetDigits(1)
03476         else:
03477             self.widthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1)
03478             
03479         self.cwidthCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("multiply width by category value"))
03480         
03481         if self.vPropertiesDict['width']:
03482             self.widthSpin.SetValue(self.vPropertiesDict['width'])
03483             self.cwidthCheck.SetValue(False)
03484         else:
03485             self.widthSpin.SetValue(self.vPropertiesDict['cwidth'])
03486             self.cwidthCheck.SetValue(True)
03487         
03488         gridBagSizer.Add(widthText, pos = (0, 0),  flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03489         gridBagSizer.Add(self.widthSpin, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03490         gridBagSizer.Add(self.cwidthCheck, pos = (1, 0), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03491         
03492         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03493         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03494         
03495         #style
03496         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Line style"))
03497         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03498         gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
03499         
03500         styleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose line style:"))
03501         penStyles = ["solid", "dashed", "dotted", "dashdotted"]
03502         self.styleCombo = PenStyleComboBox(panel, choices = penStyles, validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY'))
03503 ##        self.styleCombo = wx.ComboBox(panel, id = wx.ID_ANY,
03504 ##                            choices = ["solid", "dashed", "dotted", "dashdotted"],
03505 ##                            validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY'))
03506 ##        self.styleCombo.SetToolTipString(_("It's possible to enter a series of 0's and 1's too. "\
03507 ##                                    "The first block of repeated zeros or ones represents 'draw', "\
03508 ##                                    "the second block represents 'blank'. An even number of blocks "\
03509 ##                                    "will repeat the pattern, an odd number of blocks will alternate the pattern."))
03510         linecapText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose linecap:"))
03511         self.linecapChoice = wx.Choice(panel, id = wx.ID_ANY, choices = ["butt", "round", "extended_butt"])
03512         
03513         self.styleCombo.SetValue(self.vPropertiesDict['style'])
03514         self.linecapChoice.SetStringSelection(self.vPropertiesDict['linecap'])
03515         
03516         gridBagSizer.Add(styleText, pos = (0, 0),  flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03517         gridBagSizer.Add(self.styleCombo, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
03518         gridBagSizer.Add(linecapText, pos = (1, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03519         gridBagSizer.Add(self.linecapChoice, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
03520         
03521         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03522         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03523         
03524         panel.SetSizer(border)
03525         panel.Fit()
03526         return panel
03527         
03528     def _StyleAreaPanel(self, notebook):
03529         panel = wx.Panel(parent = notebook, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
03530         notebook.AddPage(page = panel, text = _("Size and style"))
03531         
03532         border = wx.BoxSizer(wx.VERTICAL)
03533         
03534         #pattern
03535         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Pattern"))
03536         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
03537         gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
03538         gridBagSizer.AddGrowableCol(1)
03539         
03540         self.patternCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use pattern:"))
03541         self.patFileCtrl = filebrowse.FileBrowseButton(panel, id = wx.ID_ANY, labelText = _("Choose pattern file:"),
03542                                 buttonText =  _("Browse"), toolTip = _("Type filename or click browse to choose file"), 
03543                                 dialogTitle = _("Choose a file"), startDirectory = self.patternPath, initialValue = '',
03544                                 fileMask = "Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", fileMode = wx.OPEN)
03545         self.patWidthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("pattern line width (pts):"))
03546         self.patWidthSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
03547         self.patScaleText = wx.StaticText(panel, id = wx.ID_ANY, label = _("pattern scale factor:"))
03548         self.patScaleSpin = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 25, initial = 1)
03549         
03550         self.patternCheck.SetValue(bool(self.vPropertiesDict['pat']))
03551         if self.patternCheck.GetValue():
03552             self.patFileCtrl.SetValue(self.vPropertiesDict['pat'])
03553             self.patWidthSpin.SetValue(self.vPropertiesDict['pwidth'])
03554             self.patScaleSpin.SetValue(self.vPropertiesDict['scale'])
03555         
03556         gridBagSizer.Add(self.patternCheck, pos = (0, 0),  flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03557         gridBagSizer.Add(self.patFileCtrl, pos = (1, 0), span = (1, 2),flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
03558         gridBagSizer.Add(self.patWidthText, pos = (2, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03559         gridBagSizer.Add(self.patWidthSpin, pos = (2, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03560         gridBagSizer.Add(self.patScaleText, pos = (3, 0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03561         gridBagSizer.Add(self.patScaleSpin, pos = (3, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03562         
03563         
03564         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
03565         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03566         
03567         self.Bind(wx.EVT_CHECKBOX, self.OnPattern, self.patternCheck)
03568         
03569         panel.SetSizer(border)
03570         panel.Fit()
03571         return panel
03572 
03573     def OnLayer(self, event):
03574         """!Change columns on layer change """
03575         if self.layerChoice.GetStringSelection() == self.currLayer:
03576             return
03577         self.currLayer = self.layerChoice.GetStringSelection()
03578         if self.connection:
03579             cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table']) 
03580         else:
03581             cols = []
03582 
03583         self.choiceColumns.SetItems(cols)
03584 
03585         self.choiceColumns.SetSelection(0)
03586         if self.type in ('points', 'lines'):
03587             self.colorColChoice.SetItems(cols)
03588             self.colorColChoice.SetSelection(0)
03589             
03590     def OnOutline(self, event):
03591         for widget in self.gridBagSizerO.GetChildren():
03592             if widget.GetWindow() != self.outlineCheck:
03593                 widget.GetWindow().Enable(self.outlineCheck.GetValue())
03594                 
03595     def OnFill(self, event):
03596         enable = self.fillCheck.GetValue()
03597         
03598         self.colorColChoice.Enable(enable)
03599         self.colorColRadio.Enable(enable)
03600         self.fillColorPicker.Enable(enable)
03601         self.colorPickerRadio.Enable(enable)
03602         if enable:
03603             self.OnColor(None)
03604         if not self.connection:
03605             self.colorColChoice.Disable()
03606             self.colorColRadio.Disable()
03607             
03608     def OnColor(self, event):
03609         self.colorColChoice.Enable(self.colorColRadio.GetValue())
03610         self.fillColorPicker.Enable(self.colorPickerRadio.GetValue())
03611             
03612     def OnSize(self, event):
03613         self.sizeSpin.Enable(self.sizeRadio.GetValue())
03614         self.sizeColChoice.Enable(self.sizecolumnRadio.GetValue())
03615         self.scaleText.Enable(self.sizecolumnRadio.GetValue())
03616         self.scaleSpin.Enable(self.sizecolumnRadio.GetValue())
03617         
03618     def OnRotation(self, event):
03619         for each in (self.rotateRadio, self.rotatecolumnRadio, self.rotateColChoice, self.rotateSpin):
03620             if self.rotateCheck.GetValue():
03621                 each.Enable()
03622                 self.OnRotationType(event = None)     
03623             else:
03624                 each.Disable()
03625            
03626     def OnRotationType(self, event):
03627         self.rotateSpin.Enable(self.rotateRadio.GetValue())
03628         self.rotateColChoice.Enable(self.rotatecolumnRadio.GetValue())
03629         
03630     def OnPattern(self, event):
03631         for each in (self.patFileCtrl, self.patWidthText, self.patWidthSpin, self.patScaleText, self.patScaleSpin):
03632             each.Enable(self.patternCheck.GetValue())
03633             
03634     def EnableLayerSelection(self, enable = True):
03635         for widget in self.gridBagSizerL.GetChildren():
03636             if widget.GetWindow() != self.warning:
03637                 widget.GetWindow().Enable(enable)
03638                 
03639     def getColsChoice(self, parent):
03640         """!Returns a wx.Choice with table columns"""
03641         if self.connection:
03642             cols = self.mapDBInfo.GetColumns(self.mapDBInfo.layers[int(self.currLayer)]['table']) 
03643         else:
03644             cols = []
03645 
03646         choice = wx.Choice(parent = parent, id = wx.ID_ANY, choices = cols)
03647         return choice
03648         
03649     def update(self):
03650         #feature type
03651         if self.type in ('lines', 'points'):
03652             featureType = None
03653             if self.checkType1.GetValue():
03654                 featureType = self.checkType1.GetName()
03655                 if self.checkType2.GetValue():
03656                     featureType += " or " + self.checkType2.GetName()
03657             elif self.checkType2.GetValue():
03658                 featureType = self.checkType2.GetName()
03659             if featureType:
03660                 self.vPropertiesDict['type'] = featureType
03661             
03662         # is connection
03663         self.vPropertiesDict['connection'] = self.connection
03664         if self.connection:
03665             self.vPropertiesDict['layer'] = self.layerChoice.GetStringSelection()
03666             if self.radioCats.GetValue() and not self.textCtrlCats.IsEmpty():
03667                 self.vPropertiesDict['cats'] = self.textCtrlCats.GetValue()
03668             elif self.radioWhere.GetValue() and not self.textCtrlWhere.IsEmpty():
03669                 self.vPropertiesDict['where'] = self.choiceColumns.GetStringSelection() + " " \
03670                                                                 + self.textCtrlWhere.GetValue()
03671         #mask
03672         if self.mask.GetValue():
03673             self.vPropertiesDict['masked'] = 'y' 
03674         else:
03675             self.vPropertiesDict['masked'] = 'n'
03676 
03677         #colors
03678         if self.type in ('points', 'areas'):
03679             if self.outlineCheck.GetValue():
03680                 self.vPropertiesDict['color'] = convertRGB(self.colorPicker.GetColour())
03681                 self.vPropertiesDict['width'] = self.widthSpin.GetValue()
03682             else:
03683                 self.vPropertiesDict['color'] = 'none'
03684                 
03685             if self.fillCheck.GetValue():
03686                 if self.colorPickerRadio.GetValue():
03687                     self.vPropertiesDict['fcolor'] = convertRGB(self.fillColorPicker.GetColour())
03688                     self.vPropertiesDict['rgbcolumn'] = None
03689                 if self.colorColRadio.GetValue():
03690                     self.vPropertiesDict['fcolor'] = 'none'# this color is taken in case of no record in rgb column
03691                     self.vPropertiesDict['rgbcolumn'] = self.colorColChoice.GetStringSelection()
03692             else:
03693                 self.vPropertiesDict['fcolor'] = 'none'    
03694                 
03695         if self.type == 'lines':
03696                 #hcolor only when no rgbcolumn
03697             if self.outlineCheck.GetValue():# and self.fillCheck.GetValue() and self.colorColRadio.GetValue():
03698                 self.vPropertiesDict['hcolor'] = convertRGB(self.colorPicker.GetColour())
03699                 self.vPropertiesDict['hwidth'] = self.outWidthSpin.GetValue()
03700                 
03701             else:
03702                 self.vPropertiesDict['hcolor'] = 'none'
03703                 
03704             if self.colorPickerRadio.GetValue():
03705                 self.vPropertiesDict['color'] = convertRGB(self.fillColorPicker.GetColour())
03706                 self.vPropertiesDict['rgbcolumn'] = None
03707             if self.colorColRadio.GetValue():
03708                 self.vPropertiesDict['color'] = 'none'# this color is taken in case of no record in rgb column
03709                 self.vPropertiesDict['rgbcolumn'] = self.colorColChoice.GetStringSelection()
03710         #
03711         #size and style
03712         #
03713         
03714         if self.type == 'points':
03715             #symbols
03716             if self.symbolRadio.GetValue():
03717                 self.vPropertiesDict['symbol'] = self.symbolChoice.GetStringSelection()
03718                 self.vPropertiesDict['eps'] = None
03719             else:
03720                 self.vPropertiesDict['eps'] = self.epsFileCtrl.GetValue()
03721                 self.vPropertiesDict['symbol'] = None
03722             #size
03723             if self.sizeRadio.GetValue():
03724                 self.vPropertiesDict['size'] = self.sizeSpin.GetValue()
03725                 self.vPropertiesDict['sizecolumn'] = None
03726                 self.vPropertiesDict['scale'] = None
03727             else:
03728                 self.vPropertiesDict['sizecolumn'] = self.sizeColChoice.GetStringSelection()
03729                 self.vPropertiesDict['scale'] = self.scaleSpin.GetValue()
03730                 self.vPropertiesDict['size'] = None
03731             
03732             #rotation
03733             self.vPropertiesDict['rotate'] = None
03734             self.vPropertiesDict['rotatecolumn'] = None
03735             self.vPropertiesDict['rotation'] = False
03736             if self.rotateCheck.GetValue():
03737                 self.vPropertiesDict['rotation'] = True
03738             if self.rotateRadio.GetValue():
03739                 self.vPropertiesDict['rotate'] = self.rotateSpin.GetValue()
03740             else:
03741                 self.vPropertiesDict['rotatecolumn'] = self.rotateColChoice.GetStringSelection()
03742                 
03743         if self.type == 'areas':
03744             #pattern
03745             self.vPropertiesDict['pat'] = None 
03746             if self.patternCheck.GetValue() and bool(self.patFileCtrl.GetValue()):
03747                 self.vPropertiesDict['pat'] = self.patFileCtrl.GetValue()
03748                 self.vPropertiesDict['pwidth'] = self.patWidthSpin.GetValue()
03749                 self.vPropertiesDict['scale'] = self.patScaleSpin.GetValue()
03750                 
03751         if self.type == 'lines':
03752             #width
03753             if self.cwidthCheck.GetValue():
03754                 self.vPropertiesDict['cwidth'] = self.widthSpin.GetValue()
03755                 self.vPropertiesDict['width'] = None
03756             else:
03757                 self.vPropertiesDict['width'] = self.widthSpin.GetValue()
03758                 self.vPropertiesDict['cwidth'] = None
03759             #line style
03760             if self.styleCombo.GetValue():
03761                 self.vPropertiesDict['style'] = self.styleCombo.GetValue() 
03762             else:
03763                 self.vPropertiesDict['style'] = 'solid'
03764 
03765             self.vPropertiesDict['linecap'] = self.linecapChoice.GetStringSelection()
03766             
03767     def OnOK(self, event):
03768         self.update()
03769         event.Skip()
03770         
03771 class LegendDialog(PsmapDialog):
03772     def __init__(self, parent, id, settings, page):
03773         PsmapDialog.__init__(self, parent = parent, id = id, title = "Legend settings", settings = settings)
03774         self.objectType = ('rasterLegend', 'vectorLegend')
03775         self.instruction = settings
03776         map = self.instruction.FindInstructionByType('map')
03777         if map:
03778             self.mapId = map.id 
03779         else:
03780             self.mapId = None
03781 
03782         vector = self.instruction.FindInstructionByType('vector')
03783         if vector:
03784             self.vectorId = vector.id 
03785         else:
03786             self.vectorId = None
03787 
03788         raster = self.instruction.FindInstructionByType('raster')
03789         if raster:
03790             self.rasterId = raster.id 
03791         else:
03792             self.rasterId = None
03793 
03794         self.pageId = self.instruction.FindInstructionByType('page').id
03795         currPage = self.instruction[self.pageId].GetInstruction()
03796         #raster legend
03797         if self.id[0] is not None:
03798             self.rasterLegend = self.instruction[self.id[0]]
03799             self.rLegendDict = self.rasterLegend.GetInstruction()
03800         else:
03801             self.id[0] = wx.NewId()
03802             self.rasterLegend = RasterLegend(self.id[0])
03803             self.rLegendDict = self.rasterLegend.GetInstruction()
03804             self.rLegendDict['where'] = currPage['Left'], currPage['Top']
03805             
03806             
03807         #vector legend    
03808         if self.id[1] is not None:
03809             self.vLegendDict = self.instruction[self.id[1]].GetInstruction()
03810         else:
03811             self.id[1] = wx.NewId()
03812             vectorLegend = VectorLegend(self.id[1])
03813             self.vLegendDict = vectorLegend.GetInstruction()
03814             self.vLegendDict['where'] = currPage['Left'], currPage['Top']
03815             
03816         if self.rasterId:
03817             self.currRaster = self.instruction[self.rasterId]['raster'] 
03818         else:
03819             self.currRaster = None
03820 
03821         #notebook
03822         self.notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)
03823         self.panelRaster = self._rasterLegend(self.notebook)
03824         self.panelVector = self._vectorLegend(self.notebook)  
03825         self.OnRaster(None)
03826         self.OnRange(None)
03827         self.OnIsLegend(None)
03828         self.OnSpan(None)
03829         self.OnBorder(None)
03830                 
03831         self._layout(self.notebook)
03832         self.notebook.ChangeSelection(page)
03833         self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging)
03834         
03835     def OnPageChanging(self, event):
03836         """!Workaround to scroll up to see the checkbox"""
03837         wx.CallAfter(self.FindWindowByName('rasterPanel').ScrollChildIntoView,
03838                                             self.FindWindowByName('showRLegend'))
03839         wx.CallAfter(self.FindWindowByName('vectorPanel').ScrollChildIntoView,
03840                                             self.FindWindowByName('showVLegend'))
03841                                             
03842     def _rasterLegend(self, notebook):
03843         panel = scrolled.ScrolledPanel(parent = notebook, id = wx.ID_ANY, size = (-1, 500), style = wx.TAB_TRAVERSAL)
03844         panel.SetupScrolling(scroll_x = False, scroll_y = True)
03845         panel.SetName('rasterPanel')
03846         notebook.AddPage(page = panel, text = _("Raster legend"))
03847 
03848         border = wx.BoxSizer(wx.VERTICAL)
03849         # is legend
03850         self.isRLegend = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Show raster legend"))
03851         self.isRLegend.SetValue(self.rLegendDict['rLegend'])
03852         self.isRLegend.SetName("showRLegend")
03853         border.Add(item = self.isRLegend, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03854 
03855         # choose raster
03856         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Source raster"))
03857         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
03858         flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
03859         flexSizer.AddGrowableCol(1)
03860         
03861         self.rasterDefault = wx.RadioButton(panel, id = wx.ID_ANY, label = _("current raster"), style = wx.RB_GROUP)
03862         self.rasterOther = wx.RadioButton(panel, id = wx.ID_ANY, label = _("select raster"))
03863         self.rasterDefault.SetValue(self.rLegendDict['rasterDefault'])#
03864         self.rasterOther.SetValue(not self.rLegendDict['rasterDefault'])#
03865 
03866         rasterType = getRasterType(map = self.currRaster)
03867 
03868         self.rasterCurrent = wx.StaticText(panel, id = wx.ID_ANY,
03869                                 label = _("%(rast)s: type %(type)s") % { 'rast' : self.currRaster,
03870                                                                          'type' : rasterType })
03871         self.rasterSelect = Select(panel, id = wx.ID_ANY, size = globalvar.DIALOG_GSELECT_SIZE,
03872                                     type = 'raster', multiple = False,
03873                                     updateOnPopup = True, onPopup = None)
03874         if not self.rLegendDict['rasterDefault']:
03875             self.rasterSelect.SetValue(self.rLegendDict['raster'])
03876         else:
03877             self.rasterSelect.SetValue('')
03878         flexSizer.Add(self.rasterDefault, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03879         flexSizer.Add(self.rasterCurrent, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border = 10)
03880         flexSizer.Add(self.rasterOther, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03881         flexSizer.Add(self.rasterSelect, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
03882         
03883         sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
03884         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03885         
03886         # type of legend
03887         
03888         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Type of legend"))        
03889         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
03890         vbox = wx.BoxSizer(wx.VERTICAL)
03891         self.discrete = wx.RadioButton(parent = panel, id = wx.ID_ANY, 
03892                         label = " %s " % _("discrete legend (categorical maps)"), style = wx.RB_GROUP)
03893         self.continuous = wx.RadioButton(parent = panel, id = wx.ID_ANY, 
03894                         label = " %s " % _("continuous color gradient legend (floating point map)"))
03895         
03896         vbox.Add(self.discrete, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
03897         vbox.Add(self.continuous, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 0)
03898         sizer.Add(item = vbox, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
03899         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03900         
03901         # size, position and font
03902         self.sizePositionFont(legendType = 'raster', parent = panel, mainSizer = border)
03903         
03904         # advanced settings
03905         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Advanced legend settings"))
03906         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
03907         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
03908         # no data
03909         self.nodata = wx.CheckBox(panel, id = wx.ID_ANY, label = _('draw "no data" box'))
03910         if self.rLegendDict['nodata'] == 'y':
03911             self.nodata.SetValue(True)
03912         else: 
03913             self.nodata.SetValue(False)
03914         #tickbar
03915         self.ticks = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw ticks across color table"))
03916         if self.rLegendDict['tickbar'] == 'y':
03917             self.ticks.SetValue(True)
03918         else:
03919             self.ticks.SetValue(False)
03920         # range
03921         if self.rasterId and self.instruction[self.rasterId]['raster']:
03922             rinfo = grass.raster_info(self.instruction[self.rasterId]['raster'])
03923             self.minim, self.maxim = rinfo['min'], rinfo['max']
03924         else:
03925             self.minim, self.maxim = 0,0
03926         self.range = wx.CheckBox(panel, id = wx.ID_ANY, label = _("range"))
03927         self.range.SetValue(self.rLegendDict['range'])
03928         self.minText =  wx.StaticText(panel, id = wx.ID_ANY, label = "min (%s)" % self.minim)
03929         self.maxText =  wx.StaticText(panel, id = wx.ID_ANY, label = "max (%s)" % self.maxim)       
03930         self.min = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(self.rLegendDict['min']))
03931         self.max = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(self.rLegendDict['max']))
03932         
03933         gridBagSizer.Add(self.nodata, pos = (0,0), span = (1,5), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03934         gridBagSizer.Add(self.ticks, pos = (1,0), span = (1,5), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03935         gridBagSizer.Add(self.range, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03936         gridBagSizer.Add(self.minText, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
03937         gridBagSizer.Add(self.min, pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03938         gridBagSizer.Add(self.maxText, pos = (2,3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_RIGHT, border = 0)
03939         gridBagSizer.Add(self.max, pos = (2,4), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03940         
03941         sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
03942         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03943    
03944         panel.SetSizer(border)
03945         panel.Fit()
03946         
03947         # bindings
03948         self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterDefault)
03949         self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterOther)
03950         self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isRLegend)
03951         self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.discrete)
03952         self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.continuous)
03953 ##        self.Bind(wx.EVT_CHECKBOX, self.OnDefaultSize, panel.defaultSize)
03954         self.Bind(wx.EVT_CHECKBOX, self.OnRange, self.range)
03955         self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster)
03956         
03957         return panel
03958     
03959     def _vectorLegend(self, notebook):
03960         panel = scrolled.ScrolledPanel(parent = notebook, id = wx.ID_ANY, size = (-1, 500), style = wx.TAB_TRAVERSAL)
03961         panel.SetupScrolling(scroll_x = False, scroll_y = True)
03962         panel.SetName('vectorPanel')
03963         notebook.AddPage(page = panel, text = _("Vector legend"))
03964 
03965         border = wx.BoxSizer(wx.VERTICAL)
03966         # is legend
03967         self.isVLegend = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Show vector legend"))
03968         self.isVLegend.SetValue(self.vLegendDict['vLegend'])
03969         self.isVLegend.SetName("showVLegend")
03970         border.Add(item = self.isVLegend, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
03971         
03972         #vector maps, their order, labels
03973         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Source vector maps"))
03974         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
03975         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
03976         gridBagSizer.AddGrowableCol(0,3)
03977         gridBagSizer.AddGrowableCol(1,1)
03978         
03979         vectorText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Choose vector maps and their order in legend"))
03980 
03981         self.vectorListCtrl = CheckListCtrl(panel)
03982         
03983         self.vectorListCtrl.InsertColumn(0, _("Vector map"))
03984         self.vectorListCtrl.InsertColumn(1, _("Label"))
03985         if self.vectorId:
03986             vectors = sorted(self.instruction[self.vectorId]['list'], key = lambda x: x[3])
03987             
03988             for vector in vectors:
03989                 index = self.vectorListCtrl.InsertStringItem(sys.maxint, vector[0].split('@')[0])
03990                 self.vectorListCtrl.SetStringItem(index, 1, vector[4])
03991                 self.vectorListCtrl.SetItemData(index, index)
03992                 self.vectorListCtrl.CheckItem(index, True)
03993                 if vector[3] == 0:
03994                     self.vectorListCtrl.CheckItem(index, False)
03995         if not self.vectorId:
03996             self.vectorListCtrl.SetColumnWidth(0, 100)
03997         else:
03998             self.vectorListCtrl.SetColumnWidth(0, wx.LIST_AUTOSIZE)
03999         self.vectorListCtrl.SetColumnWidth(1, wx.LIST_AUTOSIZE)
04000         
04001         self.btnUp = wx.Button(panel, id = wx.ID_ANY, label = _("Up"))
04002         self.btnDown = wx.Button(panel, id = wx.ID_ANY, label = _("Down"))
04003         self.btnLabel = wx.Button(panel, id = wx.ID_ANY, label = _("Edit label"))
04004       
04005         gridBagSizer.Add(vectorText, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04006         gridBagSizer.Add(self.vectorListCtrl, pos = (1,0), span = (3,1), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
04007         gridBagSizer.Add(self.btnUp, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04008         gridBagSizer.Add(self.btnDown, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04009         gridBagSizer.Add(self.btnLabel, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04010         
04011         sizer.Add(gridBagSizer, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
04012         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
04013         
04014         # size, position and font
04015         self.sizePositionFont(legendType = 'vector', parent = panel, mainSizer = border)
04016          
04017         # border
04018         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Border"))
04019         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
04020         flexGridSizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
04021         
04022         self.borderCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("draw border around legend"))
04023         self.borderColorCtrl = wx.ColourPickerCtrl(panel, id = wx.ID_ANY, style = wx.FNTP_FONTDESC_AS_LABEL)
04024         if self.vLegendDict['border'] == 'none':
04025             self.borderColorCtrl.SetColour(wx.BLACK)
04026             self.borderCheck.SetValue(False)
04027         else:
04028             self.borderColorCtrl.SetColour(convertRGB(self.vLegendDict['border']))
04029             self.borderCheck.SetValue(True)
04030             
04031         flexGridSizer.Add(self.borderCheck, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)    
04032         flexGridSizer.Add(self.borderColorCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04033         sizer.Add(item = flexGridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
04034         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
04035         
04036         self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp)
04037         self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown)  
04038         self.Bind(wx.EVT_BUTTON, self.OnEditLabel, self.btnLabel)
04039         self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isVLegend)    
04040         self.Bind(wx.EVT_CHECKBOX, self.OnSpan, panel.spanRadio)  
04041         self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck)
04042         self.Bind(wx.EVT_FONTPICKER_CHANGED, self.OnFont, panel.font['fontCtrl']) 
04043         
04044         panel.SetSizer(border)
04045         
04046         panel.Fit()
04047         return panel
04048     
04049     def sizePositionFont(self, legendType, parent, mainSizer):
04050         """!Insert widgets for size, position and font control"""
04051         if legendType == 'raster':
04052             legendDict = self.rLegendDict  
04053         else:
04054             legendDict = self.vLegendDict
04055         panel = parent
04056         border = mainSizer
04057         
04058         # size and position        
04059         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size and position"))
04060         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
04061         #unit
04062         self.AddUnits(parent = panel, dialogDict = legendDict)
04063         unitBox = wx.BoxSizer(wx.HORIZONTAL)
04064         unitBox.Add(panel.units['unitsLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.LEFT, border = 10)
04065         unitBox.Add(panel.units['unitsCtrl'], proportion = 1, flag = wx.ALL, border = 5)
04066         sizer.Add(unitBox, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04067         
04068         hBox = wx.BoxSizer(wx.HORIZONTAL)
04069         posBox = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_("Position"))
04070         posSizer = wx.StaticBoxSizer(posBox, wx.VERTICAL)       
04071         sizeBox = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size"))
04072         sizeSizer = wx.StaticBoxSizer(sizeBox, wx.VERTICAL) 
04073         posGridBagSizer = wx.GridBagSizer(hgap = 10, vgap = 5)
04074         posGridBagSizer.AddGrowableRow(2)
04075         
04076         #position
04077         self.AddPosition(parent = panel, dialogDict = legendDict)
04078         
04079         posGridBagSizer.Add(panel.position['xLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04080         posGridBagSizer.Add(panel.position['xCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04081         posGridBagSizer.Add(panel.position['yLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04082         posGridBagSizer.Add(panel.position['yCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04083         posGridBagSizer.Add(panel.position['comment'], pos = (2,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
04084         posSizer.Add(posGridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
04085         
04086         #size
04087         width = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width:"))
04088         if legendDict['width']:
04089             w = self.unitConv.convert(value = float(legendDict['width']), fromUnit = 'inch', toUnit = legendDict['unit'])
04090         else: 
04091             w = ''
04092         panel.widthCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(w), validator = TCValidator("DIGIT_ONLY"))
04093         panel.widthCtrl.SetToolTipString(_("Leave the edit field empty, to use default values."))
04094         
04095         if legendType == 'raster':
04096 ##            panel.defaultSize = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use default size"))
04097 ##            panel.defaultSize.SetValue(legendDict['defaultSize'])
04098             
04099             panel.heightOrColumnsLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:"))
04100             if legendDict['height']:
04101                 h = self.unitConv.convert(value = float(legendDict['height']), fromUnit = 'inch', toUnit = legendDict['unit'])
04102             else:
04103                 h = ''
04104             panel.heightOrColumnsCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = str(h), validator = TCValidator("DIGIT_ONLY"))
04105             
04106             self.rSizeGBSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
04107 ##            self.rSizeGBSizer.Add(panel.defaultSize, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04108             self.rSizeGBSizer.Add(width, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04109             self.rSizeGBSizer.Add(panel.widthCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04110             self.rSizeGBSizer.Add(panel.heightOrColumnsLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04111             self.rSizeGBSizer.Add(panel.heightOrColumnsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04112             sizeSizer.Add(self.rSizeGBSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
04113             
04114         if legendType == 'vector':
04115             panel.widthCtrl.SetToolTipString(_("Width of the color symbol (for lines)\nin front of the legend text")) 
04116             #columns
04117             minVect, maxVect = 0, 0
04118             if self.vectorId:
04119                 minVect = 1
04120                 maxVect = min(10, len(self.instruction[self.vectorId]['list']))
04121             cols = wx.StaticText(panel, id = wx.ID_ANY, label = _("Columns:"))
04122             panel.colsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, value = "",
04123                                         min = minVect, max = maxVect, initial = legendDict['cols'])
04124             #span
04125             panel.spanRadio = wx.CheckBox(panel, id = wx.ID_ANY, label = _("column span:"))
04126             panel.spanTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = '')
04127             panel.spanTextCtrl.SetToolTipString(_("Column separation distance between the left edges\n"\
04128                                                 "of two columns in a multicolumn legend"))
04129             if legendDict['span']:
04130                 panel.spanRadio.SetValue(True)
04131                 s = self.unitConv.convert(value = float(legendDict['span']), fromUnit = 'inch', toUnit = legendDict['unit'])    
04132                 panel.spanTextCtrl.SetValue(str(s))
04133             else:
04134                 panel.spanRadio.SetValue(False)
04135                 
04136             self.vSizeGBSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
04137             self.vSizeGBSizer.AddGrowableCol(1)
04138             self.vSizeGBSizer.Add(width, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04139             self.vSizeGBSizer.Add(panel.widthCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04140             self.vSizeGBSizer.Add(cols, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04141             self.vSizeGBSizer.Add(panel.colsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04142             self.vSizeGBSizer.Add(panel.spanRadio, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04143             self.vSizeGBSizer.Add(panel.spanTextCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04144             sizeSizer.Add(self.vSizeGBSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)        
04145         
04146         hBox.Add(posSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 3)
04147         hBox.Add(sizeSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 3)
04148         sizer.Add(hBox, proportion = 0, flag = wx.EXPAND, border = 0)
04149         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
04150               
04151         # font        
04152         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
04153         fontSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
04154         flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
04155         flexSizer.AddGrowableCol(1)
04156         
04157         if legendType == 'raster':
04158             self.AddFont(parent = panel, dialogDict = legendDict, color = True)
04159         else:
04160             self.AddFont(parent = panel, dialogDict = legendDict, color = False)            
04161         flexSizer.Add(panel.font['fontLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04162         flexSizer.Add(panel.font['fontCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04163         flexSizer.Add(panel.font['fontSizeLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04164         flexSizer.Add(panel.font['fontSizeCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04165         if legendType == 'raster':
04166             flexSizer.Add(panel.font['colorLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
04167             flexSizer.Add(panel.font['colorCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04168         
04169         fontSizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
04170         border.Add(item = fontSizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)    
04171 
04172     #   some enable/disable methods  
04173         
04174     def OnIsLegend(self, event):
04175         """!Enables and disables controls, it depends if raster or vector legend is checked"""
04176         page = self.notebook.GetSelection()
04177         if page == 0 or event is None:
04178             children = self.panelRaster.GetChildren()
04179             if self.isRLegend.GetValue():
04180                 for i,widget in enumerate(children):
04181                         widget.Enable()
04182                 self.OnRaster(None)
04183                 self.OnRange(None)
04184                 self.OnDiscrete(None)
04185             else:
04186                 for widget in children:
04187                     if widget.GetName() != 'showRLegend':
04188                         widget.Disable()
04189         if page == 1 or event is None:
04190             children = self.panelVector.GetChildren()
04191             if self.isVLegend.GetValue():
04192                 for i, widget in enumerate(children):
04193                         widget.Enable()
04194                 self.OnSpan(None)
04195                 self.OnBorder(None)
04196             else:
04197                 for widget in children:
04198                     if widget.GetName() != 'showVLegend':
04199                         widget.Disable()
04200                     
04201     def OnRaster(self, event):
04202         if self.rasterDefault.GetValue():#default
04203             self.rasterSelect.Disable()
04204             type = getRasterType(self.currRaster)
04205         else:#select raster
04206             self.rasterSelect.Enable()
04207             map = self.rasterSelect.GetValue()
04208             type = getRasterType(map)
04209   
04210         if type == 'CELL':
04211             self.discrete.SetValue(True)
04212         elif type in ('FCELL', 'DCELL'):
04213             self.continuous.SetValue(True)
04214         if event is None:
04215             if self.rLegendDict['discrete'] == 'y':
04216                 self.discrete.SetValue(True)
04217             elif self.rLegendDict['discrete'] == 'n':
04218                 self.continuous.SetValue(True)
04219         self.OnDiscrete(None)
04220         
04221     def OnDiscrete(self, event):
04222         """! Change control according to the type of legend"""
04223         enabledSize = self.panelRaster.heightOrColumnsCtrl.IsEnabled()
04224         self.panelRaster.heightOrColumnsCtrl.Destroy()
04225         if self.discrete.GetValue():
04226             self.panelRaster.heightOrColumnsLabel.SetLabel(_("Columns:"))
04227             self.panelRaster.heightOrColumnsCtrl = wx.SpinCtrl(self.panelRaster, id = wx.ID_ANY, value = "", min = 1, max = 10, initial = self.rLegendDict['cols'])
04228             self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
04229             self.nodata.Enable()
04230             self.range.Disable()
04231             self.min.Disable()
04232             self.max.Disable()
04233             self.minText.Disable()
04234             self.maxText.Disable()
04235             self.ticks.Disable()
04236         else:
04237             self.panelRaster.heightOrColumnsLabel.SetLabel(_("Height:"))
04238             if self.rLegendDict['height']:
04239                 h = self.unitConv.convert(value = float(self.rLegendDict['height']), fromUnit = 'inch', toUnit = self.rLegendDict['unit'])
04240             else:
04241                 h = ''
04242             self.panelRaster.heightOrColumnsCtrl = wx.TextCtrl(self.panelRaster, id = wx.ID_ANY,
04243                                                     value = str(h), validator = TCValidator("DIGIT_ONLY"))
04244             self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize)
04245             self.nodata.Disable()
04246             self.range.Enable()
04247             if self.range.GetValue():
04248                 self.minText.Enable()
04249                 self.maxText.Enable()
04250                 self.min.Enable()
04251                 self.max.Enable()
04252             self.ticks.Enable()
04253         
04254         self.rSizeGBSizer.Add(self.panelRaster.heightOrColumnsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04255         self.panelRaster.Layout()
04256         self.panelRaster.Fit()   
04257         
04258     def OnRange(self, event):
04259         if not self.range.GetValue():
04260             self.min.Disable()        
04261             self.max.Disable()
04262             self.minText.Disable()
04263             self.maxText.Disable()
04264         else:
04265             self.min.Enable()        
04266             self.max.Enable() 
04267             self.minText.Enable()
04268             self.maxText.Enable()           
04269      
04270     def OnUp(self, event):
04271         """!Moves selected map up, changes order in vector legend"""
04272         if self.vectorListCtrl.GetFirstSelected() != -1:
04273             pos = self.vectorListCtrl.GetFirstSelected()
04274             if pos:
04275                 idx1 = self.vectorListCtrl.GetItemData(pos) - 1
04276                 idx2 = self.vectorListCtrl.GetItemData(pos - 1) + 1
04277                 self.vectorListCtrl.SetItemData(pos, idx1) 
04278                 self.vectorListCtrl.SetItemData(pos - 1, idx2) 
04279                 self.vectorListCtrl.SortItems(cmp)
04280                 if pos > 0:
04281                     selected = (pos - 1) 
04282                 else:
04283                     selected = 0
04284 
04285                 self.vectorListCtrl.Select(selected)
04286        
04287     def OnDown(self, event):
04288         """!Moves selected map down, changes order in vector legend"""
04289         if self.vectorListCtrl.GetFirstSelected() != -1:
04290             pos = self.vectorListCtrl.GetFirstSelected()
04291             if pos != self.vectorListCtrl.GetItemCount() - 1:
04292                 idx1 = self.vectorListCtrl.GetItemData(pos) + 1
04293                 idx2 = self.vectorListCtrl.GetItemData(pos + 1) - 1
04294                 self.vectorListCtrl.SetItemData(pos, idx1) 
04295                 self.vectorListCtrl.SetItemData(pos + 1, idx2) 
04296                 self.vectorListCtrl.SortItems(cmp)
04297                 if pos < self.vectorListCtrl.GetItemCount() -1:
04298                     selected = (pos + 1) 
04299                 else:
04300                     selected = self.vectorListCtrl.GetItemCount() -1
04301 
04302                 self.vectorListCtrl.Select(selected)
04303                 
04304     def OnEditLabel(self, event):
04305         """!Change legend label of vector map"""
04306         if self.vectorListCtrl.GetFirstSelected() != -1:
04307             idx = self.vectorListCtrl.GetFirstSelected()
04308             default = self.vectorListCtrl.GetItem(idx, 1).GetText()
04309             dlg = wx.TextEntryDialog(self, message = _("Edit legend label:"), caption = _("Edit label"),
04310                                     defaultValue = default, style = wx.OK|wx.CANCEL|wx.CENTRE)
04311             if dlg.ShowModal() == wx.ID_OK:
04312                 new = dlg.GetValue()
04313                 self.vectorListCtrl.SetStringItem(idx, 1, new)
04314             dlg.Destroy()
04315         
04316     def OnSpan(self, event):
04317         self.panelVector.spanTextCtrl.Enable(self.panelVector.spanRadio.GetValue())
04318     def OnFont(self, event):
04319         """!Changes default width according to fontsize, width [inch] = fontsize[pt]/24"""   
04320 ##        fontsize = self.panelVector.font['fontCtrl'].GetSelectedFont().GetPointSize() 
04321         fontsize = self.panelVector.font['fontSizeCtrl'].GetValue()
04322         unit = self.unitConv.findUnit(self.panelVector.units['unitsCtrl'].GetStringSelection())
04323         w = fontsize/24.
04324         width = self.unitConv.convert(value = w, fromUnit = 'inch', toUnit = unit)
04325         self.panelVector.widthCtrl.SetValue("%3.2f" % width)
04326         
04327     def OnBorder(self, event):
04328         """!Enables/disables colorPickerCtrl for border"""    
04329         self.borderColorCtrl.Enable(self.borderCheck.GetValue())
04330     
04331     def updateRasterLegend(self):
04332         """!Save information from raster legend dialog to dictionary"""
04333 
04334         #is raster legend
04335         if not self.isRLegend.GetValue():
04336             self.rLegendDict['rLegend'] = False
04337         else:
04338             self.rLegendDict['rLegend'] = True
04339         #units
04340         currUnit = self.unitConv.findUnit(self.panelRaster.units['unitsCtrl'].GetStringSelection())
04341         self.rLegendDict['unit'] = currUnit
04342         # raster
04343         if self.rasterDefault.GetValue():
04344             self.rLegendDict['rasterDefault'] = True
04345             self.rLegendDict['raster'] = self.currRaster
04346         else:
04347             self.rLegendDict['rasterDefault'] = False
04348             self.rLegendDict['raster'] = self.rasterSelect.GetValue()
04349         if self.rLegendDict['rLegend'] and not self.rLegendDict['raster']:
04350             wx.MessageBox(message = _("No raster map selected!"),
04351                                     caption = _('No raster'), style = wx.OK|wx.ICON_ERROR)
04352             return False
04353             
04354         if self.rLegendDict['raster']:
04355             # type and range of map
04356             rasterType = getRasterType(self.rLegendDict['raster'])
04357             if rasterType is None:
04358                 return False
04359             self.rLegendDict['type'] = rasterType
04360             
04361             
04362             #discrete
04363             if self.discrete.GetValue():
04364                 self.rLegendDict['discrete'] = 'y'
04365             else:
04366                 self.rLegendDict['discrete'] = 'n'   
04367                     
04368             # font 
04369             self.rLegendDict['font'] = self.panelRaster.font['fontCtrl'].GetStringSelection()
04370             self.rLegendDict['fontsize'] = self.panelRaster.font['fontSizeCtrl'].GetValue()
04371             color = self.panelRaster.font['colorCtrl'].GetColour()
04372             self.rLegendDict['color'] = convertRGB(color)
04373 
04374             # position
04375             x = self.unitConv.convert(value = float(self.panelRaster.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
04376             y = self.unitConv.convert(value = float(self.panelRaster.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
04377             self.rLegendDict['where'] = (x, y)
04378             # estimated size
04379             width = self.panelRaster.widthCtrl.GetValue()
04380             try:
04381                 width = float(width)
04382                 width = self.unitConv.convert(value = width, fromUnit = currUnit, toUnit = 'inch')
04383             except ValueError:
04384                 width = None
04385             self.rLegendDict['width'] = width
04386             if self.rLegendDict['discrete'] == 'n':
04387                 height = self.panelRaster.heightOrColumnsCtrl.GetValue()    
04388                 try:
04389                     height = float(height)
04390                     height = self.unitConv.convert(value = height, fromUnit = currUnit, toUnit = 'inch')
04391                 except ValueError:
04392                     height = None
04393                 self.rLegendDict['height'] = height
04394             else:
04395                 cols = self.panelRaster.heightOrColumnsCtrl.GetValue()
04396                 self.rLegendDict['cols'] = cols
04397             drawHeight = self.rasterLegend.EstimateHeight(raster = self.rLegendDict['raster'], discrete = self.rLegendDict['discrete'],
04398                                             fontsize = self.rLegendDict['fontsize'], cols = self.rLegendDict['cols'],
04399                                             height = self.rLegendDict['height'])
04400             drawWidth = self.rasterLegend.EstimateWidth(raster = self.rLegendDict['raster'], discrete = self.rLegendDict['discrete'],
04401                                             fontsize = self.rLegendDict['fontsize'], cols = self.rLegendDict['cols'],
04402                                             width = self.rLegendDict['width'], paperInstr = self.instruction[self.pageId])
04403             self.rLegendDict['rect'] = wx.Rect2D(x = x, y = y, w = drawWidth, h = drawHeight)
04404                         
04405             # no data
04406             if self.rLegendDict['discrete'] == 'y':
04407                 if self.nodata.GetValue():
04408                     self.rLegendDict['nodata'] = 'y'
04409                 else:
04410                     self.rLegendDict['nodata'] = 'n'
04411             # tickbar
04412             elif self.rLegendDict['discrete'] == 'n':
04413                 if self.ticks.GetValue():
04414                     self.rLegendDict['tickbar'] = 'y'
04415                 else:
04416                     self.rLegendDict['tickbar'] = 'n'
04417             # range
04418                 if self.range.GetValue():
04419                     self.rLegendDict['range'] = True
04420                     self.rLegendDict['min'] = self.min.GetValue()
04421                     self.rLegendDict['max'] = self.max.GetValue()
04422                 else:
04423                     self.rLegendDict['range'] = False
04424          
04425         if not self.id[0] in self.instruction:
04426             rasterLegend = RasterLegend(self.id[0])
04427             self.instruction.AddInstruction(rasterLegend)
04428         self.instruction[self.id[0]].SetInstruction(self.rLegendDict)
04429 
04430         if self.id[0] not in self.parent.objectId:
04431             self.parent.objectId.append(self.id[0])
04432         return True
04433     
04434     def updateVectorLegend(self):
04435         """!Save information from vector legend dialog to dictionary"""
04436 
04437         vector = self.instruction.FindInstructionByType('vector')
04438         if vector:
04439             self.vectorId = vector.id 
04440         else:
04441             self.vectorId = None
04442 
04443         #is vector legend
04444         if not self.isVLegend.GetValue():
04445             self.vLegendDict['vLegend'] = False
04446         else:
04447             self.vLegendDict['vLegend'] = True   
04448         if self.vLegendDict['vLegend'] == True and self.vectorId is not None:
04449             # labels
04450             #reindex order
04451             idx = 1
04452             for item in range(self.vectorListCtrl.GetItemCount()):
04453                 if self.vectorListCtrl.IsChecked(item):
04454                     self.vectorListCtrl.SetItemData(item, idx)
04455                     idx += 1
04456                 else:
04457                     self.vectorListCtrl.SetItemData(item, 0)
04458             if idx == 1: 
04459                 self.vLegendDict['vLegend'] = False     
04460             else:
04461                 vList = self.instruction[self.vectorId]['list']
04462                 for i, vector in enumerate(vList):
04463                     item = self.vectorListCtrl.FindItem(start = -1, str = vector[0].split('@')[0])
04464                     vList[i][3] = self.vectorListCtrl.GetItemData(item)
04465                     vList[i][4] = self.vectorListCtrl.GetItem(item, 1).GetText()
04466                 vmaps = self.instruction.FindInstructionByType('vProperties', list = True)
04467                 for vmap, vector in zip(vmaps, vList):
04468                     self.instruction[vmap.id]['lpos'] = vector[3]
04469                     self.instruction[vmap.id]['label'] = vector[4]
04470                 #units
04471                 currUnit = self.unitConv.findUnit(self.panelVector.units['unitsCtrl'].GetStringSelection())
04472                 self.vLegendDict['unit'] = currUnit
04473                 # position
04474                 x = self.unitConv.convert(value = float(self.panelVector.position['xCtrl'].GetValue()),
04475                                                                 fromUnit = currUnit, toUnit = 'inch')
04476                 y = self.unitConv.convert(value = float(self.panelVector.position['yCtrl'].GetValue()),
04477                                                                 fromUnit = currUnit, toUnit = 'inch')
04478                 self.vLegendDict['where'] = (x, y)
04479                 
04480                 # font 
04481                 self.vLegendDict['font'] = self.panelVector.font['fontCtrl'].GetStringSelection()
04482                 self.vLegendDict['fontsize'] = self.panelVector.font['fontSizeCtrl'].GetValue()
04483                 dc = wx.ClientDC(self)
04484                 font = dc.GetFont()
04485                 dc.SetFont(wx.Font(pointSize = self.vLegendDict['fontsize'], family = font.GetFamily(),
04486                                    style = font.GetStyle(), weight = wx.FONTWEIGHT_NORMAL))
04487                 #size
04488                 width = self.unitConv.convert(value = float(self.panelVector.widthCtrl.GetValue()),
04489                                               fromUnit = currUnit, toUnit = 'inch')
04490                 self.vLegendDict['width'] = width
04491                 self.vLegendDict['cols'] = self.panelVector.colsCtrl.GetValue()
04492                 if self.panelVector.spanRadio.GetValue() and self.panelVector.spanTextCtrl.GetValue():
04493                     self.vLegendDict['span'] = self.panelVector.spanTextCtrl.GetValue()
04494                 else:
04495                     self.vLegendDict['span'] = None
04496                     
04497                 # size estimation
04498                 vectors = self.instruction[self.vectorId]['list']
04499                 labels = [vector[4] for vector in vectors if vector[3] != 0]
04500                 extent = dc.GetTextExtent(max(labels, key = len))
04501                 wExtent = self.unitConv.convert(value = extent[0], fromUnit = 'pixel', toUnit = 'inch')
04502                 hExtent = self.unitConv.convert(value = extent[1], fromUnit = 'pixel', toUnit = 'inch')
04503                 w = (width + wExtent) * self.vLegendDict['cols']
04504                 h = len(labels) * hExtent / self.vLegendDict['cols']
04505                 h *= 1.1
04506                 self.vLegendDict['rect'] = wx.Rect2D(x, y, w, h)
04507                 
04508                 #border
04509                 if self.borderCheck.GetValue():
04510                     color = self.borderColorCtrl.GetColour()
04511                     self.vLegendDict['border'] = convertRGB(color)
04512                     
04513                 else:
04514                     self.vLegendDict['border'] = 'none'
04515                                  
04516         if not self.id[1] in self.instruction:
04517             vectorLegend = VectorLegend(self.id[1])
04518             self.instruction.AddInstruction(vectorLegend)
04519         self.instruction[self.id[1]].SetInstruction(self.vLegendDict)
04520         if self.id[1] not in self.parent.objectId:
04521             self.parent.objectId.append(self.id[1])
04522         return True
04523     
04524     def update(self):
04525         okR = self.updateRasterLegend()
04526         okV = self.updateVectorLegend()
04527         if okR and okV:
04528             return True
04529         return False
04530         
04531     def updateDialog(self):
04532         """!Update legend coordinates after moving"""
04533         
04534         # raster legend    
04535         if 'rect' in self.rLegendDict:
04536             x, y = self.rLegendDict['rect'][:2]
04537             currUnit = self.unitConv.findUnit(self.panelRaster.units['unitsCtrl'].GetStringSelection())
04538             x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
04539             y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
04540             self.panelRaster.position['xCtrl'].SetValue("%5.3f" % x)
04541             self.panelRaster.position['yCtrl'].SetValue("%5.3f" % y)
04542         #update name and type of raster
04543         raster = self.instruction.FindInstructionByType('raster')
04544         if raster:
04545             self.rasterId = raster.id 
04546         else:
04547             self.rasterId = None 
04548 
04549         if raster:
04550             currRaster = raster['raster'] 
04551         else:
04552             currRaster = None
04553             
04554         rasterType = getRasterType(map = currRaster)
04555         self.rasterCurrent.SetLabel(_("%(rast)s: type %(type)s") % \
04556                                         { 'rast' : currRaster, 'type' : str(rasterType) })
04557         
04558         # vector legend       
04559         if 'rect' in self.vLegendDict:
04560             x, y = self.vLegendDict['rect'][:2]
04561             currUnit = self.unitConv.findUnit(self.panelVector.units['unitsCtrl'].GetStringSelection())
04562             x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
04563             y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
04564             self.panelVector.position['xCtrl'].SetValue("%5.3f" % x)
04565             self.panelVector.position['yCtrl'].SetValue("%5.3f" % y)
04566         # update vector maps
04567         if self.instruction.FindInstructionByType('vector'):
04568             vectors = sorted(self.instruction.FindInstructionByType('vector')['list'], key = lambda x: x[3])
04569             self.vectorListCtrl.DeleteAllItems()
04570             for vector in vectors:
04571                 index = self.vectorListCtrl.InsertStringItem(sys.maxint, vector[0].split('@')[0])
04572                 self.vectorListCtrl.SetStringItem(index, 1, vector[4])
04573                 self.vectorListCtrl.SetItemData(index, index)
04574                 self.vectorListCtrl.CheckItem(index, True)
04575                 if vector[3] == 0:
04576                     self.vectorListCtrl.CheckItem(index, False)
04577             self.panelVector.colsCtrl.SetRange(1, min(10, len(self.instruction.FindInstructionByType('vector')['list'])))
04578             self.panelVector.colsCtrl.SetValue(1)
04579         else:
04580             self.vectorListCtrl.DeleteAllItems()
04581             self.panelVector.colsCtrl.SetRange(0,0)
04582             self.panelVector.colsCtrl.SetValue(0)
04583              
04584 class MapinfoDialog(PsmapDialog):
04585     def __init__(self, parent, id, settings):
04586         PsmapDialog.__init__(self, parent = parent, id = id, title = "Mapinfo settings", settings = settings)
04587         
04588         self.objectType = ('mapinfo',)
04589         if self.id is not None:
04590             self.mapinfo = self.instruction[self.id]
04591             self.mapinfoDict = self.mapinfo.GetInstruction()
04592         else:
04593             self.id = wx.NewId()
04594             self.mapinfo = Mapinfo(self.id)
04595             self.mapinfoDict = self.mapinfo.GetInstruction()
04596             page = self.instruction.FindInstructionByType('page').GetInstruction()
04597             self.mapinfoDict['where'] = page['Left'], page['Top']
04598 
04599         self.panel = self._mapinfoPanel()
04600         
04601         self._layout(self.panel)
04602         self.OnIsBackground(None)
04603         self.OnIsBorder(None)
04604 
04605     def _mapinfoPanel(self):
04606         panel = wx.Panel(parent = self, id = wx.ID_ANY, size = (-1, -1), style = wx.TAB_TRAVERSAL)
04607         #panel.SetupScrolling(scroll_x = False, scroll_y = True)
04608         border = wx.BoxSizer(wx.VERTICAL)
04609                 
04610         # position     
04611         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Position"))
04612         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
04613         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
04614         gridBagSizer.AddGrowableCol(1)
04615         
04616         self.AddPosition(parent = panel, dialogDict = self.mapinfoDict)
04617         self.AddUnits(parent = panel, dialogDict = self.mapinfoDict)
04618         gridBagSizer.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04619         gridBagSizer.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04620         gridBagSizer.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04621         gridBagSizer.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04622         gridBagSizer.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04623         gridBagSizer.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04624         gridBagSizer.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
04625         
04626         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
04627         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
04628         
04629         # font
04630         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
04631         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
04632         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
04633         gridBagSizer.AddGrowableCol(1)
04634         
04635         self.AddFont(parent = panel, dialogDict = self.mapinfoDict)#creates font color too, used below
04636         
04637         gridBagSizer.Add(panel.font['fontLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04638         gridBagSizer.Add(panel.font['fontCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04639         gridBagSizer.Add(panel.font['fontSizeLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04640         gridBagSizer.Add(panel.font['fontSizeCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04641         gridBagSizer.Add(panel.font['colorLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
04642         gridBagSizer.Add(panel.font['colorCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04643         
04644         sizer.Add(item = gridBagSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
04645         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
04646         
04647         # colors
04648         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_("Color settings"))
04649         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
04650         flexSizer = wx.FlexGridSizer (cols = 2, hgap = 5, vgap = 5)
04651         flexSizer.AddGrowableCol(1)
04652         
04653         self.colors = {}
04654         self.colors['borderCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use border color:"))
04655         self.colors['backgroundCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("use background color:"))
04656         self.colors['borderColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
04657         self.colors['backgroundColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
04658         
04659         if self.mapinfoDict['border'] == None:
04660             self.mapinfoDict['border'] = 'none'
04661         if self.mapinfoDict['border'] != 'none':
04662             self.colors['borderCtrl'].SetValue(True) 
04663             self.colors['borderColor'].SetColour(convertRGB(self.mapinfoDict['border']))
04664         else:
04665             self.colors['borderCtrl'].SetValue(False)
04666             self.colors['borderColor'].SetColour(convertRGB('black'))
04667             
04668         if self.mapinfoDict['background'] == None:
04669             self.mapinfoDict['background'] == 'none'
04670         if self.mapinfoDict['background'] != 'none':
04671             self.colors['backgroundCtrl'].SetValue(True) 
04672             self.colors['backgroundColor'].SetColour(convertRGB(self.mapinfoDict['background']))
04673         else:
04674             self.colors['backgroundCtrl'].SetValue(False)
04675             self.colors['backgroundColor'].SetColour(convertRGB('white'))
04676                     
04677         flexSizer.Add(self.colors['borderCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04678         flexSizer.Add(self.colors['borderColor'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04679         flexSizer.Add(self.colors['backgroundCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04680         flexSizer.Add(self.colors['backgroundColor'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04681         
04682         sizer.Add(item = flexSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
04683         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
04684         
04685         panel.SetSizer(border)
04686         
04687         self.Bind(wx.EVT_CHECKBOX, self.OnIsBorder, self.colors['borderCtrl'])
04688         self.Bind(wx.EVT_CHECKBOX, self.OnIsBackground, self.colors['backgroundCtrl'])
04689         
04690         return panel
04691     
04692     def OnIsBackground(self, event):
04693         if self.colors['backgroundCtrl'].GetValue():
04694             self.colors['backgroundColor'].Enable()
04695             self.update()
04696         else:
04697             self.colors['backgroundColor'].Disable()
04698                         
04699     def OnIsBorder(self, event):
04700         if self.colors['borderCtrl'].GetValue():
04701             self.colors['borderColor'].Enable()
04702             self.update()
04703         else:
04704             self.colors['borderColor'].Disable() 
04705                                            
04706     def update(self):
04707 
04708         #units
04709         currUnit = self.unitConv.findUnit(self.panel.units['unitsCtrl'].GetStringSelection())
04710         self.mapinfoDict['unit'] = currUnit
04711         
04712         # position
04713         if self.panel.position['xCtrl'].GetValue():
04714             x = self.panel.position['xCtrl'].GetValue() 
04715         else:
04716             x = self.mapinfoDict['where'][0]
04717 
04718         if self.panel.position['yCtrl'].GetValue():
04719             y = self.panel.position['yCtrl'].GetValue() 
04720         else:
04721             y = self.mapinfoDict['where'][1]
04722 
04723         x = self.unitConv.convert(value = float(self.panel.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
04724         y = self.unitConv.convert(value = float(self.panel.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
04725         self.mapinfoDict['where'] = (x, y)
04726         
04727         # font
04728         self.mapinfoDict['font'] =  self.panel.font['fontCtrl'].GetStringSelection()
04729         self.mapinfoDict['fontsize'] = self.panel.font['fontSizeCtrl'].GetValue()
04730 
04731         #colors
04732         color = self.panel.font['colorCtrl'].GetColour()
04733         self.mapinfoDict['color'] = convertRGB(color)
04734         
04735         if self.colors['backgroundCtrl'].GetValue():    
04736             background = self.colors['backgroundColor'].GetColour()
04737             self.mapinfoDict['background'] = convertRGB(background)
04738         else:
04739             self.mapinfoDict['background'] = 'none'
04740 
04741         if self.colors['borderCtrl'].GetValue():    
04742             border = self.colors['borderColor'].GetColour()
04743             self.mapinfoDict['border'] = convertRGB(border)
04744         else:
04745             self.mapinfoDict['border'] = 'none'
04746         
04747         # estimation of size
04748         self.mapinfoDict['rect'] = self.mapinfo.EstimateRect(self.mapinfoDict)
04749 
04750         if self.id not in self.instruction:
04751             mapinfo = Mapinfo(self.id)
04752             self.instruction.AddInstruction(mapinfo)
04753             
04754         self.instruction[self.id].SetInstruction(self.mapinfoDict)
04755 
04756         if self.id not in self.parent.objectId:
04757             self.parent.objectId.append(self.id)
04758             
04759         self.updateDialog()
04760 
04761         return True
04762     
04763     def updateDialog(self):
04764         """!Update mapinfo coordinates, after moving"""
04765         x, y = self.mapinfoDict['where']
04766         currUnit = self.unitConv.findUnit(self.panel.units['unitsCtrl'].GetStringSelection())
04767         x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
04768         y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
04769         self.panel.position['xCtrl'].SetValue("%5.3f" % x)
04770         self.panel.position['yCtrl'].SetValue("%5.3f" % y)
04771              
04772 class ScalebarDialog(PsmapDialog):
04773     """!Dialog for scale bar"""
04774     def __init__(self, parent, id, settings):
04775         PsmapDialog.__init__(self, parent = parent, id = id, title = "Scale bar settings", settings = settings)
04776         self.objectType = ('scalebar',)
04777         if self.id is not None:
04778             self.scalebar = self.instruction[id]
04779             self.scalebarDict = self.scalebar.GetInstruction()
04780         else:
04781             self.id = wx.NewId()
04782             self.scalebar = Scalebar(self.id)
04783             self.scalebarDict = self.scalebar.GetInstruction()
04784             page = self.instruction.FindInstructionByType('page').GetInstruction()
04785             self.scalebarDict['where'] = page['Left'], page['Top']
04786 
04787         self.panel = self._scalebarPanel()
04788         
04789         self._layout(self.panel)
04790         
04791         self.mapUnit = projInfo()['units'].lower()
04792         if projInfo()['proj'] == 'xy':
04793             self.mapUnit = 'meters'
04794         if self.mapUnit not in self.unitConv.getAllUnits():
04795             wx.MessageBox(message = _("Units of current projection are not supported,\n meters will be used!"),
04796                             caption = _('Unsupported units'),
04797                                     style = wx.OK|wx.ICON_ERROR)
04798             self.mapUnit = 'meters'
04799             
04800     def _scalebarPanel(self):
04801         panel = wx.Panel(parent = self, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
04802         border = wx.BoxSizer(wx.VERTICAL)
04803         #        
04804         # position
04805         #
04806         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Position"))
04807         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
04808         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
04809         gridBagSizer.AddGrowableCol(1)
04810         
04811         self.AddUnits(parent = panel, dialogDict = self.scalebarDict)
04812         self.AddPosition(parent = panel, dialogDict = self.scalebarDict)
04813         
04814         if self.scalebarDict['rect']: # set position, ref point is center and not left top corner
04815             
04816             x = self.unitConv.convert(value = self.scalebarDict['where'][0] - self.scalebarDict['rect'].Get()[2]/2,
04817                                                     fromUnit = 'inch', toUnit = self.scalebarDict['unit'])
04818             y = self.unitConv.convert(value = self.scalebarDict['where'][1] - self.scalebarDict['rect'].Get()[3]/2,
04819                                                     fromUnit = 'inch', toUnit = self.scalebarDict['unit'])
04820             panel.position['xCtrl'].SetValue("%5.3f" % x)
04821             panel.position['yCtrl'].SetValue("%5.3f" % y)
04822         
04823         gridBagSizer.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04824         gridBagSizer.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04825         gridBagSizer.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04826         gridBagSizer.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04827         gridBagSizer.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04828         gridBagSizer.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04829         gridBagSizer.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag =wx.ALIGN_BOTTOM, border = 0)
04830         
04831         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
04832         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
04833         #
04834         # size
04835         #
04836         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Size"))
04837         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
04838         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
04839         gridBagSizer.AddGrowableCol(1)
04840         
04841         lengthText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Length:"))
04842         heightText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Height:"))
04843         
04844         self.lengthTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, validator = TCValidator('DIGIT_ONLY'))
04845         self.lengthTextCtrl.SetToolTipString(_("Scalebar length is given in map units"))
04846         
04847         self.heightTextCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, validator = TCValidator('DIGIT_ONLY'))
04848         self.heightTextCtrl.SetToolTipString(_("Scalebar height is real height on paper"))
04849         
04850         choices = [_('default')] + self.unitConv.getMapUnitsNames()
04851         self.unitsLength = wx.Choice(panel, id = wx.ID_ANY, choices = choices)
04852         choices = self.unitConv.getPageUnitsNames()
04853         self.unitsHeight = wx.Choice(panel, id = wx.ID_ANY, choices = choices)
04854         
04855         # set values
04856         unitName = self.unitConv.findName(self.scalebarDict['unitsLength'])
04857         if unitName:
04858             self.unitsLength.SetStringSelection(unitName)
04859         else:
04860             if self.scalebarDict['unitsLength'] == 'auto':
04861                  self.unitsLength.SetSelection(0)
04862             elif self.scalebarDict['unitsLength'] == 'nautmiles':
04863                  self.unitsLength.SetStringSelection(self.unitConv.findName("nautical miles"))
04864         self.unitsHeight.SetStringSelection(self.unitConv.findName(self.scalebarDict['unitsHeight']))
04865         if self.scalebarDict['length']:
04866             self.lengthTextCtrl.SetValue(str(self.scalebarDict['length']))
04867         else: #estimate default
04868             reg = grass.region()
04869             w = int((reg['e'] - reg['w'])/3)
04870             w = round(w, -len(str(w)) + 2) #12345 -> 12000
04871             self.lengthTextCtrl.SetValue(str(w))
04872             
04873         h = self.unitConv.convert(value = self.scalebarDict['height'], fromUnit = 'inch',
04874                                                 toUnit =  self.scalebarDict['unitsHeight']) 
04875         self.heightTextCtrl.SetValue(str(h))
04876         
04877         gridBagSizer.Add(lengthText, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04878         gridBagSizer.Add(self.lengthTextCtrl, pos = (0, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04879         gridBagSizer.Add(self.unitsLength, pos = (0, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
04880         gridBagSizer.Add(heightText, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04881         gridBagSizer.Add(self.heightTextCtrl, pos = (1, 1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04882         gridBagSizer.Add(self.unitsHeight, pos = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
04883       
04884         sizer.Add(gridBagSizer, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
04885         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
04886         #
04887         #style
04888         #
04889         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Style"))
04890         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
04891         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
04892         
04893         
04894         sbTypeText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Type:"))
04895         self.sbCombo = wx.combo.BitmapComboBox(panel, style = wx.CB_READONLY)
04896         # only temporary, images must be moved away
04897         imagePath = os.path.join(globalvar.ETCIMGDIR, "scalebar-fancy.png"), os.path.join(globalvar.ETCIMGDIR, "scalebar-simple.png") 
04898         for item, path in zip(['fancy', 'simple'], imagePath):
04899             if not os.path.exists(path):
04900                 bitmap = wx.EmptyBitmap(0,0)
04901             else:
04902                 bitmap = wx.Bitmap(path)
04903             self.sbCombo.Append(item = '', bitmap = bitmap, clientData = item[0])
04904         #self.sbCombo.Append(item = 'simple', bitmap = wx.Bitmap("./images/scalebar-simple.png"), clientData = 's')
04905         if self.scalebarDict['scalebar'] == 'f':
04906             self.sbCombo.SetSelection(0)
04907         elif self.scalebarDict['scalebar'] == 's':
04908             self.sbCombo.SetSelection(1)
04909             
04910         sbSegmentsText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Number of segments:"))
04911         self.sbSegmentsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 4)
04912         self.sbSegmentsCtrl.SetValue(self.scalebarDict['segment'])
04913         
04914         sbLabelsText1 = wx.StaticText(panel, id = wx.ID_ANY, label = _("Label every "))
04915         sbLabelsText2 = wx.StaticText(panel, id = wx.ID_ANY, label = _("segments"))
04916         self.sbLabelsCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 1, max = 30, initial = 1)
04917         self.sbLabelsCtrl.SetValue(self.scalebarDict['numbers'])
04918         
04919         #font
04920         fontsizeText = wx.StaticText(panel, id = wx.ID_ANY, label = _("Font size:"))
04921         self.fontsizeCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, min = 4, max = 30, initial = 10)
04922         self.fontsizeCtrl.SetValue(self.scalebarDict['fontsize'])
04923         
04924         self.backgroundCheck = wx.CheckBox(panel, id = wx.ID_ANY, label = _("transparent text background"))
04925         if self.scalebarDict['background'] == 'y':
04926             self.backgroundCheck.SetValue(False)
04927         else:
04928             self.backgroundCheck.SetValue(True)
04929 
04930         gridBagSizer.Add(sbTypeText, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04931         gridBagSizer.Add(self.sbCombo, pos = (0,1), span = (1, 2), flag = wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border = 0)
04932         gridBagSizer.Add(sbSegmentsText, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04933         gridBagSizer.Add(self.sbSegmentsCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04934         gridBagSizer.Add(sbLabelsText1, pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04935         gridBagSizer.Add(self.sbLabelsCtrl, pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04936         gridBagSizer.Add(sbLabelsText2, pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04937         gridBagSizer.Add(fontsizeText, pos = (3,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04938         gridBagSizer.Add(self.fontsizeCtrl, pos = (3,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04939         gridBagSizer.Add(self.backgroundCheck, pos = (4, 0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
04940         
04941         sizer.Add(gridBagSizer, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL, border = 5)
04942         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
04943         
04944         panel.SetSizer(border)
04945         
04946         return panel
04947                            
04948     def update(self):
04949         """!Save information from dialog"""
04950 
04951         #units
04952         currUnit = self.unitConv.findUnit(self.panel.units['unitsCtrl'].GetStringSelection())
04953         self.scalebarDict['unit'] = currUnit
04954         # position
04955         if self.panel.position['xCtrl'].GetValue():
04956             x = self.panel.position['xCtrl'].GetValue() 
04957         else:
04958             x = self.scalebarDict['where'][0]
04959 
04960         if self.panel.position['yCtrl'].GetValue():
04961             y = self.panel.position['yCtrl'].GetValue() 
04962         else:
04963             y = self.scalebarDict['where'][1]
04964 
04965         x = self.unitConv.convert(value = float(self.panel.position['xCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
04966         y = self.unitConv.convert(value = float(self.panel.position['yCtrl'].GetValue()), fromUnit = currUnit, toUnit = 'inch')
04967         
04968         #style
04969         self.scalebarDict['scalebar'] = self.sbCombo.GetClientData(self.sbCombo.GetSelection())
04970         self.scalebarDict['segment'] = self.sbSegmentsCtrl.GetValue()
04971         self.scalebarDict['numbers'] = self.sbLabelsCtrl.GetValue()
04972         self.scalebarDict['fontsize'] = self.fontsizeCtrl.GetValue()
04973         if self.backgroundCheck.GetValue():
04974             self.scalebarDict['background'] = 'n' 
04975         else:
04976             self.scalebarDict['background'] = 'y'
04977 
04978         
04979         # size
04980         
04981         # height
04982         self.scalebarDict['unitsHeight'] = self.unitConv.findUnit(self.unitsHeight.GetStringSelection())
04983         try:
04984             height = float(self.heightTextCtrl.GetValue())  
04985             height = self.unitConv.convert(value = height, fromUnit = self.scalebarDict['unitsHeight'], toUnit = 'inch') 
04986         except (ValueError, SyntaxError):
04987             height = 0.1 #default in inch
04988         self.scalebarDict['height'] = height    
04989         
04990         #length
04991         if self.unitsLength.GetSelection() == 0:
04992             selected = 'auto'
04993         else:
04994             selected = self.unitConv.findUnit(self.unitsLength.GetStringSelection())
04995             if selected == 'nautical miles':
04996                 selected = 'nautmiles'
04997         self.scalebarDict['unitsLength'] = selected
04998         try:
04999             length = float(self.lengthTextCtrl.GetValue())
05000         except (ValueError, SyntaxError):
05001             wx.MessageBox(message = _("Length of scale bar is not defined"),
05002                                     caption = _('Invalid input'), style = wx.OK|wx.ICON_ERROR)
05003             return False
05004         self.scalebarDict['length'] = length
05005             
05006         # estimation of size
05007         map = self.instruction.FindInstructionByType('map')
05008         if not map:
05009             map = self.instruction.FindInstructionByType('initMap')
05010         mapId = map.id
05011          
05012         rectSize = self.scalebar.EstimateSize(scalebarDict = self.scalebarDict,
05013                                                                 scale = self.instruction[mapId]['scale'])
05014         self.scalebarDict['rect'] = wx.Rect2D(x = x, y = y, w = rectSize[0], h = rectSize[1])
05015         self.scalebarDict['where'] = self.scalebarDict['rect'].GetCentre() 
05016 
05017         if self.id not in self.instruction:
05018             scalebar = Scalebar(self.id)
05019             self.instruction.AddInstruction(scalebar)
05020         self.instruction[self.id].SetInstruction(self.scalebarDict)
05021         if self.id not in self.parent.objectId:
05022             self.parent.objectId.append(self.id)
05023             
05024         return True
05025     
05026     def updateDialog(self):
05027         """!Update scalebar coordinates, after moving"""
05028         x, y = self.scalebarDict['rect'][:2]
05029         currUnit = self.unitConv.findUnit(self.panel.units['unitsCtrl'].GetStringSelection())
05030         x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
05031         y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
05032         self.panel.position['xCtrl'].SetValue("%5.3f" % x)
05033         self.panel.position['yCtrl'].SetValue("%5.3f" % y)
05034         
05035  
05036         
05037 class TextDialog(PsmapDialog):
05038     def __init__(self, parent, id, settings):
05039         PsmapDialog.__init__(self, parent = parent, id = id, title = "Text settings", settings = settings)
05040         self.objectType = ('text',)
05041         if self.id is not None:
05042             self.textDict = self.instruction[id].GetInstruction()
05043         else:
05044             self.id = wx.NewId()  
05045             text = Text(self.id)
05046             self.textDict = text.GetInstruction()
05047             page = self.instruction.FindInstructionByType('page').GetInstruction()
05048             self.textDict['where'] = page['Left'], page['Top'] 
05049                 
05050         map = self.instruction.FindInstructionByType('map')
05051         if not map:
05052             map = self.instruction.FindInstructionByType('initMap')
05053         self.mapId = map.id
05054 
05055         self.textDict['east'], self.textDict['north'] = PaperMapCoordinates(map = map, x = self.textDict['where'][0], y = self.textDict['where'][1], paperToMap = True)
05056         
05057         notebook = wx.Notebook(parent = self, id = wx.ID_ANY, style = wx.BK_DEFAULT)     
05058         self.textPanel = self._textPanel(notebook)
05059         self.positionPanel = self._positionPanel(notebook)
05060         self.OnBackground(None)
05061         self.OnHighlight(None)
05062         self.OnBorder(None)
05063         self.OnPositionType(None)
05064         self.OnRotation(None)
05065      
05066         self._layout(notebook)
05067 
05068     def _textPanel(self, notebook):
05069         panel = wx.Panel(parent = notebook, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
05070         notebook.AddPage(page = panel, text = _("Text"))
05071         
05072         border = wx.BoxSizer(wx.VERTICAL)
05073         
05074         # text entry    
05075         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Text"))
05076         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
05077         
05078         textLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Enter text:"))
05079         self.textCtrl = ExpandoTextCtrl(panel, id = wx.ID_ANY, value = self.textDict['text'])
05080         
05081         sizer.Add(textLabel, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
05082         sizer.Add(self.textCtrl, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
05083         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)        
05084         
05085         #font       
05086         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Font settings"))
05087         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
05088         flexGridSizer = wx.FlexGridSizer (rows = 3, cols = 2, hgap = 5, vgap = 5)
05089         flexGridSizer.AddGrowableCol(1)
05090         
05091         self.AddFont(parent = panel, dialogDict = self.textDict)
05092         
05093         flexGridSizer.Add(panel.font['fontLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05094         flexGridSizer.Add(panel.font['fontCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05095         flexGridSizer.Add(panel.font['fontSizeLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05096         flexGridSizer.Add(panel.font['fontSizeCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05097         flexGridSizer.Add(panel.font['colorLabel'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)        
05098         flexGridSizer.Add(panel.font['colorCtrl'], proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05099         
05100         sizer.Add(item = flexGridSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
05101         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
05102         
05103         #text effects        
05104         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Text effects"))
05105         sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
05106         gridBagSizer = wx.GridBagSizer (hgap = 5, vgap = 5)
05107         
05108         self.effect = {}
05109         self.effect['backgroundCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("text background"))
05110         self.effect['backgroundColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
05111         
05112         self.effect['highlightCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("highlight"))
05113         self.effect['highlightColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
05114         self.effect['highlightWidth'] = wx.SpinCtrl(panel, id = wx.ID_ANY, size = self.spinCtrlSize, min = 0, max = 5, initial = 1)
05115         self.effect['highlightWidthLabel'] = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
05116         
05117         self.effect['borderCtrl'] = wx.CheckBox(panel, id = wx.ID_ANY, label = _("text border"))
05118         self.effect['borderColor'] = wx.ColourPickerCtrl(panel, id = wx.ID_ANY)
05119         self.effect['borderWidth'] = wx.SpinCtrl(panel, id = wx.ID_ANY, size = self.spinCtrlSize, min = 1, max = 25, initial = 1)
05120         self.effect['borderWidthLabel'] = wx.StaticText(panel, id = wx.ID_ANY, label = _("Width (pts):"))
05121 
05122         #set values
05123         if self.textDict['background'] == None:
05124             self.textDict['background'] = 'none'
05125         if self.textDict['background'] != 'none':
05126             self.effect['backgroundCtrl'].SetValue(True) 
05127             self.effect['backgroundColor'].SetColour(convertRGB(self.textDict['background']))
05128         else:
05129             self.effect['backgroundCtrl'].SetValue(False)
05130             self.effect['backgroundColor'].SetColour(convertRGB('white'))
05131 
05132         if self.textDict['hcolor'] == None:
05133              self.textDict['hcolor'] = 'none'
05134         if self.textDict['hcolor'] != 'none':
05135             self.effect['highlightCtrl'].SetValue(True) 
05136             self.effect['highlightColor'].SetColour(convertRGB(self.textDict['hcolor']))
05137         else:
05138             self.effect['highlightCtrl'].SetValue(False)
05139             self.effect['highlightColor'].SetColour(convertRGB('grey'))
05140 
05141         self.effect['highlightWidth'].SetValue(float(self.textDict['hwidth']))
05142         
05143         if self.textDict['border'] == None:
05144             self.textDict['border'] = 'none'
05145         if self.textDict['border'] != 'none':
05146             self.effect['borderCtrl'].SetValue(True) 
05147             self.effect['borderColor'].SetColour(convertRGB(self.textDict['border'])) 
05148         else:
05149             self.effect['borderCtrl'].SetValue(False)
05150             self.effect['borderColor'].SetColour(convertRGB('black'))
05151 
05152         self.effect['borderWidth'].SetValue(float(self.textDict['width']))
05153         
05154         gridBagSizer.Add(self.effect['backgroundCtrl'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05155         gridBagSizer.Add(self.effect['backgroundColor'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05156         gridBagSizer.Add(self.effect['highlightCtrl'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05157         gridBagSizer.Add(self.effect['highlightColor'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05158         gridBagSizer.Add(self.effect['highlightWidthLabel'], pos = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05159         gridBagSizer.Add(self.effect['highlightWidth'], pos = (1,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05160         gridBagSizer.Add(self.effect['borderCtrl'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05161         gridBagSizer.Add(self.effect['borderColor'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05162         gridBagSizer.Add(self.effect['borderWidthLabel'], pos = (2,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05163         gridBagSizer.Add(self.effect['borderWidth'], pos = (2,3), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05164         
05165         sizer.Add(item = gridBagSizer, proportion = 1, flag = wx.ALL | wx.EXPAND, border = 1)
05166         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
05167         
05168         self.Bind(EVT_ETC_LAYOUT_NEEDED, self.OnRefit, self.textCtrl)
05169         self.Bind(wx.EVT_CHECKBOX, self.OnBackground, self.effect['backgroundCtrl'])
05170         self.Bind(wx.EVT_CHECKBOX, self.OnHighlight, self.effect['highlightCtrl'])
05171         self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.effect['borderCtrl'])
05172         
05173         panel.SetSizer(border)
05174         panel.Fit()
05175         
05176         return panel 
05177     
05178     def _positionPanel(self, notebook):
05179         panel = wx.Panel(parent = notebook, id = wx.ID_ANY, style = wx.TAB_TRAVERSAL)
05180         notebook.AddPage(page = panel, text = _("Position"))
05181 
05182         border = wx.BoxSizer(wx.VERTICAL) 
05183 
05184         #Position
05185         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Position"))
05186         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
05187         gridBagSizer = wx.GridBagSizer(hgap = 5, vgap = 5)
05188         gridBagSizer.AddGrowableCol(0)
05189         gridBagSizer.AddGrowableCol(1)
05190         
05191         self.positionLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("Position is given:"))
05192         self.paperPositionCtrl = wx.RadioButton(panel, id = wx.ID_ANY, label = _("relatively to paper"), style = wx.RB_GROUP)
05193         self.mapPositionCtrl = wx.RadioButton(panel, id = wx.ID_ANY, label = _("by map coordinates"))
05194         self.paperPositionCtrl.SetValue(self.textDict['XY'])
05195         self.mapPositionCtrl.SetValue(not self.textDict['XY'])
05196         
05197         gridBagSizer.Add(self.positionLabel, pos = (0,0), span = (1,3), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
05198         gridBagSizer.Add(self.paperPositionCtrl, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
05199         gridBagSizer.Add(self.mapPositionCtrl, pos = (1,1),flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT, border = 0)
05200         
05201         # first box - paper coordinates
05202         box1   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = "")
05203         sizerP = wx.StaticBoxSizer(box1, wx.VERTICAL)
05204         self.gridBagSizerP = wx.GridBagSizer (hgap = 5, vgap = 5)
05205         self.gridBagSizerP.AddGrowableCol(1)
05206         self.gridBagSizerP.AddGrowableRow(3)
05207         
05208         self.AddPosition(parent = panel, dialogDict = self.textDict)
05209         panel.position['comment'].SetLabel(_("Position from the top left\nedge of the paper"))
05210         self.AddUnits(parent = panel, dialogDict = self.textDict)
05211         self.gridBagSizerP.Add(panel.units['unitsLabel'], pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05212         self.gridBagSizerP.Add(panel.units['unitsCtrl'], pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05213         self.gridBagSizerP.Add(panel.position['xLabel'], pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05214         self.gridBagSizerP.Add(panel.position['xCtrl'], pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05215         self.gridBagSizerP.Add(panel.position['yLabel'], pos = (2,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05216         self.gridBagSizerP.Add(panel.position['yCtrl'], pos = (2,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05217         self.gridBagSizerP.Add(panel.position['comment'], pos = (3,0), span = (1,2), flag = wx.ALIGN_BOTTOM, border = 0)
05218         
05219         sizerP.Add(self.gridBagSizerP, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
05220         gridBagSizer.Add(sizerP, pos = (2,0),span = (1,1), flag = wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND, border = 0)
05221         
05222         # second box - map coordinates
05223         box2   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = "")
05224         sizerM = wx.StaticBoxSizer(box2, wx.VERTICAL)
05225         self.gridBagSizerM = wx.GridBagSizer (hgap = 5, vgap = 5)
05226         self.gridBagSizerM.AddGrowableCol(0)
05227         self.gridBagSizerM.AddGrowableCol(1)
05228         
05229         self.eastingLabel  = wx.StaticText(panel, id = wx.ID_ANY, label = "E:")
05230         self.northingLabel  = wx.StaticText(panel, id = wx.ID_ANY, label = "N:")
05231         self.eastingCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
05232         self.northingCtrl = wx.TextCtrl(panel, id = wx.ID_ANY, value = "")
05233         east, north = PaperMapCoordinates(map = self.instruction[self.mapId], x = self.textDict['where'][0], y = self.textDict['where'][1], paperToMap = True)
05234         self.eastingCtrl.SetValue(str(east))
05235         self.northingCtrl.SetValue(str(north))
05236         
05237         self.gridBagSizerM.Add(self.eastingLabel, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05238         self.gridBagSizerM.Add(self.northingLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05239         self.gridBagSizerM.Add(self.eastingCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05240         self.gridBagSizerM.Add(self.northingCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05241         
05242         sizerM.Add(self.gridBagSizerM, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
05243         gridBagSizer.Add(sizerM, pos = (2,1), flag = wx.ALIGN_LEFT|wx.EXPAND, border = 0)
05244         
05245         #offset
05246         box3   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_("Offset"))
05247         sizerO = wx.StaticBoxSizer(box3, wx.VERTICAL)
05248         gridBagSizerO = wx.GridBagSizer (hgap = 5, vgap = 5)
05249         self.xoffLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("horizontal (pts):"))
05250         self.yoffLabel = wx.StaticText(panel, id = wx.ID_ANY, label = _("vertical (pts):"))
05251         self.xoffCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, size = (50, -1), min = -50, max = 50, initial = 0)
05252         self.yoffCtrl = wx.SpinCtrl(panel, id = wx.ID_ANY, size = (50, -1), min = -50, max = 50, initial = 0) 
05253         self.xoffCtrl.SetValue(self.textDict['xoffset'])       
05254         self.yoffCtrl.SetValue(self.textDict['yoffset'])
05255         gridBagSizerO.Add(self.xoffLabel, pos = (0,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05256         gridBagSizerO.Add(self.yoffLabel, pos = (1,0), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05257         gridBagSizerO.Add(self.xoffCtrl, pos = (0,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05258         gridBagSizerO.Add(self.yoffCtrl, pos = (1,1), flag = wx.ALIGN_CENTER_VERTICAL, border = 0)
05259         
05260         sizerO.Add(gridBagSizerO, proportion = 1, flag = wx.EXPAND|wx.ALL, border = 5)
05261         gridBagSizer.Add(sizerO, pos = (3,0), flag = wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND, border = 0)
05262         # reference point
05263         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " %_(" Reference point"))
05264         sizerR = wx.StaticBoxSizer(box, wx.VERTICAL)
05265         flexSizer = wx.FlexGridSizer(rows = 3, cols = 3, hgap = 5, vgap = 5)
05266         flexSizer.AddGrowableCol(0)
05267         flexSizer.AddGrowableCol(1)
05268         flexSizer.AddGrowableCol(2)
05269         ref = []
05270         for row in ["upper", "center", "lower"]:
05271             for col in ["left", "center", "right"]:
05272                 ref.append(row + " " + col)
05273         self.radio = [wx.RadioButton(panel, id = wx.ID_ANY, label = '', style = wx.RB_GROUP, name = ref[0])]
05274         self.radio[0].SetValue(False)
05275         flexSizer.Add(self.radio[0], proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
05276         for i in range(1,9):
05277             self.radio.append(wx.RadioButton(panel, id = wx.ID_ANY, label = '', name = ref[i]))
05278             self.radio[-1].SetValue(False)
05279             flexSizer.Add(self.radio[-1], proportion = 0, flag = wx.ALIGN_CENTER, border = 0)
05280         self.FindWindowByName(self.textDict['ref']).SetValue(True)
05281                 
05282         sizerR.Add(flexSizer, proportion = 1, flag = wx.EXPAND, border = 0)
05283         gridBagSizer.Add(sizerR, pos = (3,1), flag = wx.ALIGN_LEFT|wx.EXPAND, border = 0)
05284         
05285         sizer.Add(gridBagSizer, proportion = 1, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 5)
05286         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
05287                 
05288         #rotation
05289         box   = wx.StaticBox (parent = panel, id = wx.ID_ANY, label = " %s " % _("Text rotation"))
05290         sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
05291 
05292         self.rotCtrl = wx.CheckBox(panel, id = wx.ID_ANY, label = _("rotate text (counterclockwise)"))
05293         self.rotValue = wx.SpinCtrl(panel, wx.ID_ANY, size = (50, -1), min = 0, max = 360, initial = 0)
05294         if self.textDict['rotate']:
05295             self.rotValue.SetValue(int(self.textDict['rotate']))
05296             self.rotCtrl.SetValue(True)
05297         else:
05298             self.rotValue.SetValue(0)
05299             self.rotCtrl.SetValue(False)
05300         sizer.Add(self.rotCtrl, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.ALL, border = 5)
05301         sizer.Add(self.rotValue, proportion = 0, flag = wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.ALL, border = 5)
05302         
05303         border.Add(item = sizer, proportion = 0, flag = wx.ALL | wx.EXPAND, border = 5)
05304         
05305         panel.SetSizer(border)
05306         panel.Fit()
05307           
05308         self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, self.paperPositionCtrl) 
05309         self.Bind(wx.EVT_RADIOBUTTON, self.OnPositionType, self.mapPositionCtrl)
05310         self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotCtrl)
05311         
05312         return panel
05313      
05314     def OnRefit(self, event):
05315         self.Fit()
05316         
05317     def OnRotation(self, event):
05318         if self.rotCtrl.GetValue():
05319             self.rotValue.Enable()
05320         else: 
05321             self.rotValue.Disable()
05322             
05323     def OnPositionType(self, event):
05324         if self.paperPositionCtrl.GetValue():
05325             for widget in self.gridBagSizerP.GetChildren():
05326                 widget.GetWindow().Enable()
05327             for widget in self.gridBagSizerM.GetChildren():
05328                 widget.GetWindow().Disable()
05329         else:
05330             for widget in self.gridBagSizerM.GetChildren():
05331                 widget.GetWindow().Enable()
05332             for widget in self.gridBagSizerP.GetChildren():
05333                 widget.GetWindow().Disable()
05334                 
05335     def OnBackground(self, event):
05336         if self.effect['backgroundCtrl'].GetValue():
05337             self.effect['backgroundColor'].Enable()
05338             self.update()
05339         else:
05340             self.effect['backgroundColor'].Disable()
05341     
05342     def OnHighlight(self, event):
05343         if self.effect['highlightCtrl'].GetValue():
05344             self.effect['highlightColor'].Enable()
05345             self.effect['highlightWidth'].Enable()
05346             self.effect['highlightWidthLabel'].Enable()
05347             self.update()
05348         else:
05349             self.effect['highlightColor'].Disable()
05350             self.effect['highlightWidth'].Disable()
05351             self.effect['highlightWidthLabel'].Disable()
05352             
05353     def OnBorder(self, event):
05354         if self.effect['borderCtrl'].GetValue():
05355             self.effect['borderColor'].Enable()
05356             self.effect['borderWidth'].Enable()
05357             self.effect['borderWidthLabel'].Enable()
05358             self.update()
05359         else:
05360             self.effect['borderColor'].Disable()
05361             self.effect['borderWidth'].Disable()
05362             self.effect['borderWidthLabel'].Disable()
05363             
05364     def update(self): 
05365         #text
05366         self.textDict['text'] = self.textCtrl.GetValue()
05367         if not self.textDict['text']:
05368             wx.MessageBox(_("No text entered!"), _("Error"))
05369             return False
05370             
05371         #font
05372         self.textDict['font'] = self.textPanel.font['fontCtrl'].GetStringSelection()
05373         self.textDict['fontsize'] = self.textPanel.font['fontSizeCtrl'].GetValue()
05374         color = self.textPanel.font['colorCtrl'].GetColour()
05375         self.textDict['color'] = convertRGB(color)
05376 
05377         #effects
05378         if self.effect['backgroundCtrl'].GetValue():
05379             background = self.effect['backgroundColor'].GetColour()
05380             self.textDict['background'] = convertRGB(background)
05381         else:
05382             self.textDict['background'] = 'none'        
05383                 
05384         if self.effect['borderCtrl'].GetValue():
05385             border = self.effect['borderColor'].GetColour()
05386             self.textDict['border'] = convertRGB(border)
05387         else:
05388             self.textDict['border'] = 'none' 
05389                      
05390         self.textDict['width'] = self.effect['borderWidth'].GetValue()
05391         
05392         if self.effect['highlightCtrl'].GetValue():
05393             highlight = self.effect['highlightColor'].GetColour()
05394             self.textDict['hcolor'] = convertRGB(highlight)
05395         else:
05396             self.textDict['hcolor'] = 'none'
05397 
05398         self.textDict['hwidth'] = self.effect['highlightWidth'].GetValue()
05399         
05400         #offset
05401         self.textDict['xoffset'] = self.xoffCtrl.GetValue()
05402         self.textDict['yoffset'] = self.yoffCtrl.GetValue()
05403 
05404         #position
05405         if self.paperPositionCtrl.GetValue():
05406             self.textDict['XY'] = True
05407             currUnit = self.unitConv.findUnit(self.positionPanel.units['unitsCtrl'].GetStringSelection())
05408             self.textDict['unit'] = currUnit
05409             if self.positionPanel.position['xCtrl'].GetValue():
05410                 x = self.positionPanel.position['xCtrl'].GetValue() 
05411             else:
05412                 x = self.textDict['where'][0]
05413 
05414             if self.positionPanel.position['yCtrl'].GetValue():
05415                 y = self.positionPanel.position['yCtrl'].GetValue() 
05416             else:
05417                 y = self.textDict['where'][1]
05418 
05419             x = self.unitConv.convert(value = float(x), fromUnit = currUnit, toUnit = 'inch')
05420             y = self.unitConv.convert(value = float(y), fromUnit = currUnit, toUnit = 'inch')
05421             self.textDict['where'] = x, y
05422             self.textDict['east'], self.textDict['north'] = PaperMapCoordinates(self.instruction[self.mapId], x, y, paperToMap = True)
05423         else:
05424             self.textDict['XY'] = False
05425             if self.eastingCtrl.GetValue():
05426                 self.textDict['east'] = self.eastingCtrl.GetValue() 
05427             else:
05428                 self.textDict['east'] = self.textDict['east']
05429 
05430             if self.northingCtrl.GetValue():
05431                 self.textDict['north'] = self.northingCtrl.GetValue() 
05432             else:
05433                 self.textDict['north'] = self.textDict['north']
05434 
05435             self.textDict['where'] = PaperMapCoordinates(map = self.instruction[self.mapId], x = float(self.textDict['east']),
05436                                                             y = float(self.textDict['north']), paperToMap = False)
05437         #rotation
05438         if self.rotCtrl.GetValue():
05439             self.textDict['rotate'] = self.rotValue.GetValue()
05440         else:
05441             self.textDict['rotate'] = None
05442         #reference point
05443         for radio in self.radio:
05444             if radio.GetValue() == True:
05445                 self.textDict['ref'] = radio.GetName()
05446                 
05447         if self.id not in self.instruction:
05448             text = Text(self.id)
05449             self.instruction.AddInstruction(text)
05450         self.instruction[self.id].SetInstruction(self.textDict)
05451         
05452         if self.id not in self.parent.objectId:
05453             self.parent.objectId.append(self.id)
05454 
05455 #        self.updateDialog()
05456 
05457         return True
05458     
05459     def updateDialog(self):
05460         """!Update text coordinates, after moving"""
05461         # XY coordinates
05462         x, y = self.textDict['where'][:2]
05463         currUnit = self.unitConv.findUnit(self.positionPanel.units['unitsCtrl'].GetStringSelection())
05464         x = self.unitConv.convert(value = x, fromUnit = 'inch', toUnit = currUnit)
05465         y = self.unitConv.convert(value = y, fromUnit = 'inch', toUnit = currUnit)
05466         self.positionPanel.position['xCtrl'].SetValue("%5.3f" % x)
05467         self.positionPanel.position['yCtrl'].SetValue("%5.3f" % y)
05468         # EN coordinates
05469         e, n = self.textDict['east'], self.textDict['north']
05470         self.eastingCtrl.SetValue(str(self.textDict['east']))
05471         self.northingCtrl.SetValue(str(self.textDict['north']))
05472         
05473 def convertRGB(rgb):
05474     """!Converts wx.Colour(r,g,b,a) to string 'r:g:b' or named color,
05475             or named color/r:g:b string to wx.Colour, depending on input""" 
05476     # transform a wx.Colour tuple into an r:g:b string    
05477     if type(rgb) == wx.Colour:
05478         for name, color in grass.named_colors.items(): 
05479             if  rgb.Red() == int(color[0] * 255) and\
05480                 rgb.Green() == int(color[1] * 255) and\
05481                 rgb.Blue() == int(color[2] * 255):
05482                 return name
05483         return str(rgb.Red()) + ':' + str(rgb.Green()) + ':' + str(rgb.Blue())
05484     # transform a GRASS named color or an r:g:b string into a wx.Colour tuple
05485     else:
05486         color = (grass.parse_color(rgb)[0]*255,
05487                  grass.parse_color(rgb)[1]*255,
05488                  grass.parse_color(rgb)[2]*255)
05489         color = wx.Color(*color)
05490         if color.IsOk():
05491             return color
05492         else:  
05493             return None
05494         
05495 def PaperMapCoordinates(map, x, y, paperToMap = True):
05496     """!Converts paper (inch) coordinates -> map coordinates"""
05497     unitConv = UnitConversion()
05498     currRegionDict = grass.region()
05499     cornerEasting, cornerNorthing = currRegionDict['w'], currRegionDict['n']
05500     xMap = map['rect'][0]
05501     yMap = map['rect'][1]
05502     widthMap = map['rect'][2] * 0.0254 # to meter
05503     heightMap = map['rect'][3] * 0.0254
05504     xScale = widthMap / abs(currRegionDict['w'] - currRegionDict['e'])
05505     yScale = heightMap / abs(currRegionDict['n'] - currRegionDict['s'])
05506     currScale = (xScale + yScale) / 2
05507  
05508     if not paperToMap:
05509         textEasting, textNorthing = x, y
05510         eastingDiff = textEasting - cornerEasting 
05511         if currRegionDict['w'] > currRegionDict['e']:
05512             eastingDiff = - eastingDiff
05513         else:
05514             eastingDiff = eastingDiff
05515 
05516         northingDiff = textNorthing - cornerNorthing
05517         if currRegionDict['n'] > currRegionDict['s']:
05518             northingDiff = - northingDiff 
05519         else:
05520             northingDiff = northingDiff
05521 
05522         xPaper = xMap + unitConv.convert(value = eastingDiff, fromUnit = 'meter', toUnit = 'inch') * currScale
05523         yPaper = yMap + unitConv.convert(value = northingDiff, fromUnit = 'meter', toUnit = 'inch') * currScale
05524         return xPaper, yPaper
05525     else:
05526         if currRegionDict['w'] < currRegionDict['e']:
05527             eastingDiff = (x - xMap) 
05528         else:
05529             eastingDiff = (xMap - x)
05530         if currRegionDict['n'] < currRegionDict['s']:
05531             northingDiff = (y - yMap) 
05532         else:
05533             northingDiff = (yMap - y)
05534 
05535         textEasting = cornerEasting + unitConv.convert(value = eastingDiff, fromUnit = 'inch', toUnit = 'meter') / currScale
05536         textNorthing = cornerNorthing + unitConv.convert(value = northingDiff, fromUnit = 'inch', toUnit = 'meter') / currScale
05537         return int(textEasting), int(textNorthing)
05538         
05539 def AutoAdjust(self, scaleType,  rect, map = None, mapType = None, region = None):
05540     """!Computes map scale, center and map frame rectangle to fit region (scale is not fixed)"""
05541     currRegionDict = {}
05542     if scaleType == 0 and map:# automatic, region from raster or vector
05543         res = ''
05544         if mapType == 'raster': 
05545             try:
05546                 res = grass.read_command("g.region", flags = 'gu', rast = map)
05547             except grass.ScriptError:
05548                 pass
05549         elif mapType == 'vector':
05550             res = grass.read_command("g.region", flags = 'gu', vect = map)
05551         currRegionDict = grass.parse_key_val(res, val_type = float)
05552     elif scaleType == 1 and region: # saved region
05553         res = grass.read_command("g.region", flags = 'gu', region = region)
05554         currRegionDict = grass.parse_key_val(res, val_type = float)
05555     elif scaleType == 2: # current region
05556         env = grass.gisenv()
05557         windFilePath = os.path.join(env['GISDBASE'], env['LOCATION_NAME'], env['MAPSET'], 'WIND')
05558         try:
05559             windFile = open(windFilePath, 'r').read()
05560         except IOError:
05561             currRegionDict = grass.region()
05562         regionDict = grass.parse_key_val(windFile, sep = ':', val_type = float)
05563         region = grass.read_command("g.region", flags = 'gu', n = regionDict['north'], s = regionDict['south'],
05564                                     e = regionDict['east'], w = regionDict['west'])
05565         currRegionDict = grass.parse_key_val(region, val_type = float)
05566                                                                 
05567     else:
05568         return None, None, None
05569     
05570     if not currRegionDict:
05571         return None, None, None
05572     rX = rect.x
05573     rY = rect.y
05574     rW = rect.width
05575     rH = rect.height
05576     if not hasattr(self, 'unitConv'):
05577         self.unitConv = UnitConversion(self)
05578     toM = 1
05579     if projInfo()['proj'] != 'xy':
05580         toM = float(projInfo()['meters'])
05581 
05582     mW = self.unitConv.convert(value = (currRegionDict['e'] - currRegionDict['w']) * toM, fromUnit = 'meter', toUnit = 'inch')
05583     mH = self.unitConv.convert(value = (currRegionDict['n'] - currRegionDict['s']) * toM, fromUnit = 'meter', toUnit = 'inch')
05584     scale = min(rW/mW, rH/mH)
05585     
05586     if rW/rH > mW/mH:
05587         x = rX - (rH*(mW/mH) - rW)/2
05588         y = rY
05589         rWNew = rH*(mW/mH)
05590         rHNew = rH
05591     else:
05592         x = rX
05593         y = rY - (rW*(mH/mW) - rH)/2
05594         rHNew = rW*(mH/mW)
05595         rWNew = rW
05596 
05597     # center
05598     cE = (currRegionDict['w'] + currRegionDict['e'])/2
05599     cN = (currRegionDict['n'] + currRegionDict['s'])/2
05600     return scale, (cE, cN), wx.Rect2D(x, y, rWNew, rHNew) #inch
05601 
05602 def SetResolution(dpi, width, height):
05603     """!If resolution is too high, lower it
05604     
05605     @param dpi max DPI
05606     @param width map frame width
05607     @param height map frame height
05608     """
05609     region = grass.region()
05610     if region['cols'] > width * dpi or region['rows'] > height * dpi:
05611         rows = height * dpi
05612         cols = width * dpi
05613         RunCommand('g.region', rows = rows, cols = cols)
05614                
05615 def ComputeSetRegion(self, mapDict):
05616     """!Computes and sets region from current scale, map center coordinates and map rectangle"""
05617 
05618     if mapDict['scaleType'] == 3: # fixed scale
05619         scale = mapDict['scale']
05620             
05621         if not hasattr(self, 'unitConv'):
05622             self.unitConv = UnitConversion(self)
05623         
05624         fromM = 1
05625         if projInfo()['proj'] != 'xy':
05626             fromM = float(projInfo()['meters'])
05627         rectHalfInch = (mapDict['rect'].width/2, mapDict['rect'].height/2)
05628         rectHalfMeter = (self.unitConv.convert(value = rectHalfInch[0], fromUnit = 'inch', toUnit = 'meter')/ fromM /scale,
05629                          self.unitConv.convert(value = rectHalfInch[1], fromUnit = 'inch', toUnit = 'meter')/ fromM /scale) 
05630         
05631         centerE = mapDict['center'][0]
05632         centerN = mapDict['center'][1]
05633         
05634         raster = self.instruction.FindInstructionByType('raster')
05635         if raster:
05636             rasterId = raster.id 
05637         else:
05638             rasterId = None
05639 
05640         if rasterId:
05641             RunCommand('g.region', n = ceil(centerN + rectHalfMeter[1]),
05642                        s = floor(centerN - rectHalfMeter[1]),
05643                        e = ceil(centerE + rectHalfMeter[0]),
05644                        w = floor(centerE - rectHalfMeter[0]),
05645                        rast = self.instruction[rasterId]['raster'])
05646         else:
05647             RunCommand('g.region', n = ceil(centerN + rectHalfMeter[1]),
05648                        s = floor(centerN - rectHalfMeter[1]),
05649                        e = ceil(centerE + rectHalfMeter[0]),
05650                        w = floor(centerE - rectHalfMeter[0]))
05651                     
05652 def projInfo():
05653     """!Return region projection and map units information,
05654     taken from render.py"""
05655     
05656     projinfo = dict()
05657     
05658     ret = RunCommand('g.proj', read = True, flags = 'p')
05659     
05660     if not ret:
05661         return projinfo
05662     
05663     for line in ret.splitlines():
05664         if ':' in line:
05665             key, val = line.split(':')
05666             projinfo[key.strip()] = val.strip()
05667         elif "XY location (unprojected)" in line:
05668             projinfo['proj'] = 'xy'
05669             projinfo['units'] = ''
05670             break
05671     
05672     return projinfo
05673 
05674 def GetMapBounds(filename, portrait = True):
05675     """!Run ps.map -b to get information about map bounding box
05676     
05677         @param filename psmap input file
05678         @param portrait page orientation"""
05679     orient = ''
05680     if not portrait:
05681         orient = 'r'
05682     try:
05683         bb = map(float, grass.read_command('ps.map',
05684                                            flags = 'b' + orient,
05685                                            quiet = True,
05686                                            input = filename).strip().split('=')[1].split(','))
05687     except (grass.ScriptError, IndexError):
05688         GError(message = _("Unable to run `ps.map -b`"))
05689         return None
05690     return wx.Rect2D(bb[0], bb[3], bb[2] - bb[0], bb[1] - bb[3])
05691 
05692 def getRasterType(map):
05693     """!Returns type of raster map (CELL, FCELL, DCELL)"""
05694     if map is None:
05695         map = ''
05696     file = grass.find_file(name = map, element = 'cell')
05697     if file['file']:
05698         rasterType = grass.raster_info(map)['datatype']
05699         return rasterType
05700     else:
05701         return None
05702    
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines