1""" 2@package psmap.dialogs 3 4@brief dialogs for wxPsMap 5 6Classes: 7 - dialogs::TCValidator 8 - dialogs::PenStyleComboBox 9 - dialogs::CheckListCtrl 10 - dialogs::PsmapDialog 11 - dialogs::PageSetupDialog 12 - dialogs::MapDialog 13 - dialogs::MapFramePanel 14 - dialogs::RasterPanel 15 - dialogs::VectorPanel 16 - dialogs::RasterDialog 17 - dialogs::MainVectorDialog 18 - dialogs::VPropertiesDialog 19 - dialogs::LegendDialog 20 - dialogs::MapinfoDialog 21 - dialogs::ScalebarDialog 22 - dialogs::TextDialog 23 - dialogs::ImageDialog 24 - dialogs::NorthArrowDialog 25 - dialogs::PointDialog 26 - dialogs::RectangleDialog 27 28(C) 2011-2012 by Anna Kratochvilova, and the GRASS Development Team 29 30This program is free software under the GNU General Public License 31(>=v2). Read the file COPYING that comes with GRASS for details. 32 33@author Anna Kratochvilova <kratochanna gmail.com> (bachelor's project) 34@author Martin Landa <landa.martin gmail.com> (mentor) 35""" 36 37import os 38import string 39import sys 40from copy import deepcopy 41 42import wx 43import wx.lib.agw.floatspin as fs 44from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin 45 46from core import globalvar 47 48if globalvar.wxPythonPhoenix: 49 from wx import Validator 50else: 51 from wx import PyValidator as Validator 52 53import grass.script as grass 54 55from core.utils import PilImageToWxImage 56from dbmgr.vinfo import VectorDBInfo 57from gui_core.gselect import Select 58from core.gcmd import RunCommand, GError, GMessage 59from gui_core.dialogs import SymbolDialog 60from gui_core.wrap import ( 61 BitmapButton, BitmapComboBox, BitmapFromImage, Button, 62 CheckBox, Choice, ClientDC, ColourPickerCtrl, Dialog, DirBrowseButton, 63 EmptyBitmap, ExpandoTextCtrl, FileBrowseButton, FloatSpin, ListBox, 64 ListCtrl, Notebook, OwnerDrawnComboBox, Panel, RadioButton, 65 Rect, ScrolledPanel, SpinCtrl, StaticBox, StaticText, TextCtrl, 66 TextEntryDialog, EmptyImage, CheckListCtrlMixin 67) 68from psmap.utils import * 69from psmap.instructions import * 70 71# grass.set_raise_on_error(True) 72 73PSMAP_COLORS = [ 74 'aqua', 75 'black', 76 'blue', 77 'brown', 78 'cyan', 79 'gray', 80 'grey', 81 'green', 82 'indigo', 83 'magenta', 84 'orange', 85 'purple', 86 'red', 87 'violet', 88 'white', 89 'yellow'] 90 91 92class TCValidator(Validator): 93 """validates input in textctrls, combobox, taken from wxpython demo""" 94 95 def __init__(self, flag=None): 96 Validator.__init__(self) 97 self.flag = flag 98 self.Bind(wx.EVT_CHAR, self.OnChar) 99 100 def Clone(self): 101 return TCValidator(self.flag) 102 103 def Validate(self, win): 104 105 tc = self.GetWindow() 106 val = tc.GetValue() 107 108 if self.flag == 'DIGIT_ONLY': 109 for x in val: 110 if x not in string.digits: 111 return False 112 return True 113 114 def OnChar(self, event): 115 key = event.GetKeyCode() 116 if key < wx.WXK_SPACE or key == wx.WXK_DELETE or key > 255: 117 event.Skip() 118 return 119 if self.flag == 'DIGIT_ONLY' and chr(key) in string.digits + '.-': 120 event.Skip() 121 return 122# if self.flag == 'SCALE' and chr(key) in string.digits + ':': 123# event.Skip() 124# return 125 if self.flag == 'ZERO_AND_ONE_ONLY' and chr(key) in '01': 126 event.Skip() 127 return 128 if not wx.Validator_IsSilent(): 129 wx.Bell() 130 # Returning without calling even.Skip eats the event before it 131 # gets to the text control 132 return 133 134 135class PenStyleComboBox(OwnerDrawnComboBox): 136 """Combo for selecting line style, taken from wxpython demo""" 137 138 # Overridden from OwnerDrawnComboBox, called to draw each 139 # item in the list 140 def OnDrawItem(self, dc, rect, item, flags): 141 if item == wx.NOT_FOUND: 142 # painting the control, but there is no valid item selected yet 143 return 144 145 r = Rect(*rect) # make a copy 146 r.Deflate(3, 5) 147 148 penStyle = wx.SOLID 149 if item == 1: 150 penStyle = wx.LONG_DASH 151 elif item == 2: 152 penStyle = wx.DOT 153 elif item == 3: 154 penStyle = wx.DOT_DASH 155 156 pen = wx.Pen(dc.GetTextForeground(), 3, penStyle) 157 dc.SetPen(pen) 158 159 # for painting the items in the popup 160 dc.DrawText(self.GetString(item), 161 r.x + 3, 162 (r.y + 0) + ((r.height / 2) - dc.GetCharHeight()) / 2 163 ) 164 dc.DrawLine(r.x + 5, r.y + ((r.height / 4) * 3) + 1, 165 r.x + r.width - 5, r.y + ((r.height / 4) * 3) + 1) 166 167 def OnDrawBackground(self, dc, rect, item, flags): 168 """Overridden from OwnerDrawnComboBox, called for drawing the 169 background area of each item.""" 170 # If the item is selected, or its item # iseven, or we are painting the 171 # combo control itself, then use the default rendering. 172 if (item & 1 == 0 or flags & (OwnerDrawnComboBox.ODCB_PAINTING_CONTROL | 173 OwnerDrawnComboBox.ODCB_PAINTING_SELECTED)): 174 OwnerDrawnComboBox.OnDrawBackground( 175 self, dc, rect, item, flags) 176 return 177 178 # Otherwise, draw every other background with different colour. 179 bgCol = wx.Colour(240, 240, 250) 180 dc.SetBrush(wx.Brush(bgCol)) 181 dc.SetPen(wx.Pen(bgCol)) 182 if globalvar.wxPythonPhoenix: 183 dc.DrawRectangle(rect) 184 else: 185 dc.DrawRectangleRect(rect) 186 187 def OnMeasureItem(self, item): 188 """Overridden from OwnerDrawnComboBox, should return the height 189 needed to display an item in the popup, or -1 for default""" 190 return 30 191 192 def OnMeasureItemWidth(self, item): 193 """Overridden from OwnerDrawnComboBox. Callback for item width, or 194 -1 for default/undetermined""" 195 return -1 # default - will be measured from text width 196 197 198class CheckListCtrl(ListCtrl, CheckListCtrlMixin, ListCtrlAutoWidthMixin): 199 """List control for managing order and labels of vector maps in legend""" 200 201 def __init__(self, parent): 202 ListCtrl.__init__( 203 self, parent, id=wx.ID_ANY, style=wx.LC_REPORT | wx.LC_SINGLE_SEL | 204 wx.BORDER_SUNKEN | wx.LC_VRULES | wx.LC_HRULES) 205 CheckListCtrlMixin.__init__(self) 206 ListCtrlAutoWidthMixin.__init__(self) 207 208 209class PsmapDialog(Dialog): 210 211 def __init__(self, parent, id, title, settings, env, apply=True): 212 Dialog.__init__(self, parent=parent, id=wx.ID_ANY, 213 title=title, size=wx.DefaultSize, 214 style=wx.CAPTION | wx.MINIMIZE_BOX | wx.CLOSE_BOX) 215 self.apply = apply 216 self.id = id 217 self.env = env 218 self.parent = parent 219 self.instruction = settings 220 self.objectType = None 221 self.unitConv = UnitConversion(self) 222 self.spinCtrlSize = (65, -1) 223 224 self.Bind(wx.EVT_CLOSE, self.OnClose) 225 226 def AddUnits(self, parent, dialogDict): 227 parent.units = dict() 228 parent.units['unitsLabel'] = StaticText( 229 parent, id=wx.ID_ANY, label=_("Units:")) 230 choices = self.unitConv.getPageUnitsNames() 231 parent.units['unitsCtrl'] = Choice( 232 parent, id=wx.ID_ANY, choices=choices) 233 parent.units['unitsCtrl'].SetStringSelection( 234 self.unitConv.findName(dialogDict['unit'])) 235 236 def AddPosition(self, parent, dialogDict): 237 if not hasattr(parent, "position"): 238 parent.position = dict() 239 parent.position['comment'] = StaticText(parent, id=wx.ID_ANY, label=_( 240 "Position of the top left corner\nfrom the top left edge of the paper")) 241 parent.position['xLabel'] = StaticText( 242 parent, id=wx.ID_ANY, label=_("X:")) 243 parent.position['yLabel'] = StaticText( 244 parent, id=wx.ID_ANY, label=_("Y:")) 245 parent.position['xCtrl'] = TextCtrl( 246 parent, id=wx.ID_ANY, value=str( 247 dialogDict['where'][0]), validator=TCValidator( 248 flag='DIGIT_ONLY')) 249 parent.position['yCtrl'] = TextCtrl( 250 parent, id=wx.ID_ANY, value=str( 251 dialogDict['where'][1]), validator=TCValidator( 252 flag='DIGIT_ONLY')) 253 if 'unit' in dialogDict: 254 x = self.unitConv.convert( 255 value=dialogDict['where'][0], 256 fromUnit='inch', 257 toUnit=dialogDict['unit']) 258 y = self.unitConv.convert( 259 value=dialogDict['where'][1], 260 fromUnit='inch', 261 toUnit=dialogDict['unit']) 262 parent.position['xCtrl'].SetValue("%5.3f" % x) 263 parent.position['yCtrl'].SetValue("%5.3f" % y) 264 265 def AddExtendedPosition(self, panel, gridBagSizer, dialogDict): 266 """Add widgets for setting position relative to paper and to map""" 267 panel.position = dict() 268 positionLabel = StaticText( 269 panel, id=wx.ID_ANY, label=_("Position is given:")) 270 panel.position['toPaper'] = RadioButton( 271 panel, id=wx.ID_ANY, label=_("relative to paper"), style=wx.RB_GROUP) 272 panel.position['toMap'] = RadioButton( 273 panel, id=wx.ID_ANY, label=_("by map coordinates")) 274 panel.position['toPaper'].SetValue(dialogDict['XY']) 275 panel.position['toMap'].SetValue(not dialogDict['XY']) 276 277 gridBagSizer.Add( 278 positionLabel, pos=( 279 0, 0), span=( 280 1, 3), flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT, border=0) 281 gridBagSizer.Add( 282 panel.position['toPaper'], 283 pos=( 284 1, 285 0), 286 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT, 287 border=0) 288 gridBagSizer.Add( 289 panel.position['toMap'], 290 pos=( 291 1, 292 1), 293 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT, 294 border=0) 295 296 # first box - paper coordinates 297 box1 = StaticBox(parent=panel, id=wx.ID_ANY, label="") 298 sizerP = wx.StaticBoxSizer(box1, wx.VERTICAL) 299 self.gridBagSizerP = wx.GridBagSizer(hgap=5, vgap=5) 300 301 self.AddPosition(parent=panel, dialogDict=dialogDict) 302 panel.position['comment'].SetLabel( 303 _("Position from the top left\nedge of the paper")) 304 self.AddUnits(parent=panel, dialogDict=dialogDict) 305 self.gridBagSizerP.Add( 306 panel.units['unitsLabel'], pos=( 307 0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 308 self.gridBagSizerP.Add( 309 panel.units['unitsCtrl'], pos=( 310 0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 311 self.gridBagSizerP.Add( 312 panel.position['xLabel'], pos=( 313 1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 314 self.gridBagSizerP.Add(panel.position['xCtrl'], pos=( 315 1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 316 self.gridBagSizerP.Add( 317 panel.position['yLabel'], pos=( 318 2, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 319 self.gridBagSizerP.Add(panel.position['yCtrl'], pos=( 320 2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 321 self.gridBagSizerP.Add( 322 panel.position['comment'], pos=( 323 3, 0), span=( 324 1, 2), flag=wx.ALIGN_BOTTOM, border=0) 325 326 self.gridBagSizerP.AddGrowableCol(1) 327 self.gridBagSizerP.AddGrowableRow(3) 328 sizerP.Add( 329 self.gridBagSizerP, 330 proportion=1, 331 flag=wx.EXPAND | wx.ALL, 332 border=5) 333 gridBagSizer.Add( 334 sizerP, pos=( 335 2, 0), span=( 336 1, 1), flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND, border=0) 337 338 # second box - map coordinates 339 box2 = StaticBox(parent=panel, id=wx.ID_ANY, label="") 340 sizerM = wx.StaticBoxSizer(box2, wx.VERTICAL) 341 self.gridBagSizerM = wx.GridBagSizer(hgap=5, vgap=5) 342 343 eastingLabel = StaticText(panel, id=wx.ID_ANY, label="E:") 344 northingLabel = StaticText(panel, id=wx.ID_ANY, label="N:") 345 panel.position['eCtrl'] = TextCtrl(panel, id=wx.ID_ANY, value="") 346 panel.position['nCtrl'] = TextCtrl(panel, id=wx.ID_ANY, value="") 347 east, north = PaperMapCoordinates( 348 mapInstr=self.instruction[self.mapId], 349 x=dialogDict['where'][0], 350 y=dialogDict['where'][1], 351 paperToMap=True, 352 env=self.env) 353 panel.position['eCtrl'].SetValue(str(east)) 354 panel.position['nCtrl'].SetValue(str(north)) 355 356 self.gridBagSizerM.Add( 357 eastingLabel, pos=(0, 0), 358 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 359 self.gridBagSizerM.Add( 360 northingLabel, pos=(1, 0), 361 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 362 self.gridBagSizerM.Add(panel.position['eCtrl'], pos=( 363 0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 364 self.gridBagSizerM.Add(panel.position['nCtrl'], pos=( 365 1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 366 367 self.gridBagSizerM.AddGrowableCol(0) 368 self.gridBagSizerM.AddGrowableCol(1) 369 sizerM.Add( 370 self.gridBagSizerM, 371 proportion=1, 372 flag=wx.EXPAND | wx.ALL, 373 border=5) 374 gridBagSizer.Add( 375 sizerM, pos=(2, 1), 376 flag=wx.ALIGN_LEFT | wx.EXPAND, border=0) 377 378 def AddFont(self, parent, dialogDict, color=True): 379 parent.font = dict() 380## parent.font['fontLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose font:")) 381## parent.font['fontCtrl'] = wx.FontPickerCtrl(parent, id = wx.ID_ANY) 382## 383# parent.font['fontCtrl'].SetSelectedFont( 384# wx.FontFromNativeInfoString(dialogDict['font'] + " " + str(dialogDict['fontsize']))) 385# parent.font['fontCtrl'].SetMaxPointSize(50) 386## 387# if color: 388## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Choose color:")) 389## parent.font['colorCtrl'] = ColourPickerCtrl(parent, id = wx.ID_ANY, style=wx.FNTP_FONTDESC_AS_LABEL) 390# parent.font['colorCtrl'].SetColour(dialogDict['color']) 391 392# parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color'])) 393 394 parent.font['fontLabel'] = StaticText( 395 parent, id=wx.ID_ANY, label=_("Font:")) 396 parent.font['fontSizeLabel'] = StaticText( 397 parent, id=wx.ID_ANY, label=_("Font size:")) 398 fontChoices = [ 399 'Times-Roman', 400 'Times-Italic', 401 'Times-Bold', 402 'Times-BoldItalic', 403 'Helvetica', 404 'Helvetica-Oblique', 405 'Helvetica-Bold', 406 'Helvetica-BoldOblique', 407 'Courier', 408 'Courier-Oblique', 409 'Courier-Bold', 410 'Courier-BoldOblique'] 411 parent.font['fontCtrl'] = Choice( 412 parent, id=wx.ID_ANY, choices=fontChoices) 413 if dialogDict['font'] in fontChoices: 414 parent.font['fontCtrl'].SetStringSelection(dialogDict['font']) 415 else: 416 parent.font['fontCtrl'].SetStringSelection('Helvetica') 417 parent.font['fontSizeCtrl'] = SpinCtrl( 418 parent, id=wx.ID_ANY, min=4, max=50, initial=10) 419 parent.font['fontSizeCtrl'].SetValue(dialogDict['fontsize']) 420 421 if color: 422 parent.font['colorLabel'] = StaticText( 423 parent, id=wx.ID_ANY, label=_("Choose color:")) 424 parent.font['colorCtrl'] = ColourPickerCtrl( 425 parent, id=wx.ID_ANY) 426 parent.font['colorCtrl'].SetColour(convertRGB(dialogDict['color'])) 427## parent.font['colorLabel'] = wx.StaticText(parent, id = wx.ID_ANY, label = _("Color:")) 428# colorChoices = [ 'aqua', 'black', 'blue', 'brown', 'cyan', 'gray', 'green', 'indigo', 'magenta',\ 429# 'orange', 'purple', 'red', 'violet', 'white', 'yellow'] 430## parent.colorCtrl = Choice(parent, id = wx.ID_ANY, choices = colorChoices) 431# parent.colorCtrl.SetStringSelection(parent.rLegendDict['color']) 432## parent.font['colorCtrl'] = ColourPickerCtrl(parent, id = wx.ID_ANY) 433# parent.font['colorCtrl'].SetColour(dialogDict['color']) 434 435 def OnApply(self, event): 436 ok = self.update() 437 if ok: 438 self.parent.DialogDataChanged(id=self.id) 439 return True 440 else: 441 return False 442 443 def OnOK(self, event): 444 """Apply changes, close dialog""" 445 ok = self.OnApply(event) 446 if ok: 447 self.Close() 448 449 def OnCancel(self, event): 450 """Close dialog""" 451 self.Close() 452 453 def OnClose(self, event): 454 """Destroy dialog and delete it from open dialogs""" 455 if self.objectType: 456 for each in self.objectType: 457 if each in self.parent.openDialogs: 458 del self.parent.openDialogs[each] 459 event.Skip() 460 self.Destroy() 461 462 def _layout(self, panel): 463 # buttons 464 btnCancel = Button(self, wx.ID_CANCEL) 465 btnOK = Button(self, wx.ID_OK) 466 btnOK.SetDefault() 467 if self.apply: 468 btnApply = Button(self, wx.ID_APPLY) 469 470 # bindigs 471 btnOK.Bind(wx.EVT_BUTTON, self.OnOK) 472 btnOK.SetToolTip(_("Close dialog and apply changes")) 473 #btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel) 474 btnCancel.SetToolTip(_("Close dialog and ignore changes")) 475 btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel) 476 if self.apply: 477 btnApply.Bind(wx.EVT_BUTTON, self.OnApply) 478 btnApply.SetToolTip(_("Apply changes")) 479 480 # sizers 481 btnSizer = wx.StdDialogButtonSizer() 482 btnSizer.AddButton(btnCancel) 483 if self.apply: 484 btnSizer.AddButton(btnApply) 485 btnSizer.AddButton(btnOK) 486 btnSizer.Realize() 487 488 mainSizer = wx.BoxSizer(wx.VERTICAL) 489 mainSizer.Add( 490 panel, 491 proportion=1, 492 flag=wx.EXPAND | wx.ALL, 493 border=5) 494 mainSizer.Add(btnSizer, proportion=0, 495 flag=wx.EXPAND | wx.ALL, border=5) 496 497 self.SetSizer(mainSizer) 498 mainSizer.Layout() 499 mainSizer.Fit(self) 500 501 502class PageSetupDialog(PsmapDialog): 503 504 def __init__(self, parent, id, settings, env): 505 PsmapDialog.__init__( 506 self, 507 parent=parent, 508 id=id, 509 title="Page setup", 510 settings=settings, 511 env=env) 512 513 self.cat = [ 514 'Units', 515 'Format', 516 'Orientation', 517 'Width', 518 'Height', 519 'Left', 520 'Right', 521 'Top', 522 'Bottom'] 523 labels = [ 524 _('Units'), 525 _('Format'), 526 _('Orientation'), 527 _('Width'), 528 _('Height'), 529 _('Left'), 530 _('Right'), 531 _('Top'), 532 _('Bottom')] 533 self.catsLabels = dict(zip(self.cat, labels)) 534 paperString = RunCommand('ps.map', flags='p', read=True, quiet=True) 535 self.paperTable = self._toList(paperString) 536 self.unitsList = self.unitConv.getPageUnitsNames() 537 self.pageSetupDict = settings[id].GetInstruction() 538 539 self._layout() 540 541 if self.pageSetupDict: 542 self.getCtrl('Units').SetStringSelection( 543 self.unitConv.findName(self.pageSetupDict['Units'])) 544 if self.pageSetupDict['Format'] == 'custom': 545 self.getCtrl('Format').SetSelection( 546 self.getCtrl('Format').GetCount() - 1) 547 else: 548 self.getCtrl('Format').SetStringSelection( 549 self.pageSetupDict['Format']) 550 if self.pageSetupDict['Orientation'] == 'Portrait': 551 self.getCtrl('Orientation').SetSelection(0) 552 else: 553 self.getCtrl('Orientation').SetSelection(1) 554 555 for item in self.cat[3:]: 556 val = self.unitConv.convert( 557 value=self.pageSetupDict[item], 558 fromUnit='inch', 559 toUnit=self.pageSetupDict['Units']) 560 self.getCtrl(item).SetValue("%4.3f" % val) 561 562 if self.getCtrl('Format').GetSelection() != self.getCtrl( 563 'Format').GetCount() - 1: # custom 564 self.getCtrl('Width').Disable() 565 self.getCtrl('Height').Disable() 566 else: 567 self.getCtrl('Orientation').Disable() 568 # events 569 self.getCtrl('Units').Bind(wx.EVT_CHOICE, self.OnChoice) 570 self.getCtrl('Format').Bind(wx.EVT_CHOICE, self.OnChoice) 571 self.getCtrl('Orientation').Bind(wx.EVT_CHOICE, self.OnChoice) 572 self.btnOk.Bind(wx.EVT_BUTTON, self.OnOK) 573 574 def update(self): 575 self.pageSetupDict['Units'] = self.unitConv.findUnit( 576 self.getCtrl('Units').GetStringSelection()) 577 self.pageSetupDict['Format'] = self.paperTable[ 578 self.getCtrl('Format').GetSelection()]['Format'] 579 if self.getCtrl('Orientation').GetSelection() == 0: 580 self.pageSetupDict['Orientation'] = 'Portrait' 581 else: 582 self.pageSetupDict['Orientation'] = 'Landscape' 583 for item in self.cat[3:]: 584 self.pageSetupDict[item] = self.unitConv.convert( 585 value=float(self.getCtrl(item).GetValue()), 586 fromUnit=self.pageSetupDict['Units'], 587 toUnit='inch') 588 589 def OnOK(self, event): 590 try: 591 self.update() 592 except ValueError: 593 wx.MessageBox( 594 message=_("Literal is not allowed!"), 595 caption=_('Invalid input'), 596 style=wx.OK | wx.ICON_ERROR) 597 else: 598 event.Skip() 599 600 def _layout(self): 601 size = (110, -1) 602 # sizers 603 mainSizer = wx.BoxSizer(wx.VERTICAL) 604 pageBox = StaticBox( 605 self, 606 id=wx.ID_ANY, 607 label=" %s " % 608 _("Page size")) 609 pageSizer = wx.StaticBoxSizer(pageBox, wx.VERTICAL) 610 marginBox = StaticBox( 611 self, id=wx.ID_ANY, label=" %s " % 612 _("Margins")) 613 marginSizer = wx.StaticBoxSizer(marginBox, wx.VERTICAL) 614 horSizer = wx.BoxSizer(wx.HORIZONTAL) 615 #staticText + choice 616 choices = [ 617 self.unitsList, [ 618 item['Format'] for item in self.paperTable], [ 619 _('Portrait'), _('Landscape')]] 620 propor = [0, 1, 1] 621 border = [5, 3, 3] 622 self.hBoxDict = {} 623 for i, item in enumerate(self.cat[:3]): 624 hBox = wx.BoxSizer(wx.HORIZONTAL) 625 stText = StaticText( 626 self, id=wx.ID_ANY, label=self.catsLabels[item] + ':') 627 choice = Choice( 628 self, 629 id=wx.ID_ANY, 630 choices=choices[i], 631 size=size) 632 hBox.Add( 633 stText, 634 proportion=propor[i], 635 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, 636 border=border[i]) 637 hBox.Add(choice, proportion=0, flag=wx.ALL, border=border[i]) 638 if item == 'Units': 639 hBox.Add(size, 1) 640 self.hBoxDict[item] = hBox 641 642 #staticText + TextCtrl 643 for item in self.cat[3:]: 644 hBox = wx.BoxSizer(wx.HORIZONTAL) 645 label = StaticText( 646 self, id=wx.ID_ANY, label=self.catsLabels[item] + ':') 647 textctrl = TextCtrl(self, id=wx.ID_ANY, size=size, value='') 648 hBox.Add( 649 label, 650 proportion=1, 651 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, 652 border=3) 653 hBox.Add( 654 textctrl, 655 proportion=0, 656 flag=wx.ALIGN_CENTRE | wx.ALL, 657 border=3) 658 self.hBoxDict[item] = hBox 659 660 sizer = list([mainSizer] + [pageSizer] * 4 + [marginSizer] * 4) 661 for i, item in enumerate(self.cat): 662 sizer[i].Add( 663 self.hBoxDict[item], 664 0, wx.GROW | wx.RIGHT | wx.LEFT, 5) 665 # OK button 666 btnSizer = wx.StdDialogButtonSizer() 667 self.btnOk = Button(self, wx.ID_OK) 668 self.btnOk.SetDefault() 669 btnSizer.AddButton(self.btnOk) 670 btn = Button(self, wx.ID_CANCEL) 671 btnSizer.AddButton(btn) 672 btnSizer.Realize() 673 674 horSizer.Add( 675 pageSizer, 676 proportion=0, 677 flag=wx.LEFT | wx.RIGHT | wx.BOTTOM, 678 border=10) 679 horSizer.Add(marginSizer, proportion=0, flag=wx.LEFT | 680 wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=10) 681 mainSizer.Add(horSizer, proportion=0, border=10) 682 mainSizer.Add( 683 btnSizer, 684 proportion=0, 685 flag=wx.ALIGN_RIGHT | wx.ALL, 686 border=10) 687 self.SetSizer(mainSizer) 688 mainSizer.Fit(self) 689 690 def OnChoice(self, event): 691 currPaper = self.paperTable[self.getCtrl('Format').GetSelection()] 692 currUnit = self.unitConv.findUnit( 693 self.getCtrl('Units').GetStringSelection()) 694 currOrientIdx = self.getCtrl('Orientation').GetSelection() 695 newSize = dict() 696 for item in self.cat[3:]: 697 newSize[item] = self.unitConv.convert( 698 float(currPaper[item]), 699 fromUnit='inch', toUnit=currUnit) 700 701 enable = True 702 if currPaper['Format'] != _('custom'): 703 if currOrientIdx == 1: # portrait 704 newSize['Width'], newSize['Height'] = newSize[ 705 'Height'], newSize['Width'] 706 for item in self.cat[3:]: 707 self.getCtrl(item).ChangeValue("%4.3f" % newSize[item]) 708 enable = False 709 self.getCtrl('Width').Enable(enable) 710 self.getCtrl('Height').Enable(enable) 711 self.getCtrl('Orientation').Enable(not enable) 712 713 def getCtrl(self, item): 714 return self.hBoxDict[item].GetItem(1).GetWindow() 715 716 def _toList(self, paperStr): 717 718 sizeList = list() 719 for line in paperStr.strip().split('\n'): 720 d = dict(zip([self.cat[1]] + self.cat[3:], line.split())) 721 sizeList.append(d) 722 d = {}.fromkeys([self.cat[1]] + self.cat[3:], 100) 723 d.update(Format=_('custom')) 724 sizeList.append(d) 725 return sizeList 726 727 728class MapDialog(PsmapDialog): 729 """Dialog for map frame settings and optionally raster and vector map selection""" 730 731 def __init__(self, parent, id, settings, env, rect=None, notebook=False): 732 PsmapDialog.__init__( 733 self, 734 parent=parent, 735 id=id, 736 title="", 737 settings=settings, 738 env=env) 739 740 self.isNotebook = notebook 741 if self.isNotebook: 742 self.objectType = ('mapNotebook',) 743 else: 744 self.objectType = ('map',) 745 746 # notebook 747 if self.isNotebook: 748 self.notebook = Notebook( 749 parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT) 750 self.mPanel = MapFramePanel( 751 parent=self.notebook, 752 id=self.id[0], 753 settings=self.instruction, 754 env=env, 755 rect=rect, 756 notebook=True) 757 self.id[0] = self.mPanel.getId() 758 self.rPanel = RasterPanel( 759 parent=self.notebook, id=self.id[1], 760 settings=self.instruction, env=env, notebook=True) 761 self.id[1] = self.rPanel.getId() 762 self.vPanel = VectorPanel( 763 parent=self.notebook, id=self.id[2], 764 settings=self.instruction, env=env, notebook=True) 765 self.id[2] = self.vPanel.getId() 766 self._layout(self.notebook) 767 self.SetTitle(_("Map settings")) 768 else: 769 self.mPanel = MapFramePanel( 770 parent=self, 771 id=self.id[0], 772 settings=self.instruction, 773 env=env, 774 rect=rect, 775 notebook=False) 776 self.id[0] = self.mPanel.getId() 777 self._layout(self.mPanel) 778 self.SetTitle(_("Map frame settings")) 779 780 def OnApply(self, event): 781 """Apply changes""" 782 if self.isNotebook: 783 okV = self.vPanel.update() 784 okR = self.rPanel.update() 785 if okV and self.id[2] in self.instruction: 786 self.parent.DialogDataChanged(id=self.id[2]) 787 if okR and self.id[1] in self.instruction: 788 self.parent.DialogDataChanged(id=self.id[1]) 789 if not okR or not okV: 790 return False 791 792 ok = self.mPanel.update() 793 if ok: 794 self.parent.DialogDataChanged(id=self.id[0]) 795 return True 796 797 return False 798 799 def OnCancel(self, event): 800 """Close dialog and remove tmp red box""" 801 self.parent.canvas.pdcTmp.RemoveId(self.parent.canvas.idZoomBoxTmp) 802 self.parent.canvas.Refresh() 803 self.Close() 804 805 def updateDialog(self): 806 """Update raster and vector information""" 807 if self.mPanel.scaleChoice.GetSelection() == 0: 808 if self.mPanel.rasterTypeRadio.GetValue(): 809 if 'raster' in self.parent.openDialogs: 810 if self.parent.openDialogs['raster'].rPanel.rasterYesRadio.GetValue() and \ 811 self.parent.openDialogs['raster'].rPanel.rasterSelect.GetValue() == self.mPanel.select.GetValue(): 812 self.mPanel.drawMap.SetValue(True) 813 else: 814 self.mPanel.drawMap.SetValue(False) 815 else: 816 if 'vector' in self.parent.openDialogs: 817 found = False 818 for each in self.parent.openDialogs[ 819 'vector'].vPanel.vectorList: 820 if each[0] == self.mPanel.select.GetValue(): 821 found = True 822 self.mPanel.drawMap.SetValue(found) 823 824 825class MapFramePanel(Panel): 826 """Panel with map (scale, region, border) settings""" 827 828 def __init__(self, parent, id, settings, env, rect, notebook=True): 829 Panel.__init__(self, parent, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL) 830 831 self.id = id 832 self.instruction = settings 833 self.env = env 834 835 if notebook: 836 self.book = parent 837 self.book.AddPage(page=self, text=_("Map frame")) 838 self.mapDialog = self.book.GetParent() 839 else: 840 self.mapDialog = parent 841 842 if self.id is not None: 843 self.mapFrameDict = self.instruction[self.id].GetInstruction() 844 else: 845 self.id = NewId() 846 mapFrame = MapFrame(self.id, env=self.env) 847 self.mapFrameDict = mapFrame.GetInstruction() 848 self.mapFrameDict['rect'] = rect 849 850 self._layout() 851 852 self.scale = [None] * 4 853 self.center = [None] * 4 854 855 self.selectedMap = self.mapFrameDict['map'] 856 self.selectedRegion = self.mapFrameDict['region'] 857 self.scaleType = self.mapFrameDict['scaleType'] 858 self.mapType = self.mapFrameDict['mapType'] 859 self.scaleChoice.SetSelection(self.mapFrameDict['scaleType']) 860 if self.instruction[self.id]: 861 self.drawMap.SetValue(self.mapFrameDict['drawMap']) 862 else: 863 self.drawMap.SetValue(True) 864 if self.mapFrameDict['scaleType'] == 0 and self.mapFrameDict['map']: 865 self.select.SetValue(self.mapFrameDict['map']) 866 if self.mapFrameDict['mapType'] == 'raster': 867 self.rasterTypeRadio.SetValue(True) 868 self.vectorTypeRadio.SetValue(False) 869 else: 870 self.rasterTypeRadio.SetValue(False) 871 self.vectorTypeRadio.SetValue(True) 872 elif self.mapFrameDict['scaleType'] == 1 and self.mapFrameDict['region']: 873 self.select.SetValue(self.mapFrameDict['region']) 874 875 self.OnMap(None) 876 self.scale[self.mapFrameDict['scaleType']] = self.mapFrameDict['scale'] 877 self.center[self.mapFrameDict['scaleType'] 878 ] = self.mapFrameDict['center'] 879 self.OnScaleChoice(None) 880 self.OnElementType(None) 881 self.OnBorder(None) 882 883 def _layout(self): 884 """Do layout""" 885 border = wx.BoxSizer(wx.VERTICAL) 886 887 box = StaticBox( 888 parent=self, 889 id=wx.ID_ANY, 890 label=" %s " % 891 _("Map frame")) 892 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 893 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 894 895 # scale options 896 frameText = StaticText( 897 self, id=wx.ID_ANY, label=_("Map frame options:")) 898 scaleChoices = [_("fit frame to match selected map"), 899 _("fit frame to match saved region"), 900 _("fit frame to match current computational region"), 901 _("fixed scale and map center")] 902 self.scaleChoice = Choice(self, id=wx.ID_ANY, choices=scaleChoices) 903 904 gridBagSizer.Add( 905 frameText, pos=(0, 0), 906 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 907 gridBagSizer.Add( 908 self.scaleChoice, 909 pos=( 910 1, 911 0), 912 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 913 border=0) 914 915 # map and region selection 916 self.staticBox = StaticBox( 917 parent=self, id=wx.ID_ANY, label=" %s " % 918 _("Map selection")) 919 sizerM = wx.StaticBoxSizer(self.staticBox, wx.HORIZONTAL) 920 self.mapSizer = wx.GridBagSizer(hgap=5, vgap=5) 921 922 self.rasterTypeRadio = RadioButton( 923 self, id=wx.ID_ANY, label=" %s " % 924 _("raster"), style=wx.RB_GROUP) 925 self.vectorTypeRadio = RadioButton( 926 self, id=wx.ID_ANY, label=" %s " % 927 _("vector")) 928 self.drawMap = CheckBox( 929 self, id=wx.ID_ANY, label="add selected map") 930 931 self.mapOrRegionText = [_("Map:"), _("Region:")] 932 dc = ClientDC(self) # determine size of labels 933 width = max( 934 dc.GetTextExtent( 935 self.mapOrRegionText[0])[0], dc.GetTextExtent( 936 self.mapOrRegionText[1])[0]) 937 self.mapText = StaticText( 938 self, id=wx.ID_ANY, label=self.mapOrRegionText[0], 939 size=(width, -1)) 940 self.select = Select( 941 self, 942 id=wx.ID_ANY, 943 size=globalvar.DIALOG_GSELECT_SIZE, 944 type='raster', 945 multiple=False, 946 updateOnPopup=True, 947 onPopup=None) 948 949 self.mapSizer.Add( 950 self.rasterTypeRadio, pos=(0, 1), 951 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 952 self.mapSizer.Add( 953 self.vectorTypeRadio, pos=(0, 2), 954 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 955 self.mapSizer.Add( 956 self.drawMap, 957 pos=( 958 0, 959 3), 960 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 961 border=0) 962 self.mapSizer.Add( 963 self.mapText, pos=(1, 0), 964 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 965 self.mapSizer.Add( 966 self.select, pos=( 967 1, 1), span=( 968 1, 3), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 969 970 sizerM.Add( 971 self.mapSizer, 972 proportion=1, 973 flag=wx.EXPAND | wx.ALL, 974 border=5) 975 gridBagSizer.Add( 976 sizerM, 977 pos=( 978 2, 979 0), 980 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 981 border=0) 982 983 # map scale and center 984 boxC = StaticBox( 985 parent=self, 986 id=wx.ID_ANY, 987 label=" %s " % 988 _("Map scale and center")) 989 sizerC = wx.StaticBoxSizer(boxC, wx.HORIZONTAL) 990 self.centerSizer = wx.FlexGridSizer(rows=2, cols=5, hgap=5, vgap=5) 991 992 centerText = StaticText(self, id=wx.ID_ANY, label=_("Center:")) 993 self.eastingText = StaticText(self, id=wx.ID_ANY, label=_("E:")) 994 self.northingText = StaticText(self, id=wx.ID_ANY, label=_("N:")) 995 self.eastingTextCtrl = TextCtrl( 996 self, id=wx.ID_ANY, style=wx.TE_RIGHT, 997 validator=TCValidator(flag='DIGIT_ONLY')) 998 self.northingTextCtrl = TextCtrl( 999 self, id=wx.ID_ANY, style=wx.TE_RIGHT, 1000 validator=TCValidator(flag='DIGIT_ONLY')) 1001 scaleText = StaticText(self, id=wx.ID_ANY, label=_("Scale:")) 1002 scalePrefixText = StaticText(self, id=wx.ID_ANY, label=_("1 :")) 1003 self.scaleTextCtrl = TextCtrl( 1004 self, id=wx.ID_ANY, value="", style=wx.TE_RIGHT, 1005 validator=TCValidator('DIGIT_ONLY')) 1006 1007 self.centerSizer.Add( 1008 centerText, 1009 proportion=0, 1010 flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 1011 border=10) 1012 self.centerSizer.Add( 1013 self.eastingText, 1014 proportion=0, 1015 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 1016 border=0) 1017 self.centerSizer.Add( 1018 self.eastingTextCtrl, 1019 proportion=0, 1020 flag=wx.ALIGN_CENTER_VERTICAL, 1021 border=0) 1022 self.centerSizer.Add( 1023 self.northingText, 1024 proportion=0, 1025 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 1026 border=0) 1027 self.centerSizer.Add( 1028 self.northingTextCtrl, 1029 proportion=0, 1030 flag=wx.ALIGN_CENTER_VERTICAL, 1031 border=0) 1032 1033 self.centerSizer.Add( 1034 scaleText, 1035 proportion=0, 1036 flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 1037 border=10) 1038 self.centerSizer.Add( 1039 scalePrefixText, 1040 proportion=0, 1041 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 1042 border=0) 1043 self.centerSizer.Add( 1044 self.scaleTextCtrl, 1045 proportion=0, 1046 flag=wx.ALIGN_CENTER_VERTICAL, 1047 border=0) 1048 1049 sizerC.Add( 1050 self.centerSizer, 1051 proportion=1, 1052 flag=wx.EXPAND | wx.ALL, 1053 border=5) 1054 gridBagSizer.Add( 1055 sizerC, 1056 pos=( 1057 3, 1058 0), 1059 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1060 border=0) 1061 1062 # resolution 1063 flexSizer = wx.FlexGridSizer(rows=1, cols=2, hgap=5, vgap=5) 1064 1065 resolutionText = StaticText( 1066 self, id=wx.ID_ANY, label=_("Map max resolution (dpi):")) 1067 self.resolutionSpin = SpinCtrl( 1068 self, id=wx.ID_ANY, min=1, max=1000, initial=300) 1069 1070 flexSizer.Add( 1071 resolutionText, 1072 proportion=0, 1073 flag=wx.ALIGN_CENTER_VERTICAL, 1074 border=0) 1075 flexSizer.Add( 1076 self.resolutionSpin, 1077 proportion=0, 1078 flag=wx.ALIGN_CENTER_VERTICAL, 1079 border=0) 1080 self.resolutionSpin.SetValue(self.mapFrameDict['resolution']) 1081 1082 gridBagSizer.Add( 1083 flexSizer, 1084 pos=( 1085 4, 1086 0), 1087 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1088 border=0) 1089 1090 sizer.Add( 1091 gridBagSizer, 1092 proportion=1, 1093 flag=wx.EXPAND | wx.ALL, 1094 border=5) 1095 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 1096 1097 # border 1098 # GTC Line around legend or map frame 1099 box = StaticBox( 1100 parent=self, 1101 id=wx.ID_ANY, 1102 label=" %s " % 1103 _("Border")) 1104 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 1105 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 1106 1107 self.borderCheck = CheckBox( 1108 self, id=wx.ID_ANY, label=( 1109 _("draw border around map frame"))) 1110 if self.mapFrameDict['border'] == 'y': 1111 self.borderCheck.SetValue(True) 1112 else: 1113 self.borderCheck.SetValue(False) 1114 1115 self.borderColorText = StaticText( 1116 self, id=wx.ID_ANY, label=_("border color:")) 1117 self.borderWidthText = StaticText( 1118 self, id=wx.ID_ANY, label=_("border width (pts):")) 1119 self.borderColourPicker = ColourPickerCtrl(self, id=wx.ID_ANY) 1120 self.borderWidthCtrl = SpinCtrl( 1121 self, id=wx.ID_ANY, min=1, max=100, initial=1) 1122 1123 if self.mapFrameDict['border'] == 'y': 1124 self.borderWidthCtrl.SetValue(int(self.mapFrameDict['width'])) 1125 self.borderColourPicker.SetColour( 1126 convertRGB(self.mapFrameDict['color'])) 1127 1128 gridBagSizer.Add( 1129 self.borderCheck, pos=( 1130 0, 0), span=( 1131 1, 2), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 1132 gridBagSizer.Add( 1133 self.borderColorText, pos=(1, 1), 1134 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 1135 gridBagSizer.Add( 1136 self.borderWidthText, pos=(2, 1), 1137 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 1138 gridBagSizer.Add( 1139 self.borderColourPicker, 1140 pos=( 1141 1, 1142 2), 1143 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1144 border=0) 1145 gridBagSizer.Add( 1146 self.borderWidthCtrl, 1147 pos=( 1148 2, 1149 2), 1150 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1151 border=0) 1152 1153 sizer.Add( 1154 gridBagSizer, 1155 proportion=1, 1156 flag=wx.EXPAND | wx.ALL, 1157 border=5) 1158 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 1159 1160 self.SetSizer(border) 1161 self.Fit() 1162 1163 if projInfo()['proj'] == 'll': 1164 self.scaleChoice.SetItems(self.scaleChoice.GetItems()[0:3]) 1165 boxC.Hide() 1166 for each in self.centerSizer.GetChildren(): 1167 each.GetWindow().Hide() 1168 1169 # bindings 1170 self.scaleChoice.Bind(wx.EVT_CHOICE, self.OnScaleChoice) 1171 self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.vectorTypeRadio) 1172 self.Bind(wx.EVT_RADIOBUTTON, self.OnElementType, self.rasterTypeRadio) 1173 self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck) 1174 1175 def OnMap(self, event): 1176 """Selected map or region changing""" 1177 1178 if self.select.GetValue(): 1179 self.selected = self.select.GetValue() 1180 else: 1181 self.selected = None 1182 1183 if self.scaleChoice.GetSelection() == 0: 1184 self.selectedMap = self.selected 1185 if self.rasterTypeRadio.GetValue(): 1186 mapType = 'raster' 1187 else: 1188 mapType = 'vector' 1189 1190 self.scale[0], self.center[0], foo = AutoAdjust( 1191 self, scaleType=0, map=self.selected, mapType=mapType, 1192 rect=self.mapFrameDict['rect'], env=self.env) 1193 #self.center[0] = self.RegionCenter(self.RegionDict(scaleType = 0)) 1194 1195 elif self.scaleChoice.GetSelection() == 1: 1196 self.selectedRegion = self.selected 1197 self.scale[1], self.center[1], foo = AutoAdjust( 1198 self, scaleType=1, region=self.selected, 1199 rect=self.mapFrameDict['rect'], env=self.env) 1200 #self.center[1] = self.RegionCenter(self.RegionDict(scaleType = 1)) 1201 elif self.scaleChoice.GetSelection() == 2: 1202 self.scale[2], self.center[2], foo = AutoAdjust( 1203 self, scaleType=2, rect=self.mapFrameDict['rect'], env=self.env) 1204 #self.center[2] = self.RegionCenter(self.RegionDict(scaleType = 2)) 1205 1206 else: 1207 self.scale[3] = None 1208 self.center[3] = None 1209 1210 self.OnScaleChoice(None) 1211 1212 def OnScaleChoice(self, event): 1213 """Selected scale type changing""" 1214 1215 scaleType = self.scaleChoice.GetSelection() 1216 if self.scaleType != scaleType: 1217 self.scaleType = scaleType 1218 self.select.SetValue("") 1219 1220 if scaleType in ( 1221 0, 1): # automatic - region from raster map, saved region 1222 if scaleType == 0: 1223 # set map selection 1224 self.rasterTypeRadio.Show() 1225 self.vectorTypeRadio.Show() 1226 self.drawMap.Show() 1227 self.staticBox.SetLabel(" %s " % _("Map selection")) 1228 if self.rasterTypeRadio.GetValue(): 1229 stype = 'raster' 1230 else: 1231 stype = 'vector' 1232 1233 self.select.SetElementList(type=stype) 1234 self.mapText.SetLabel(self.mapOrRegionText[0]) 1235 self.select.SetToolTip( 1236 _("Region is set to match this map,\nraster or vector map must be added later")) 1237 1238 if scaleType == 1: 1239 # set region selection 1240 self.rasterTypeRadio.Hide() 1241 self.vectorTypeRadio.Hide() 1242 self.drawMap.Hide() 1243 self.staticBox.SetLabel(" %s " % _("Region selection")) 1244 stype = 'region' 1245 self.select.SetElementList(type=stype) 1246 self.mapText.SetLabel(self.mapOrRegionText[1]) 1247 self.select.SetToolTip("") 1248 1249 for each in self.mapSizer.GetChildren(): 1250 each.GetWindow().Enable() 1251 for each in self.centerSizer.GetChildren(): 1252 each.GetWindow().Disable() 1253 1254 if self.scale[scaleType]: 1255 1256 self.scaleTextCtrl.SetValue( 1257 "%.0f" % (1 / self.scale[scaleType])) 1258 if self.center[scaleType]: 1259 self.eastingTextCtrl.SetValue(str(self.center[scaleType][0])) 1260 self.northingTextCtrl.SetValue(str(self.center[scaleType][1])) 1261 elif scaleType == 2: 1262 for each in self.mapSizer.GetChildren(): 1263 each.GetWindow().Disable() 1264 for each in self.centerSizer.GetChildren(): 1265 each.GetWindow().Disable() 1266 1267 if self.scale[scaleType]: 1268 self.scaleTextCtrl.SetValue( 1269 "%.0f" % (1 / self.scale[scaleType])) 1270 if self.center[scaleType]: 1271 self.eastingTextCtrl.SetValue(str(self.center[scaleType][0])) 1272 self.northingTextCtrl.SetValue(str(self.center[scaleType][1])) 1273 else: # fixed 1274 for each in self.mapSizer.GetChildren(): 1275 each.GetWindow().Disable() 1276 for each in self.centerSizer.GetChildren(): 1277 each.GetWindow().Enable() 1278 1279 if self.scale[scaleType]: 1280 self.scaleTextCtrl.SetValue( 1281 "%.0f" % (1 / self.scale[scaleType])) 1282 if self.center[scaleType]: 1283 self.eastingTextCtrl.SetValue(str(self.center[scaleType][0])) 1284 self.northingTextCtrl.SetValue(str(self.center[scaleType][1])) 1285 1286 def OnElementType(self, event): 1287 """Changes data in map selection tree ctrl popup""" 1288 if self.rasterTypeRadio.GetValue(): 1289 mapType = 'raster' 1290 else: 1291 mapType = 'vector' 1292 self.select.SetElementList(type=mapType) 1293 if self.mapType != mapType and event is not None: 1294 self.mapType = mapType 1295 self.select.SetValue('') 1296 self.mapType = mapType 1297 1298 def OnBorder(self, event): 1299 """Enables/disable the part relating to border of map frame""" 1300 for each in (self.borderColorText, self.borderWidthText, 1301 self.borderColourPicker, self.borderWidthCtrl): 1302 each.Enable(self.borderCheck.GetValue()) 1303 1304 def getId(self): 1305 """Returns id of raster map""" 1306 return self.id 1307 1308 def update(self): 1309 """Save changes""" 1310 mapFrameDict = dict(self.mapFrameDict) 1311 # resolution 1312 mapFrameDict['resolution'] = self.resolutionSpin.GetValue() 1313 # scale 1314 scaleType = self.scaleType 1315 mapFrameDict['scaleType'] = scaleType 1316 1317 if mapFrameDict['scaleType'] == 0: 1318 if self.select.GetValue(): 1319 mapFrameDict['drawMap'] = self.drawMap.GetValue() 1320 mapFrameDict['map'] = self.select.GetValue() 1321 mapFrameDict['mapType'] = self.mapType 1322 mapFrameDict['region'] = None 1323 1324 if mapFrameDict['drawMap']: 1325 1326 if mapFrameDict['mapType'] == 'raster': 1327 mapFile = grass.find_file( 1328 mapFrameDict['map'], 1329 element='cell') 1330 if mapFile['file'] == '': 1331 GMessage( 1332 "Raster %s not found" % 1333 mapFrameDict['map']) 1334 return False 1335 raster = self.instruction.FindInstructionByType( 1336 'raster') 1337 if raster: 1338 raster['raster'] = mapFrameDict['map'] 1339 else: 1340 raster = Raster(NewId(), env=self.env) 1341 raster['raster'] = mapFrameDict['map'] 1342 raster['isRaster'] = True 1343 self.instruction.AddInstruction(raster) 1344 1345 elif mapFrameDict['mapType'] == 'vector': 1346 1347 mapFile = grass.find_file( 1348 mapFrameDict['map'], 1349 element='vector') 1350 if mapFile['file'] == '': 1351 GMessage( 1352 "Vector %s not found" % 1353 mapFrameDict['map']) 1354 return False 1355 1356 vector = self.instruction.FindInstructionByType( 1357 'vector') 1358 isAdded = False 1359 if vector: 1360 for each in vector['list']: 1361 if each[0] == mapFrameDict['map']: 1362 isAdded = True 1363 if not isAdded: 1364 topoInfo = grass.vector_info_topo( 1365 map=mapFrameDict['map']) 1366 if topoInfo: 1367 if bool(topoInfo['areas']): 1368 topoType = 'areas' 1369 elif bool(topoInfo['lines']): 1370 topoType = 'lines' 1371 else: 1372 topoType = 'points' 1373 label = '('.join( 1374 mapFrameDict['map'].split('@')) + ')' 1375 1376 if not vector: 1377 vector = Vector(NewId(), env=self.env) 1378 vector['list'] = [] 1379 self.instruction.AddInstruction(vector) 1380 id = NewId() 1381 vector['list'].insert( 1382 0, [mapFrameDict['map'], topoType, id, 1, label]) 1383 vProp = VProperties(id, topoType, env=self.env) 1384 vProp['name'], vProp['label'], vProp[ 1385 'lpos'] = mapFrameDict['map'], label, 1 1386 self.instruction.AddInstruction(vProp) 1387 else: 1388 return False 1389 1390 self.scale[0], self.center[0], self.rectAdjusted = AutoAdjust( 1391 self, scaleType=0, map=mapFrameDict['map'], env=self.env, 1392 mapType=self.mapType, rect=self.mapFrameDict['rect']) 1393 1394 if self.rectAdjusted: 1395 mapFrameDict['rect'] = self.rectAdjusted 1396 else: 1397 mapFrameDict['rect'] = self.mapFrameDict['rect'] 1398 1399 mapFrameDict['scale'] = self.scale[0] 1400 1401 mapFrameDict['center'] = self.center[0] 1402 # set region 1403 if self.mapType == 'raster': 1404 self.env['GRASS_REGION'] = grass.region_env(raster=mapFrameDict['map'], 1405 env=self.env) 1406 if self.mapType == 'vector': 1407 raster = self.instruction.FindInstructionByType('raster') 1408 if raster: 1409 rasterId = raster.id 1410 else: 1411 rasterId = None 1412 1413 if rasterId: 1414 self.env['GRASS_REGION'] = grass.region_env(vector=mapFrameDict['map'], 1415 raster=self.instruction[rasterId]['raster'], 1416 env=self.env) 1417 else: 1418 self.env['GRASS_REGION'] = grass.region_env(vector=mapFrameDict['map'], 1419 env=self.env) 1420 1421 else: 1422 wx.MessageBox( 1423 message=_("No map selected!"), 1424 caption=_('Invalid input'), 1425 style=wx.OK | wx.ICON_ERROR) 1426 return False 1427 1428 elif mapFrameDict['scaleType'] == 1: 1429 if self.select.GetValue(): 1430 mapFrameDict['drawMap'] = False 1431 mapFrameDict['map'] = None 1432 mapFrameDict['mapType'] = None 1433 mapFrameDict['region'] = self.select.GetValue() 1434 self.scale[1], self.center[1], self.rectAdjusted = AutoAdjust( 1435 self, scaleType=1, region=mapFrameDict['region'], 1436 rect=self.mapFrameDict['rect'], env=self.env) 1437 if self.rectAdjusted: 1438 mapFrameDict['rect'] = self.rectAdjusted 1439 else: 1440 mapFrameDict['rect'] = self.mapFrameDict['rect'] 1441 1442 mapFrameDict['scale'] = self.scale[1] 1443 mapFrameDict['center'] = self.center[1] 1444 # set region 1445 self.env['GRASS_REGION'] = grass.region_env(region=mapFrameDict['region'], 1446 env=self.env) 1447 else: 1448 wx.MessageBox( 1449 message=_("No region selected!"), 1450 caption=_('Invalid input'), 1451 style=wx.OK | wx.ICON_ERROR) 1452 return False 1453 1454 elif scaleType == 2: 1455 mapFrameDict['drawMap'] = False 1456 mapFrameDict['map'] = None 1457 mapFrameDict['mapType'] = None 1458 mapFrameDict['region'] = None 1459 self.scale[2], self.center[2], self.rectAdjusted = AutoAdjust( 1460 self, scaleType=2, rect=self.mapFrameDict['rect'], env=self.env) 1461 if self.rectAdjusted: 1462 mapFrameDict['rect'] = self.rectAdjusted 1463 else: 1464 mapFrameDict['rect'] = self.mapFrameDict['rect'] 1465 1466 mapFrameDict['scale'] = self.scale[2] 1467 mapFrameDict['center'] = self.center[2] 1468 region = grass.region(env=None) 1469 1470 raster = self.instruction.FindInstructionByType('raster') 1471 if raster: 1472 rasterId = raster.id 1473 else: 1474 rasterId = None 1475 1476 if rasterId: # because of resolution 1477 self.env['GRASS_REGION'] = grass.region_env(n=region['n'], s=region['s'], 1478 e=region['e'], w=region['w'], 1479 raster=self.instruction[rasterId]['raster'], 1480 env=self.env) 1481 else: 1482 self.env['GRASS_REGION'] = grass.region_env(n=region['n'], s=region['s'], 1483 e=region['e'], w=region['w'], 1484 env=self.env) 1485 1486 elif scaleType == 3: 1487 mapFrameDict['drawMap'] = False 1488 mapFrameDict['map'] = None 1489 mapFrameDict['mapType'] = None 1490 mapFrameDict['region'] = None 1491 mapFrameDict['rect'] = self.mapFrameDict['rect'] 1492 try: 1493 scaleNumber = float(self.scaleTextCtrl.GetValue()) 1494 centerE = float(self.eastingTextCtrl.GetValue()) 1495 centerN = float(self.northingTextCtrl.GetValue()) 1496 except (ValueError, SyntaxError): 1497 wx.MessageBox( 1498 message=_("Invalid scale or map center!"), 1499 caption=_('Invalid input'), 1500 style=wx.OK | wx.ICON_ERROR) 1501 return False 1502 mapFrameDict['scale'] = 1 / scaleNumber 1503 mapFrameDict['center'] = centerE, centerN 1504 1505 ComputeSetRegion(self, mapDict=mapFrameDict, env=self.env) 1506 1507 # check resolution 1508 SetResolution( 1509 dpi=mapFrameDict['resolution'], 1510 width=mapFrameDict['rect'].width, 1511 height=mapFrameDict['rect'].height, 1512 env=self.env) 1513 # border 1514 if self.borderCheck.GetValue(): 1515 mapFrameDict['border'] = 'y' 1516 else: 1517 mapFrameDict['border'] = 'n' 1518 1519 if mapFrameDict['border'] == 'y': 1520 mapFrameDict['width'] = self.borderWidthCtrl.GetValue() 1521 mapFrameDict['color'] = convertRGB( 1522 self.borderColourPicker.GetColour()) 1523 1524 if self.id not in self.instruction: 1525 mapFrame = MapFrame(self.id, env=self.env) 1526 self.instruction.AddInstruction(mapFrame) 1527 self.instruction[self.id].SetInstruction(mapFrameDict) 1528 1529 if self.id not in self.mapDialog.parent.objectId: 1530 self.mapDialog.parent.objectId.insert( 1531 0, self.id) # map frame is drawn first 1532 return True 1533 1534 1535class RasterPanel(Panel): 1536 """Panel for raster map settings""" 1537 1538 def __init__(self, parent, id, settings, env, notebook=True): 1539 Panel.__init__(self, parent, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL) 1540 self.instruction = settings 1541 self.env = env 1542 1543 if notebook: 1544 self.book = parent 1545 self.book.AddPage(page=self, text=_("Raster map")) 1546 self.mainDialog = self.book.GetParent() 1547 else: 1548 self.mainDialog = parent 1549 if id: 1550 self.id = id 1551 self.rasterDict = self.instruction[self.id].GetInstruction() 1552 else: 1553 self.id = NewId() 1554 raster = Raster(self.id, env=self.env) 1555 self.rasterDict = raster.GetInstruction() 1556 1557 self._layout() 1558 self.OnRaster(None) 1559 1560 def _layout(self): 1561 """Do layout""" 1562 border = wx.BoxSizer(wx.VERTICAL) 1563 1564 # choose raster map 1565 1566 box = StaticBox( 1567 parent=self, 1568 id=wx.ID_ANY, 1569 label=" %s " % 1570 _("Choose raster map")) 1571 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 1572 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 1573 1574 self.rasterNoRadio = RadioButton( 1575 self, id=wx.ID_ANY, label=_("no raster map"), 1576 style=wx.RB_GROUP) 1577 self.rasterYesRadio = RadioButton( 1578 self, id=wx.ID_ANY, label=_("raster:")) 1579 1580 self.rasterSelect = Select( 1581 self, 1582 id=wx.ID_ANY, 1583 size=globalvar.DIALOG_GSELECT_SIZE, 1584 type='raster', 1585 multiple=False, 1586 updateOnPopup=True, 1587 onPopup=None) 1588 if self.rasterDict['isRaster']: 1589 self.rasterYesRadio.SetValue(True) 1590 self.rasterNoRadio.SetValue(False) 1591 self.rasterSelect.SetValue(self.rasterDict['raster']) 1592 else: 1593 self.rasterYesRadio.SetValue(False) 1594 self.rasterNoRadio.SetValue(True) 1595 mapId = self.instruction.FindInstructionByType('map').id 1596 1597 if self.instruction[mapId]['map'] and self.instruction[ 1598 mapId]['mapType'] == 'raster': 1599 # raster map from map frame dialog if possible 1600 self.rasterSelect.SetValue(self.instruction[mapId]['map']) 1601 else: 1602 self.rasterSelect.SetValue('') 1603 gridBagSizer.Add( 1604 self.rasterNoRadio, pos=( 1605 0, 0), span=( 1606 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 1607 gridBagSizer.Add( 1608 self.rasterYesRadio, pos=(1, 0), 1609 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 1610 gridBagSizer.Add( 1611 self.rasterSelect, 1612 pos=( 1613 1, 1614 1), 1615 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1616 border=0) 1617 1618 sizer.Add( 1619 gridBagSizer, 1620 proportion=1, 1621 flag=wx.EXPAND | wx.ALL, 1622 border=5) 1623 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 1624 1625 #self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster) 1626 self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterNoRadio) 1627 self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterYesRadio) 1628 1629 self.SetSizer(border) 1630 self.Fit() 1631 1632 def OnRaster(self, event): 1633 """Enable/disable raster selection""" 1634 self.rasterSelect.Enable(self.rasterYesRadio.GetValue()) 1635 1636 def update(self): 1637 # draw raster 1638 mapInstr = self.instruction.FindInstructionByType('map') 1639 if not mapInstr: # no map frame 1640 GMessage(message=_("Please, create map frame first.")) 1641 return 1642 1643 if self.rasterNoRadio.GetValue() or not self.rasterSelect.GetValue(): 1644 self.rasterDict['isRaster'] = False 1645 self.rasterDict['raster'] = None 1646 mapInstr['drawMap'] = False 1647 if self.id in self.instruction: 1648 del self.instruction[self.id] 1649 1650 else: 1651 self.rasterDict['isRaster'] = True 1652 self.rasterDict['raster'] = self.rasterSelect.GetValue() 1653 if self.rasterDict['raster'] != mapInstr['drawMap']: 1654 mapInstr['drawMap'] = False 1655 1656 raster = self.instruction.FindInstructionByType('raster') 1657 if not raster: 1658 raster = Raster(self.id, env=self.env) 1659 self.instruction.AddInstruction(raster) 1660 self.instruction[self.id].SetInstruction(self.rasterDict) 1661 else: 1662 self.instruction[raster.id].SetInstruction(self.rasterDict) 1663 1664 if 'map' in self.mainDialog.parent.openDialogs: 1665 self.mainDialog.parent.openDialogs['map'].updateDialog() 1666 return True 1667 1668 def getId(self): 1669 return self.id 1670 1671 1672class VectorPanel(Panel): 1673 """Panel for vector maps settings""" 1674 1675 def __init__(self, parent, id, settings, env, notebook=True): 1676 Panel.__init__(self, parent, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL) 1677 1678 self.parent = parent 1679 self.env = env 1680 self.instruction = settings 1681 self.tmpDialogDict = {} 1682 vectors = self.instruction.FindInstructionByType( 1683 'vProperties', list=True) 1684 for vector in vectors: 1685 self.tmpDialogDict[vector.id] = dict( 1686 self.instruction[vector.id].GetInstruction()) 1687 1688 if id: 1689 self.id = id 1690 self.vectorList = deepcopy(self.instruction[id]['list']) 1691 else: 1692 self.id = NewId() 1693 self.vectorList = [] 1694 1695 vLegend = self.instruction.FindInstructionByType('vectorLegend') 1696 if vLegend: 1697 self.vLegendId = vLegend.id 1698 else: 1699 self.vLegendId = None 1700 1701 self._layout() 1702 1703 if notebook: 1704 self.parent.AddPage(page=self, text=_("Vector maps")) 1705 self.parent = self.parent.GetParent() 1706 1707 def _layout(self): 1708 """Do layout""" 1709 border = wx.BoxSizer(wx.VERTICAL) 1710 1711 # choose vector map 1712 1713 box = StaticBox( 1714 parent=self, 1715 id=wx.ID_ANY, 1716 label=" %s " % 1717 _("Add map")) 1718 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 1719 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 1720 1721 text = StaticText(self, id=wx.ID_ANY, label=_("Map:")) 1722 self.select = Select(self, id=wx.ID_ANY, # size = globalvar.DIALOG_GSELECT_SIZE, 1723 type='vector', multiple=False, 1724 updateOnPopup=True, onPopup=None) 1725 topologyTypeTr = [_("points"), _("lines"), _("areas")] 1726 self.topologyTypeList = ["points", "lines", "areas"] 1727 self.vectorType = wx.RadioBox( 1728 self, 1729 id=wx.ID_ANY, 1730 label=" %s " % 1731 _("Data Type"), 1732 choices=topologyTypeTr, 1733 majorDimension=3, 1734 style=wx.RA_SPECIFY_COLS) 1735 1736 self.AddVector = Button(self, id=wx.ID_ANY, label=_("Add")) 1737 1738 gridBagSizer.Add( 1739 text, pos=(0, 0), 1740 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 1741 gridBagSizer.Add( 1742 self.select, pos=( 1743 0, 1), span=( 1744 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 1745 gridBagSizer.Add( 1746 self.vectorType, pos=(1, 1), 1747 flag=wx.ALIGN_CENTER, border=0) 1748 gridBagSizer.Add( 1749 self.AddVector, pos=(1, 2), 1750 flag=wx.ALIGN_BOTTOM | wx.ALIGN_RIGHT, border=0) 1751 1752 sizer.Add( 1753 gridBagSizer, 1754 proportion=1, 1755 flag=wx.EXPAND | wx.ALL, 1756 border=5) 1757 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 1758 1759 # manage vector layers 1760 1761 box = StaticBox( 1762 parent=self, 1763 id=wx.ID_ANY, 1764 label=" %s " % 1765 _("Manage vector maps")) 1766 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 1767 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 1768 1769 text = StaticText(self, id=wx.ID_ANY, label=_( 1770 "The topmost vector map overlaps the others")) 1771 self.listbox = ListBox( 1772 self, id=wx.ID_ANY, choices=[], 1773 style=wx.LB_SINGLE | wx.LB_NEEDED_SB) 1774 self.btnUp = Button(self, id=wx.ID_ANY, label=_("Up")) 1775 self.btnDown = Button(self, id=wx.ID_ANY, label=_("Down")) 1776 self.btnDel = Button(self, id=wx.ID_ANY, label=_("Delete")) 1777 self.btnProp = Button(self, id=wx.ID_ANY, label=_("Properties...")) 1778 1779 self.updateListBox(selected=0) 1780 1781 gridBagSizer.Add( 1782 text, pos=(0, 0), 1783 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 1784 gridBagSizer.Add( 1785 self.listbox, pos=( 1786 1, 0), span=( 1787 4, 1), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 1788 gridBagSizer.Add( 1789 self.btnUp, 1790 pos=( 1791 1, 1792 1), 1793 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1794 border=0) 1795 gridBagSizer.Add( 1796 self.btnDown, 1797 pos=( 1798 2, 1799 1), 1800 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1801 border=0) 1802 gridBagSizer.Add( 1803 self.btnDel, 1804 pos=( 1805 3, 1806 1), 1807 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1808 border=0) 1809 gridBagSizer.Add( 1810 self.btnProp, 1811 pos=( 1812 4, 1813 1), 1814 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 1815 border=0) 1816 1817 gridBagSizer.AddGrowableCol(0, 2) 1818 gridBagSizer.AddGrowableCol(1, 1) 1819 sizer.Add(gridBagSizer, proportion=0, flag=wx.ALL, border=5) 1820 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 1821 1822 self.Bind(wx.EVT_BUTTON, self.OnAddVector, self.AddVector) 1823 self.Bind(wx.EVT_BUTTON, self.OnDelete, self.btnDel) 1824 self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp) 1825 self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown) 1826 self.Bind(wx.EVT_BUTTON, self.OnProperties, self.btnProp) 1827 self.select.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnVector) 1828 1829 self.SetSizer(border) 1830 self.Fit() 1831 1832 self.Bind(wx.EVT_LISTBOX_DCLICK, self.OnProperties, self.listbox) 1833 1834 def OnVector(self, event): 1835 """Gets info about toplogy and enables/disables choices point/line/area""" 1836 vmap = self.select.GetValue() 1837 try: 1838 topoInfo = grass.vector_info_topo(map=vmap) 1839 except grass.ScriptError: 1840 return 1841 1842 if topoInfo: 1843 self.vectorType.EnableItem(2, bool(topoInfo['areas'])) 1844 self.vectorType.EnableItem( 1845 1, bool( 1846 topoInfo['boundaries']) or bool( 1847 topoInfo['lines'])) 1848 self.vectorType.EnableItem( 1849 0, bool( 1850 topoInfo['centroids'] or bool( 1851 topoInfo['points']))) 1852 for item in range(2, -1, -1): 1853 if self.vectorType.IsItemEnabled(item): 1854 self.vectorType.SetSelection(item) 1855 break 1856 1857 self.AddVector.SetFocus() 1858 1859 def OnAddVector(self, event): 1860 """Adds vector map to list""" 1861 vmap = self.select.GetValue() 1862 if vmap: 1863 mapname = vmap.split('@')[0] 1864 try: 1865 mapset = '(' + vmap.split('@')[1] + ')' 1866 except IndexError: 1867 mapset = '' 1868 idx = self.vectorType.GetSelection() 1869 ttype = self.topologyTypeList[idx] 1870 record = "%s - %s" % (vmap, ttype) 1871 id = NewId() 1872 lpos = 1 1873 label = mapname + mapset 1874 self.vectorList.insert(0, [vmap, ttype, id, lpos, label]) 1875 self.reposition() 1876 self.listbox.InsertItems([record], 0) 1877 1878 vector = VProperties(id, ttype, env=self.env) 1879 self.tmpDialogDict[id] = vector.GetInstruction() 1880 self.tmpDialogDict[id]['name'] = vmap 1881 1882 self.listbox.SetSelection(0) 1883 self.listbox.EnsureVisible(0) 1884 self.btnProp.SetFocus() 1885 self.enableButtons() 1886 1887 def OnDelete(self, event): 1888 """Deletes vector map from the list""" 1889 if self.listbox.GetSelections(): 1890 pos = self.listbox.GetSelection() 1891 id = self.vectorList[pos][2] 1892 del self.vectorList[pos] 1893 del self.tmpDialogDict[id] 1894 1895 for i in range(pos, len(self.vectorList)): 1896 if self.vectorList[i][3]: # can be 0 1897 self.vectorList[i][3] -= 1 1898 1899 if pos < len(self.vectorList) - 1: 1900 selected = pos 1901 else: 1902 selected = len(self.vectorList) - 1 1903 self.updateListBox(selected=selected) 1904 if self.listbox.IsEmpty(): 1905 self.enableButtons(False) 1906 1907 def OnUp(self, event): 1908 """Moves selected map to top""" 1909 if self.listbox.GetSelections(): 1910 pos = self.listbox.GetSelection() 1911 if pos: 1912 self.vectorList.insert(pos - 1, self.vectorList.pop(pos)) 1913 if not self.vLegendId: 1914 self.reposition() 1915 1916 if pos > 0: 1917 self.updateListBox(selected=(pos - 1)) 1918 else: 1919 self.updateListBox(selected=0) 1920 1921 def OnDown(self, event): 1922 """Moves selected map to bottom""" 1923 if self.listbox.GetSelections(): 1924 pos = self.listbox.GetSelection() 1925 if pos != len(self.vectorList) - 1: 1926 self.vectorList.insert(pos + 1, self.vectorList.pop(pos)) 1927 if not self.vLegendId: 1928 self.reposition() 1929 if pos < len(self.vectorList) - 1: 1930 self.updateListBox(selected=(pos + 1)) 1931 else: 1932 self.updateListBox(selected=len(self.vectorList) - 1) 1933 1934 def OnProperties(self, event): 1935 """Opens vector map properties dialog""" 1936 if self.listbox.GetSelections(): 1937 pos = self.listbox.GetSelection() 1938 id = self.vectorList[pos][2] 1939 1940 dlg = VPropertiesDialog( 1941 self, 1942 id=id, 1943 settings=self.instruction, 1944 env=self.env, 1945 vectors=self.vectorList, 1946 tmpSettings=self.tmpDialogDict[id]) 1947 dlg.ShowModal() 1948 1949 self.parent.FindWindowById(wx.ID_OK).SetFocus() 1950 1951 def enableButtons(self, enable=True): 1952 """Enable/disable up, down, properties, delete buttons""" 1953 self.btnUp.Enable(enable) 1954 self.btnDown.Enable(enable) 1955 self.btnProp.Enable(enable) 1956 self.btnDel.Enable(enable) 1957 1958 def updateListBox(self, selected=None): 1959 mapList = ["%s - %s" % (item[0], item[1]) for item in self.vectorList] 1960 self.listbox.Set(mapList) 1961 if self.listbox.IsEmpty(): 1962 self.enableButtons(False) 1963 else: 1964 self.enableButtons(True) 1965 if selected is not None: 1966 self.listbox.SetSelection(selected) 1967 self.listbox.EnsureVisible(selected) 1968 1969 def reposition(self): 1970 """Update position in legend, used only if there is no vlegend yet""" 1971 for i in range(len(self.vectorList)): 1972 if self.vectorList[i][3]: 1973 self.vectorList[i][3] = i + 1 1974 1975 def getId(self): 1976 return self.id 1977 1978 def update(self): 1979 vectors = self.instruction.FindInstructionByType( 1980 'vProperties', list=True) 1981 1982 for vector in vectors: 1983 del self.instruction[vector.id] 1984 if self.id in self.instruction: 1985 del self.instruction[self.id] 1986 1987 if len(self.vectorList) > 0: 1988 vector = Vector(self.id, env=self.env) 1989 self.instruction.AddInstruction(vector) 1990 1991 vector.SetInstruction({'list': deepcopy(self.vectorList)}) 1992 1993 # save new vectors 1994 for item in self.vectorList: 1995 id = item[2] 1996 1997 vLayer = VProperties(id, item[1], env=self.env) 1998 self.instruction.AddInstruction(vLayer) 1999 vLayer.SetInstruction(self.tmpDialogDict[id]) 2000 vLayer['name'] = item[0] 2001 vLayer['label'] = item[4] 2002 vLayer['lpos'] = item[3] 2003 2004 else: 2005 if self.id in self.instruction: 2006 del self.instruction[self.id] 2007 2008 if 'map' in self.parent.parent.openDialogs: 2009 self.parent.parent.openDialogs['map'].updateDialog() 2010 2011 return True 2012 2013 2014class RasterDialog(PsmapDialog): 2015 2016 def __init__(self, parent, id, settings, env): 2017 PsmapDialog.__init__( 2018 self, 2019 parent=parent, 2020 id=id, 2021 title=_("Raster map settings"), 2022 settings=settings, 2023 env=env) 2024 self.objectType = ('raster',) 2025 2026 self.rPanel = RasterPanel( 2027 parent=self, 2028 id=self.id, 2029 settings=self.instruction, 2030 notebook=False, 2031 env=self.env) 2032 2033 self.id = self.rPanel.getId() 2034 self._layout(self.rPanel) 2035 2036 def update(self): 2037 ok = self.rPanel.update() 2038 if ok: 2039 return True 2040 return False 2041 2042 def OnApply(self, event): 2043 ok = self.update() 2044 if not ok: 2045 return False 2046 2047 if self.id in self.instruction: 2048 self.parent.DialogDataChanged(id=self.id) 2049 else: 2050 mapId = self.instruction.FindInstructionByType('map').id 2051 self.parent.DialogDataChanged(id=mapId) 2052 return True 2053 2054 def updateDialog(self): 2055 """Update information (not used)""" 2056 pass 2057# if 'map' in self.parent.openDialogs: 2058# if self.parent.openDialogs['map'].mPanel.rasterTypeRadio.GetValue()\ 2059# and self.parent.openDialogs['map'].mPanel.select.GetValue(): 2060# if self.parent.openDialogs['map'].mPanel.drawMap.IsChecked(): 2061# self.rPanel.rasterSelect.SetValue(self.parent.openDialogs['map'].mPanel.select.GetValue()) 2062 2063 2064class MainVectorDialog(PsmapDialog): 2065 2066 def __init__(self, parent, id, settings, env): 2067 PsmapDialog.__init__( 2068 self, 2069 parent=parent, 2070 id=id, 2071 title=_("Vector maps settings"), 2072 settings=settings, 2073 env=env) 2074 self.objectType = ('vector',) 2075 self.vPanel = VectorPanel( 2076 parent=self, 2077 id=self.id, 2078 settings=self.instruction, 2079 env=env, 2080 notebook=False) 2081 2082 self.id = self.vPanel.getId() 2083 self._layout(self.vPanel) 2084 2085 def update(self): 2086 self.vPanel.update() 2087 2088 def OnApply(self, event): 2089 self.update() 2090 if self.id in self.instruction: 2091 self.parent.DialogDataChanged(id=self.id) 2092 else: 2093 mapId = self.instruction.FindInstructionByType('map').id 2094 self.parent.DialogDataChanged(id=mapId) 2095 return True 2096 2097 def updateDialog(self): 2098 """Update information (not used)""" 2099 pass 2100 2101 2102class VPropertiesDialog(PsmapDialog): 2103 2104 def __init__(self, parent, id, settings, vectors, tmpSettings, env): 2105 PsmapDialog.__init__( 2106 self, 2107 parent=parent, 2108 id=id, 2109 title="", 2110 settings=settings, 2111 env=env, 2112 apply=False) 2113 2114 vectorList = vectors 2115 self.vPropertiesDict = tmpSettings 2116 2117 # determine map and its type 2118 for item in vectorList: 2119 if id == item[2]: 2120 self.vectorName = item[0] 2121 self.type = item[1] 2122 self.SetTitle(_("%s properties") % self.vectorName) 2123 2124 # vector map info 2125 self.connection = True 2126 try: 2127 self.mapDBInfo = VectorDBInfo(self.vectorName) 2128 self.layers = self.mapDBInfo.layers.keys() 2129 except grass.ScriptError: 2130 self.connection = False 2131 self.layers = [] 2132 if not self.layers: 2133 self.connection = False 2134 self.layers = [] 2135 2136 self.currLayer = self.vPropertiesDict['layer'] 2137 2138 # path to symbols, patterns 2139 gisbase = os.getenv("GISBASE") 2140 self.symbolPath = os.path.join(gisbase, 'etc', 'symbol') 2141 self.symbols = [] 2142 for dir in os.listdir(self.symbolPath): 2143 for symbol in os.listdir(os.path.join(self.symbolPath, dir)): 2144 self.symbols.append(os.path.join(dir, symbol)) 2145 self.patternPath = os.path.join(gisbase, 'etc', 'paint', 'patterns') 2146 2147 # notebook 2148 notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT) 2149 self.DSpanel = self._DataSelectionPanel(notebook) 2150 self.EnableLayerSelection(enable=self.connection) 2151 selectPanel = { 2152 'points': [ 2153 self._ColorsPointAreaPanel, self._StylePointPanel], 'lines': [ 2154 self._ColorsLinePanel, self._StyleLinePanel], 'areas': [ 2155 self._ColorsPointAreaPanel, self._StyleAreaPanel]} 2156 self.ColorsPanel = selectPanel[self.type][0](notebook) 2157 2158 self.OnOutline(None) 2159 if self.type in ('points', 'areas'): 2160 self.OnFill(None) 2161 self.OnColor(None) 2162 2163 self.StylePanel = selectPanel[self.type][1](notebook) 2164 if self.type == 'points': 2165 self.OnSize(None) 2166 self.OnRotation(None) 2167 self.OnSymbology(None) 2168 if self.type == 'areas': 2169 self.OnPattern(None) 2170 2171 self._layout(notebook) 2172 2173 def _DataSelectionPanel(self, notebook): 2174 panel = Panel( 2175 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 2176 style=wx.TAB_TRAVERSAL) 2177 notebook.AddPage(page=panel, text=_("Data selection")) 2178 2179 border = wx.BoxSizer(wx.VERTICAL) 2180 2181 # data type 2182 self.checkType1 = self.checkType2 = None 2183 if self.type in ('lines', 'points'): 2184 box = StaticBox( 2185 parent=panel, 2186 id=wx.ID_ANY, 2187 label=" %s " % 2188 _("Feature type")) 2189 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2190 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 2191 if self.type == 'points': 2192 label = (_("points"), _("centroids")) 2193 else: 2194 label = (_("lines"), _("boundaries")) 2195 if self.type == 'points': 2196 name = ("point", "centroid") 2197 else: 2198 name = ("line", "boundary") 2199 self.checkType1 = CheckBox( 2200 panel, id=wx.ID_ANY, label=label[0], name=name[0]) 2201 self.checkType2 = CheckBox( 2202 panel, id=wx.ID_ANY, label=label[1], name=name[1]) 2203 self.checkType1.SetValue( 2204 self.vPropertiesDict['type'].find( 2205 name[0]) >= 0) 2206 self.checkType2.SetValue( 2207 self.vPropertiesDict['type'].find( 2208 name[1]) >= 0) 2209 2210 gridBagSizer.Add( 2211 self.checkType1, pos=(0, 0), 2212 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2213 gridBagSizer.Add( 2214 self.checkType2, pos=(0, 1), 2215 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2216 sizer.Add( 2217 gridBagSizer, 2218 proportion=1, 2219 flag=wx.EXPAND | wx.ALL, 2220 border=5) 2221 border.Add( 2222 sizer, 2223 proportion=0, 2224 flag=wx.ALL | wx.EXPAND, 2225 border=5) 2226 2227 # layer selection 2228 box = StaticBox( 2229 parent=panel, 2230 id=wx.ID_ANY, 2231 label=" %s " % 2232 _("Layer selection")) 2233 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2234 self.gridBagSizerL = wx.GridBagSizer(hgap=5, vgap=5) 2235 2236 self.warning = StaticText(panel, id=wx.ID_ANY, label="") 2237 if not self.connection: 2238 self.warning = StaticText(panel, id=wx.ID_ANY, label=_( 2239 "Database connection is not defined in DB file.")) 2240 text = StaticText(panel, id=wx.ID_ANY, label=_("Select layer:")) 2241 self.layerChoice = Choice( 2242 panel, id=wx.ID_ANY, choices=[str(each) for each in self.layers], 2243 size=self.spinCtrlSize) 2244 2245 self.layerChoice.SetStringSelection(self.currLayer) 2246 2247 if self.connection: 2248 table = self.mapDBInfo.layers[int(self.currLayer)]['table'] 2249 else: 2250 table = "" 2251 2252 self.radioWhere = RadioButton( 2253 panel, id=wx.ID_ANY, label="SELECT * FROM %s WHERE" % 2254 table, style=wx.RB_GROUP) 2255 self.textCtrlWhere = TextCtrl(panel, id=wx.ID_ANY, value="") 2256 2257 if self.connection: 2258 cols = self.mapDBInfo.GetColumns( 2259 self.mapDBInfo.layers[int(self.currLayer)]['table']) 2260 else: 2261 cols = [] 2262 2263 self.choiceColumns = Choice(panel, id=wx.ID_ANY, choices=cols) 2264 2265 self.radioCats = RadioButton( 2266 panel, id=wx.ID_ANY, label="Choose categories ") 2267 self.textCtrlCats = TextCtrl(panel, id=wx.ID_ANY, value="") 2268 self.textCtrlCats.SetToolTip( 2269 _("list of categories (e.g. 1,3,5-7)")) 2270 2271 if 'cats' in self.vPropertiesDict: 2272 self.radioCats.SetValue(True) 2273 self.textCtrlCats.SetValue(self.vPropertiesDict['cats']) 2274 if 'where' in self.vPropertiesDict: 2275 self.radioWhere.SetValue(True) 2276 where = self.vPropertiesDict['where'].strip().split(" ", 1) 2277 self.choiceColumns.SetStringSelection(where[0]) 2278 self.textCtrlWhere.SetValue(where[1]) 2279 2280 row = 0 2281 if not self.connection: 2282 self.gridBagSizerL.Add( 2283 self.warning, pos=( 2284 0, 0), span=( 2285 1, 3), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2286 row = 1 2287 self.gridBagSizerL.Add( 2288 text, pos=(0 + row, 0), 2289 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2290 self.gridBagSizerL.Add( 2291 self.layerChoice, pos=(0 + row, 1), 2292 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 2293 self.gridBagSizerL.Add( 2294 self.radioWhere, pos=(1 + row, 0), 2295 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2296 self.gridBagSizerL.Add( 2297 self.choiceColumns, pos=(1 + row, 1), 2298 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2299 self.gridBagSizerL.Add( 2300 self.textCtrlWhere, pos=(1 + row, 2), 2301 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2302 self.gridBagSizerL.Add( 2303 self.radioCats, pos=(2 + row, 0), 2304 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2305 self.gridBagSizerL.Add( 2306 self.textCtrlCats, pos=(2 + row, 1), 2307 span=(1, 2), 2308 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 2309 2310 sizer.Add( 2311 self.gridBagSizerL, 2312 proportion=1, 2313 flag=wx.EXPAND | wx.ALL, 2314 border=5) 2315 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2316 2317 # mask 2318 box = StaticBox( 2319 parent=panel, 2320 id=wx.ID_ANY, 2321 label=" %s " % 2322 _("Mask")) 2323 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2324 2325 self.mask = CheckBox( 2326 panel, id=wx.ID_ANY, label=_("Use current mask")) 2327 if self.vPropertiesDict['masked'] == 'y': 2328 self.mask.SetValue(True) 2329 else: 2330 self.mask.SetValue(False) 2331 2332 sizer.Add(self.mask, proportion=1, flag=wx.EXPAND | wx.ALL, border=5) 2333 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2334 2335 self.Bind(wx.EVT_CHOICE, self.OnLayer, self.layerChoice) 2336 2337 panel.SetSizer(border) 2338 panel.Fit() 2339 return panel 2340 2341 def _ColorsPointAreaPanel(self, notebook): 2342 panel = Panel( 2343 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 2344 style=wx.TAB_TRAVERSAL) 2345 notebook.AddPage(page=panel, text=_("Colors")) 2346 2347 border = wx.BoxSizer(wx.VERTICAL) 2348 2349 #colors - outline 2350 box = StaticBox( 2351 parent=panel, 2352 id=wx.ID_ANY, 2353 label=" %s " % 2354 _("Outline")) 2355 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2356 self.gridBagSizerO = wx.GridBagSizer(hgap=5, vgap=2) 2357 2358 self.outlineCheck = CheckBox( 2359 panel, id=wx.ID_ANY, label=_("draw outline")) 2360 self.outlineCheck.SetValue(self.vPropertiesDict['color'] != 'none') 2361 2362 widthText = StaticText(panel, id=wx.ID_ANY, label=_("Width (pts):")) 2363 2364 self.widthSpin = FloatSpin( 2365 panel, 2366 id=wx.ID_ANY, 2367 min_val=0, 2368 max_val=30, 2369 increment=0.5, 2370 value=1, 2371 style=fs.FS_RIGHT) 2372 self.widthSpin.SetFormat("%f") 2373 self.widthSpin.SetDigits(2) 2374 2375 if self.vPropertiesDict['color'] is None: 2376 self.vPropertiesDict['color'] = 'none' 2377 2378 if self.vPropertiesDict['color'] != 'none': 2379 self.widthSpin.SetValue(self.vPropertiesDict['width']) 2380 else: 2381 self.widthSpin.SetValue(1) 2382 2383 colorText = StaticText(panel, id=wx.ID_ANY, label=_("Color:")) 2384 self.colorPicker = ColourPickerCtrl(panel, id=wx.ID_ANY) 2385 if self.vPropertiesDict['color'] != 'none': 2386 self.colorPicker.SetColour( 2387 convertRGB(self.vPropertiesDict['color'])) 2388 else: 2389 self.colorPicker.SetColour(convertRGB('black')) 2390 2391 self.gridBagSizerO.Add( 2392 self.outlineCheck, pos=( 2393 0, 0), span=( 2394 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2395 self.gridBagSizerO.Add( 2396 widthText, pos=(1, 1), 2397 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2398 self.gridBagSizerO.Add( 2399 self.widthSpin, pos=(1, 2), 2400 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 2401 self.gridBagSizerO.Add( 2402 colorText, pos=(2, 1), 2403 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2404 self.gridBagSizerO.Add( 2405 self.colorPicker, pos=(2, 2), 2406 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2407 2408 sizer.Add( 2409 self.gridBagSizerO, 2410 proportion=1, 2411 flag=wx.EXPAND | wx.ALL, 2412 border=5) 2413 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2414 2415 self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck) 2416 2417 #colors - fill 2418 box = StaticBox( 2419 parent=panel, 2420 id=wx.ID_ANY, 2421 label=" %s " % 2422 _("Fill")) 2423 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2424 self.gridBagSizerF = wx.GridBagSizer(hgap=5, vgap=2) 2425 2426 self.fillCheck = CheckBox( 2427 panel, id=wx.ID_ANY, label=_("fill color")) 2428 self.fillCheck.SetValue( 2429 self.vPropertiesDict['fcolor'] != 2430 'none' or self.vPropertiesDict['rgbcolumn'] is not None) 2431 2432 self.colorPickerRadio = RadioButton( 2433 panel, id=wx.ID_ANY, label=_("choose color:"), style=wx.RB_GROUP) 2434 # set choose color option if there is no db connection 2435 if self.connection: 2436 self.colorPickerRadio.SetValue( 2437 not self.vPropertiesDict['rgbcolumn']) 2438 else: 2439 self.colorPickerRadio.SetValue(False) 2440 self.fillColorPicker = ColourPickerCtrl(panel, id=wx.ID_ANY) 2441 if self.vPropertiesDict['fcolor'] != 'none': 2442 self.fillColorPicker.SetColour( 2443 convertRGB(self.vPropertiesDict['fcolor'])) 2444 else: 2445 self.fillColorPicker.SetColour(convertRGB('red')) 2446 2447 self.colorColRadio = RadioButton( 2448 panel, id=wx.ID_ANY, label=_("color from map table column:")) 2449 self.colorColChoice = self.getColsChoice(parent=panel) 2450 if self.connection: 2451 if self.vPropertiesDict['rgbcolumn']: 2452 self.colorColRadio.SetValue(True) 2453 self.colorColChoice.SetStringSelection( 2454 self.vPropertiesDict['rgbcolumn']) 2455 else: 2456 self.colorColRadio.SetValue(False) 2457 self.colorColChoice.SetSelection(0) 2458 self.colorColChoice.Enable(self.connection) 2459 self.colorColRadio.Enable(self.connection) 2460 2461 self.gridBagSizerF.Add( 2462 self.fillCheck, pos=( 2463 0, 0), span=( 2464 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2465 self.gridBagSizerF.Add( 2466 self.colorPickerRadio, pos=(1, 1), 2467 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2468 self.gridBagSizerF.Add( 2469 self.fillColorPicker, pos=(1, 2), 2470 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2471 self.gridBagSizerF.Add( 2472 self.colorColRadio, pos=(2, 1), 2473 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2474 self.gridBagSizerF.Add( 2475 self.colorColChoice, pos=(2, 2), 2476 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 2477 2478 sizer.Add( 2479 self.gridBagSizerF, 2480 proportion=1, 2481 flag=wx.EXPAND | wx.ALL, 2482 border=5) 2483 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2484 2485 self.Bind(wx.EVT_CHECKBOX, self.OnFill, self.fillCheck) 2486 self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio) 2487 self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio) 2488 2489 panel.SetSizer(border) 2490 panel.Fit() 2491 return panel 2492 2493 def _ColorsLinePanel(self, notebook): 2494 panel = Panel( 2495 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 2496 style=wx.TAB_TRAVERSAL) 2497 notebook.AddPage(page=panel, text=_("Colors")) 2498 2499 border = wx.BoxSizer(wx.VERTICAL) 2500 2501 #colors - outline 2502 box = StaticBox( 2503 parent=panel, 2504 id=wx.ID_ANY, 2505 label=" %s " % 2506 _("Outline")) 2507 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2508 self.gridBagSizerO = wx.GridBagSizer(hgap=5, vgap=2) 2509 2510 if self.vPropertiesDict['hcolor'] is None: 2511 self.vPropertiesDict['hcolor'] = 'none' 2512 if self.vPropertiesDict['color'] is None: 2513 self.vPropertiesDict['color'] = 'none' 2514 2515 self.outlineCheck = CheckBox( 2516 panel, id=wx.ID_ANY, label=_("draw outline")) 2517 self.outlineCheck.SetValue(self.vPropertiesDict['hcolor'] != 'none') 2518 self.outlineCheck.SetToolTip( 2519 _("No effect for fill color from table column")) 2520 2521 widthText = StaticText(panel, id=wx.ID_ANY, label=_("Width (pts):")) 2522 2523 self.outWidthSpin = FloatSpin( 2524 panel, 2525 id=wx.ID_ANY, 2526 min_val=0, 2527 max_val=30, 2528 increment=0.5, 2529 value=1, 2530 style=fs.FS_RIGHT) 2531 self.outWidthSpin.SetFormat("%f") 2532 self.outWidthSpin.SetDigits(1) 2533 2534 if self.vPropertiesDict['hcolor'] != 'none': 2535 self.outWidthSpin.SetValue(self.vPropertiesDict['hwidth']) 2536 else: 2537 self.outWidthSpin.SetValue(1) 2538 2539 colorText = StaticText(panel, id=wx.ID_ANY, label=_("Color:")) 2540 self.colorPicker = ColourPickerCtrl(panel, id=wx.ID_ANY) 2541 if self.vPropertiesDict['hcolor'] != 'none': 2542 self.colorPicker.SetColour( 2543 convertRGB(self.vPropertiesDict['hcolor'])) 2544 else: 2545 self.colorPicker.SetColour(convertRGB('black')) 2546 2547 self.gridBagSizerO.Add( 2548 self.outlineCheck, pos=( 2549 0, 0), span=( 2550 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2551 self.gridBagSizerO.Add( 2552 widthText, pos=(1, 1), 2553 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2554 self.gridBagSizerO.Add( 2555 self.outWidthSpin, pos=(1, 2), 2556 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 2557 self.gridBagSizerO.Add( 2558 colorText, pos=(2, 1), 2559 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2560 self.gridBagSizerO.Add( 2561 self.colorPicker, pos=(2, 2), 2562 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2563 2564 sizer.Add( 2565 self.gridBagSizerO, 2566 proportion=1, 2567 flag=wx.EXPAND | wx.ALL, 2568 border=5) 2569 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2570 2571 self.Bind(wx.EVT_CHECKBOX, self.OnOutline, self.outlineCheck) 2572 2573 #colors - fill 2574 box = StaticBox( 2575 parent=panel, 2576 id=wx.ID_ANY, 2577 label=" %s " % 2578 _("Fill")) 2579 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2580 self.gridBagSizerF = wx.GridBagSizer(hgap=5, vgap=2) 2581 2582 fillText = StaticText( 2583 panel, id=wx.ID_ANY, label=_("Color of lines:")) 2584 2585 self.colorPickerRadio = RadioButton( 2586 panel, id=wx.ID_ANY, label=_("choose color:"), style=wx.RB_GROUP) 2587 2588 # set choose color option if there is no db connection 2589 if self.connection: 2590 self.colorPickerRadio.SetValue( 2591 not self.vPropertiesDict['rgbcolumn']) 2592 else: 2593 self.colorPickerRadio.SetValue(False) 2594 self.fillColorPicker = ColourPickerCtrl(panel, id=wx.ID_ANY) 2595 if self.vPropertiesDict['color'] != 'none': 2596 self.fillColorPicker.SetColour( 2597 convertRGB(self.vPropertiesDict['color'])) 2598 else: 2599 self.fillColorPicker.SetColour(convertRGB('black')) 2600 2601 self.colorColRadio = RadioButton( 2602 panel, id=wx.ID_ANY, label=_("color from map table column:")) 2603 self.colorColChoice = self.getColsChoice(parent=panel) 2604 if self.connection: 2605 if self.vPropertiesDict['rgbcolumn']: 2606 self.colorColRadio.SetValue(True) 2607 self.colorColChoice.SetStringSelection( 2608 self.vPropertiesDict['rgbcolumn']) 2609 else: 2610 self.colorColRadio.SetValue(False) 2611 self.colorColChoice.SetSelection(0) 2612 self.colorColChoice.Enable(self.connection) 2613 self.colorColRadio.Enable(self.connection) 2614 2615 self.gridBagSizerF.Add( 2616 fillText, pos=( 2617 0, 0), span=( 2618 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2619 self.gridBagSizerF.Add( 2620 self.colorPickerRadio, pos=(1, 1), 2621 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2622 self.gridBagSizerF.Add( 2623 self.fillColorPicker, pos=(1, 2), 2624 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2625 self.gridBagSizerF.Add( 2626 self.colorColRadio, pos=(2, 1), 2627 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2628 self.gridBagSizerF.Add( 2629 self.colorColChoice, pos=(2, 2), 2630 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 2631 2632 sizer.Add( 2633 self.gridBagSizerF, 2634 proportion=1, 2635 flag=wx.EXPAND | wx.ALL, 2636 border=5) 2637 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2638 2639 self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorColRadio) 2640 self.Bind(wx.EVT_RADIOBUTTON, self.OnColor, self.colorPickerRadio) 2641 2642 panel.SetSizer(border) 2643 panel.Fit() 2644 return panel 2645 2646 def _StylePointPanel(self, notebook): 2647 panel = Panel( 2648 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 2649 style=wx.TAB_TRAVERSAL) 2650 notebook.AddPage(page=panel, text=_("Size and style")) 2651 2652 border = wx.BoxSizer(wx.VERTICAL) 2653 2654 # symbology 2655 box = StaticBox( 2656 parent=panel, 2657 id=wx.ID_ANY, 2658 label=" %s " % 2659 _("Symbology")) 2660 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2661 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 2662 2663 self.symbolRadio = RadioButton( 2664 panel, id=wx.ID_ANY, label=_("symbol:"), 2665 style=wx.RB_GROUP) 2666 self.symbolRadio.SetValue(bool(self.vPropertiesDict['symbol'])) 2667 2668 self.symbolName = StaticText(panel, id=wx.ID_ANY) 2669 self.symbolName.SetLabel(self.vPropertiesDict['symbol']) 2670 bitmap = wx.Bitmap( 2671 os.path.join( 2672 globalvar.SYMBDIR, 2673 self.vPropertiesDict['symbol']) + 2674 '.png') 2675 self.symbolButton = BitmapButton(panel, id=wx.ID_ANY, bitmap=bitmap) 2676 2677 self.epsRadio = RadioButton( 2678 panel, id=wx.ID_ANY, label=_("eps file:")) 2679 self.epsRadio.SetValue(bool(self.vPropertiesDict['eps'])) 2680 2681 self.epsFileCtrl = FileBrowseButton( 2682 panel, id=wx.ID_ANY, labelText='', buttonText=_("Browse"), 2683 toolTip=_("Type filename or click browse to choose file"), 2684 dialogTitle=_("Choose a file"), 2685 startDirectory='', initialValue='', 2686 fileMask="Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", 2687 fileMode=wx.FD_OPEN) 2688 if not self.vPropertiesDict['eps']: 2689 self.epsFileCtrl.SetValue('') 2690 else: # eps chosen 2691 self.epsFileCtrl.SetValue(self.vPropertiesDict['eps']) 2692 2693 gridBagSizer.Add( 2694 self.symbolRadio, pos=(0, 0), 2695 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2696 gridBagSizer.Add( 2697 self.symbolName, 2698 pos=( 2699 0, 2700 1), 2701 flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 2702 border=10) 2703 gridBagSizer.Add( 2704 self.symbolButton, pos=(0, 2), 2705 flag=wx.ALIGN_RIGHT, border=0) 2706 gridBagSizer.Add( 2707 self.epsRadio, pos=(1, 0), 2708 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2709 gridBagSizer.Add( 2710 self.epsFileCtrl, pos=( 2711 1, 1), span=( 2712 1, 2), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 2713 2714 gridBagSizer.AddGrowableCol(1) 2715 gridBagSizer.AddGrowableCol(2) 2716 sizer.Add( 2717 gridBagSizer, 2718 proportion=1, 2719 flag=wx.EXPAND | wx.ALL, 2720 border=5) 2721 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2722 2723 self.Bind(wx.EVT_BUTTON, self.OnSymbolSelection, self.symbolButton) 2724 self.Bind(wx.EVT_RADIOBUTTON, self.OnSymbology, self.symbolRadio) 2725 self.Bind(wx.EVT_RADIOBUTTON, self.OnSymbology, self.epsRadio) 2726 2727 # size 2728 2729 box = StaticBox( 2730 parent=panel, 2731 id=wx.ID_ANY, 2732 label=" %s " % 2733 _("Size")) 2734 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2735 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 2736 2737 self.sizeRadio = RadioButton( 2738 panel, id=wx.ID_ANY, label=_("size:"), 2739 style=wx.RB_GROUP) 2740 self.sizeSpin = SpinCtrl( 2741 panel, id=wx.ID_ANY, min=1, max=50, initial=1) 2742 self.sizecolumnRadio = RadioButton( 2743 panel, id=wx.ID_ANY, label=_("size from map table column:")) 2744 self.sizeColChoice = self.getColsChoice(panel) 2745 self.scaleText = StaticText(panel, id=wx.ID_ANY, label=_("scale:")) 2746 self.scaleSpin = SpinCtrl( 2747 panel, id=wx.ID_ANY, min=1, max=25, initial=1) 2748 2749 self.sizeRadio.SetValue(self.vPropertiesDict['size'] is not None) 2750 self.sizecolumnRadio.SetValue(bool(self.vPropertiesDict['sizecolumn'])) 2751 if self.vPropertiesDict['size']: 2752 self.sizeSpin.SetValue(self.vPropertiesDict['size']) 2753 else: 2754 self.sizeSpin.SetValue(5) 2755 if self.vPropertiesDict['sizecolumn']: 2756 self.scaleSpin.SetValue(self.vPropertiesDict['scale']) 2757 self.sizeColChoice.SetStringSelection( 2758 self.vPropertiesDict['sizecolumn']) 2759 else: 2760 self.scaleSpin.SetValue(1) 2761 self.sizeColChoice.SetSelection(0) 2762 if not self.connection: 2763 for each in (self.sizecolumnRadio, self.sizeColChoice, 2764 self.scaleSpin, self.scaleText): 2765 each.Disable() 2766 2767 gridBagSizer.Add( 2768 self.sizeRadio, pos=(0, 0), 2769 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2770 gridBagSizer.Add( 2771 self.sizeSpin, pos=(0, 1), 2772 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2773 gridBagSizer.Add( 2774 self.sizecolumnRadio, pos=(1, 0), 2775 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2776 gridBagSizer.Add( 2777 self.sizeColChoice, 2778 pos=( 2779 1, 2780 1), 2781 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 2782 border=0) 2783 gridBagSizer.Add( 2784 self.scaleText, 2785 pos=( 2786 2, 2787 0), 2788 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 2789 border=0) 2790 gridBagSizer.Add( 2791 self.scaleSpin, pos=(2, 1), 2792 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2793 2794 gridBagSizer.AddGrowableCol(0) 2795 sizer.Add( 2796 gridBagSizer, 2797 proportion=1, 2798 flag=wx.EXPAND | wx.ALL, 2799 border=5) 2800 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2801 2802 self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizeRadio) 2803 self.Bind(wx.EVT_RADIOBUTTON, self.OnSize, self.sizecolumnRadio) 2804 2805 # rotation 2806 box = StaticBox( 2807 parent=panel, 2808 id=wx.ID_ANY, 2809 label=" %s " % 2810 _("Rotation")) 2811 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2812 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 2813 2814 self.rotateCheck = CheckBox( 2815 panel, id=wx.ID_ANY, label=_("rotate symbols:")) 2816 self.rotateRadio = RadioButton(panel, id=wx.ID_ANY, label=_( 2817 "counterclockwise in degrees:"), style=wx.RB_GROUP) 2818 self.rotateSpin = SpinCtrl( 2819 panel, id=wx.ID_ANY, min=0, max=360, initial=0) 2820 self.rotatecolumnRadio = RadioButton( 2821 panel, id=wx.ID_ANY, label=_("from map table column:")) 2822 self.rotateColChoice = self.getColsChoice(panel) 2823 2824 self.rotateCheck.SetValue(self.vPropertiesDict['rotation']) 2825 self.rotateRadio.SetValue(self.vPropertiesDict['rotate'] is not None) 2826 self.rotatecolumnRadio.SetValue( 2827 bool(self.vPropertiesDict['rotatecolumn'])) 2828 if self.vPropertiesDict['rotate']: 2829 self.rotateSpin.SetValue(self.vPropertiesDict['rotate']) 2830 else: 2831 self.rotateSpin.SetValue(0) 2832 if self.vPropertiesDict['rotatecolumn']: 2833 self.rotateColChoice.SetStringSelection( 2834 self.vPropertiesDict['rotatecolumn']) 2835 else: 2836 self.rotateColChoice.SetSelection(0) 2837 2838 gridBagSizer.Add( 2839 self.rotateCheck, pos=( 2840 0, 0), span=( 2841 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2842 gridBagSizer.Add( 2843 self.rotateRadio, pos=(1, 1), 2844 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2845 gridBagSizer.Add( 2846 self.rotateSpin, pos=(1, 2), 2847 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2848 gridBagSizer.Add( 2849 self.rotatecolumnRadio, pos=(2, 1), 2850 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2851 gridBagSizer.Add( 2852 self.rotateColChoice, 2853 pos=( 2854 2, 2855 2), 2856 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 2857 border=0) 2858 2859 gridBagSizer.AddGrowableCol(1) 2860 sizer.Add( 2861 gridBagSizer, 2862 proportion=1, 2863 flag=wx.EXPAND | wx.ALL, 2864 border=5) 2865 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2866 2867 self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotateCheck) 2868 self.Bind(wx.EVT_RADIOBUTTON, self.OnRotationType, self.rotateRadio) 2869 self.Bind( 2870 wx.EVT_RADIOBUTTON, 2871 self.OnRotationType, 2872 self.rotatecolumnRadio) 2873 2874 panel.SetSizer(border) 2875 panel.Fit() 2876 return panel 2877 2878 def _StyleLinePanel(self, notebook): 2879 panel = Panel( 2880 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 2881 style=wx.TAB_TRAVERSAL) 2882 notebook.AddPage(page=panel, text=_("Size and style")) 2883 2884 border = wx.BoxSizer(wx.VERTICAL) 2885 2886 # width 2887 box = StaticBox( 2888 parent=panel, 2889 id=wx.ID_ANY, 2890 label=" %s " % 2891 _("Width")) 2892 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2893 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 2894 2895 widthText = StaticText( 2896 panel, id=wx.ID_ANY, label=_("Set width (pts):")) 2897 2898 self.widthSpin = FloatSpin( 2899 panel, 2900 id=wx.ID_ANY, 2901 min_val=0, 2902 max_val=30, 2903 increment=0.5, 2904 value=1, 2905 style=fs.FS_RIGHT) 2906 self.widthSpin.SetFormat("%f") 2907 self.widthSpin.SetDigits(1) 2908 2909 self.cwidthCheck = CheckBox( 2910 panel, id=wx.ID_ANY, label=_("multiply width by category value")) 2911 2912 if self.vPropertiesDict['width']: 2913 self.widthSpin.SetValue(self.vPropertiesDict['width']) 2914 self.cwidthCheck.SetValue(False) 2915 else: 2916 self.widthSpin.SetValue(self.vPropertiesDict['cwidth']) 2917 self.cwidthCheck.SetValue(True) 2918 2919 gridBagSizer.Add( 2920 widthText, pos=(0, 0), 2921 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2922 gridBagSizer.Add( 2923 self.widthSpin, pos=(0, 1), 2924 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2925 gridBagSizer.Add( 2926 self.cwidthCheck, pos=( 2927 1, 0), span=( 2928 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2929 2930 sizer.Add( 2931 gridBagSizer, 2932 proportion=1, 2933 flag=wx.EXPAND | wx.ALL, 2934 border=5) 2935 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2936 2937 # style 2938 box = StaticBox( 2939 parent=panel, 2940 id=wx.ID_ANY, 2941 label=" %s " % 2942 _("Line style")) 2943 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 2944 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 2945 2946 styleText = StaticText( 2947 panel, id=wx.ID_ANY, label=_("Choose line style:")) 2948 penStyles = ["solid", "dashed", "dotted", "dashdotted"] 2949 self.styleCombo = PenStyleComboBox( 2950 panel, choices=penStyles, validator=TCValidator( 2951 flag='ZERO_AND_ONE_ONLY')) 2952# self.styleCombo = wx.ComboBox(panel, id = wx.ID_ANY, 2953## choices = ["solid", "dashed", "dotted", "dashdotted"], 2954# validator = TCValidator(flag = 'ZERO_AND_ONE_ONLY')) 2955# self.styleCombo.SetToolTipString(_("It's possible to enter a series of 0's and 1's too. "\ 2956## "The first block of repeated zeros or ones represents 'draw', "\ 2957## "the second block represents 'blank'. An even number of blocks "\ 2958# "will repeat the pattern, an odd number of blocks will alternate the pattern.")) 2959 linecapText = StaticText( 2960 panel, id=wx.ID_ANY, label=_("Choose linecap:")) 2961 self.linecapChoice = Choice( 2962 panel, id=wx.ID_ANY, choices=[ 2963 "butt", "round", "extended_butt"]) 2964 2965 self.styleCombo.SetValue(self.vPropertiesDict['style']) 2966 self.linecapChoice.SetStringSelection(self.vPropertiesDict['linecap']) 2967 2968 gridBagSizer.Add( 2969 styleText, pos=(0, 0), 2970 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2971 gridBagSizer.Add( 2972 self.styleCombo, 2973 pos=( 2974 0, 2975 1), 2976 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 2977 border=0) 2978 gridBagSizer.Add( 2979 linecapText, pos=(1, 0), 2980 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 2981 gridBagSizer.Add( 2982 self.linecapChoice, 2983 pos=( 2984 1, 2985 1), 2986 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 2987 border=0) 2988 2989 sizer.Add( 2990 gridBagSizer, 2991 proportion=1, 2992 flag=wx.EXPAND | wx.ALL, 2993 border=5) 2994 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 2995 2996 panel.SetSizer(border) 2997 panel.Fit() 2998 return panel 2999 3000 def _StyleAreaPanel(self, notebook): 3001 panel = Panel( 3002 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 3003 style=wx.TAB_TRAVERSAL) 3004 notebook.AddPage(page=panel, text=_("Size and style")) 3005 3006 border = wx.BoxSizer(wx.VERTICAL) 3007 3008 # pattern 3009 box = StaticBox( 3010 parent=panel, 3011 id=wx.ID_ANY, 3012 label=" %s " % 3013 _("Pattern")) 3014 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 3015 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 3016 3017 self.patternCheck = CheckBox( 3018 panel, id=wx.ID_ANY, label=_("use pattern:")) 3019 self.patFileCtrl = FileBrowseButton( 3020 panel, id=wx.ID_ANY, labelText=_("Choose pattern file:"), 3021 buttonText=_("Browse"), 3022 toolTip=_("Type filename or click browse to choose file"), 3023 dialogTitle=_("Choose a file"), 3024 startDirectory=self.patternPath, initialValue='', 3025 fileMask="Encapsulated PostScript (*.eps)|*.eps|All files (*.*)|*.*", 3026 fileMode=wx.FD_OPEN) 3027 self.patWidthText = StaticText( 3028 panel, id=wx.ID_ANY, label=_("pattern line width (pts):")) 3029 self.patWidthSpin = SpinCtrl( 3030 panel, id=wx.ID_ANY, min=1, max=25, initial=1) 3031 self.patScaleText = StaticText( 3032 panel, id=wx.ID_ANY, label=_("pattern scale factor:")) 3033 self.patScaleSpin = SpinCtrl( 3034 panel, id=wx.ID_ANY, min=1, max=25, initial=1) 3035 3036 self.patternCheck.SetValue(bool(self.vPropertiesDict['pat'])) 3037 if self.patternCheck.GetValue(): 3038 self.patFileCtrl.SetValue(self.vPropertiesDict['pat']) 3039 self.patWidthSpin.SetValue(self.vPropertiesDict['pwidth']) 3040 self.patScaleSpin.SetValue(self.vPropertiesDict['scale']) 3041 3042 gridBagSizer.Add( 3043 self.patternCheck, pos=(0, 0), 3044 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3045 gridBagSizer.Add( 3046 self.patFileCtrl, pos=( 3047 1, 0), span=( 3048 1, 2), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 3049 gridBagSizer.Add( 3050 self.patWidthText, pos=(2, 0), 3051 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3052 gridBagSizer.Add( 3053 self.patWidthSpin, pos=(2, 1), 3054 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3055 gridBagSizer.Add( 3056 self.patScaleText, pos=(3, 0), 3057 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3058 gridBagSizer.Add( 3059 self.patScaleSpin, pos=(3, 1), 3060 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3061 3062 gridBagSizer.AddGrowableCol(1) 3063 sizer.Add( 3064 gridBagSizer, 3065 proportion=1, 3066 flag=wx.EXPAND | wx.ALL, 3067 border=5) 3068 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 3069 3070 self.Bind(wx.EVT_CHECKBOX, self.OnPattern, self.patternCheck) 3071 3072 panel.SetSizer(border) 3073 panel.Fit() 3074 return panel 3075 3076 def OnLayer(self, event): 3077 """Change columns on layer change """ 3078 if self.layerChoice.GetStringSelection() == self.currLayer: 3079 return 3080 self.currLayer = self.layerChoice.GetStringSelection() 3081 if self.connection: 3082 cols = self.mapDBInfo.GetColumns( 3083 self.mapDBInfo.layers[int(self.currLayer)]['table']) 3084 else: 3085 cols = [] 3086 3087 self.choiceColumns.SetItems(cols) 3088 3089 self.choiceColumns.SetSelection(0) 3090 if self.type in ('points', 'lines'): 3091 self.colorColChoice.SetItems(cols) 3092 self.colorColChoice.SetSelection(0) 3093 3094 def OnOutline(self, event): 3095 for widget in self.gridBagSizerO.GetChildren(): 3096 if widget.GetWindow() != self.outlineCheck: 3097 widget.GetWindow().Enable(self.outlineCheck.GetValue()) 3098 3099 def OnFill(self, event): 3100 enable = self.fillCheck.GetValue() 3101 3102 self.colorColChoice.Enable(enable) 3103 self.colorColRadio.Enable(enable) 3104 self.fillColorPicker.Enable(enable) 3105 self.colorPickerRadio.Enable(enable) 3106 if enable: 3107 self.OnColor(None) 3108 if not self.connection: 3109 self.colorColChoice.Disable() 3110 self.colorColRadio.Disable() 3111 3112 def OnColor(self, event): 3113 self.colorColChoice.Enable(self.colorColRadio.GetValue()) 3114 self.fillColorPicker.Enable(self.colorPickerRadio.GetValue()) 3115 3116 def OnSize(self, event): 3117 self.sizeSpin.Enable(self.sizeRadio.GetValue()) 3118 self.sizeColChoice.Enable(self.sizecolumnRadio.GetValue()) 3119 self.scaleText.Enable(self.sizecolumnRadio.GetValue()) 3120 self.scaleSpin.Enable(self.sizecolumnRadio.GetValue()) 3121 3122 def OnRotation(self, event): 3123 for each in (self.rotateRadio, self.rotatecolumnRadio, 3124 self.rotateColChoice, self.rotateSpin): 3125 if self.rotateCheck.GetValue(): 3126 each.Enable() 3127 self.OnRotationType(event=None) 3128 else: 3129 each.Disable() 3130 3131 def OnRotationType(self, event): 3132 self.rotateSpin.Enable(self.rotateRadio.GetValue()) 3133 self.rotateColChoice.Enable(self.rotatecolumnRadio.GetValue()) 3134 3135 def OnPattern(self, event): 3136 for each in (self.patFileCtrl, self.patWidthText, 3137 self.patWidthSpin, self.patScaleText, self.patScaleSpin): 3138 each.Enable(self.patternCheck.GetValue()) 3139 3140 def OnSymbology(self, event): 3141 useSymbol = self.symbolRadio.GetValue() 3142 3143 self.symbolButton.Enable(useSymbol) 3144 self.symbolName.Enable(useSymbol) 3145 self.epsFileCtrl.Enable(not useSymbol) 3146 3147 def OnSymbolSelection(self, event): 3148 dlg = SymbolDialog(self, symbolPath=globalvar.SYMBDIR, 3149 currentSymbol=self.symbolName.GetLabel()) 3150 if dlg.ShowModal() == wx.ID_OK: 3151 img = dlg.GetSelectedSymbolPath() 3152 name = dlg.GetSelectedSymbolName() 3153 self.symbolButton.SetBitmapLabel(wx.Bitmap(img + '.png')) 3154 self.symbolName.SetLabel(name) 3155 3156 dlg.Destroy() 3157 3158 def EnableLayerSelection(self, enable=True): 3159 for widget in self.gridBagSizerL.GetChildren(): 3160 if widget.GetWindow() != self.warning: 3161 widget.GetWindow().Enable(enable) 3162 3163 def getColsChoice(self, parent): 3164 """Returns a Choice with table columns""" 3165 if self.connection: 3166 cols = self.mapDBInfo.GetColumns( 3167 self.mapDBInfo.layers[int(self.currLayer)]['table']) 3168 else: 3169 cols = [] 3170 3171 choice = Choice(parent=parent, id=wx.ID_ANY, choices=cols) 3172 return choice 3173 3174 def update(self): 3175 # feature type 3176 if self.type in ('lines', 'points'): 3177 featureType = None 3178 if self.checkType1.GetValue(): 3179 featureType = self.checkType1.GetName() 3180 if self.checkType2.GetValue(): 3181 featureType += " or " + self.checkType2.GetName() 3182 elif self.checkType2.GetValue(): 3183 featureType = self.checkType2.GetName() 3184 if featureType: 3185 self.vPropertiesDict['type'] = featureType 3186 3187 # is connection 3188 self.vPropertiesDict['connection'] = self.connection 3189 if self.connection: 3190 self.vPropertiesDict[ 3191 'layer'] = self.layerChoice.GetStringSelection() 3192 if self.radioCats.GetValue() and not self.textCtrlCats.IsEmpty(): 3193 self.vPropertiesDict['cats'] = self.textCtrlCats.GetValue() 3194 elif self.radioWhere.GetValue() and not self.textCtrlWhere.IsEmpty(): 3195 self.vPropertiesDict['where'] = self.choiceColumns.GetStringSelection( 3196 ) + " " + self.textCtrlWhere.GetValue() 3197 # mask 3198 if self.mask.GetValue(): 3199 self.vPropertiesDict['masked'] = 'y' 3200 else: 3201 self.vPropertiesDict['masked'] = 'n' 3202 3203 # colors 3204 if self.type in ('points', 'areas'): 3205 if self.outlineCheck.GetValue(): 3206 self.vPropertiesDict['color'] = convertRGB( 3207 self.colorPicker.GetColour()) 3208 self.vPropertiesDict['width'] = self.widthSpin.GetValue() 3209 else: 3210 self.vPropertiesDict['color'] = 'none' 3211 3212 if self.fillCheck.GetValue(): 3213 if self.colorPickerRadio.GetValue(): 3214 self.vPropertiesDict['fcolor'] = convertRGB( 3215 self.fillColorPicker.GetColour()) 3216 self.vPropertiesDict['rgbcolumn'] = None 3217 if self.colorColRadio.GetValue(): 3218 # this color is taken in case of no record in rgb column 3219 self.vPropertiesDict['fcolor'] = 'none' 3220 self.vPropertiesDict[ 3221 'rgbcolumn'] = self.colorColChoice.GetStringSelection() 3222 else: 3223 self.vPropertiesDict['fcolor'] = 'none' 3224 3225 if self.type == 'lines': 3226 # hcolor only when no rgbcolumn 3227 # and self.fillCheck.GetValue() and self.colorColRadio.GetValue(): 3228 if self.outlineCheck.GetValue(): 3229 self.vPropertiesDict['hcolor'] = convertRGB( 3230 self.colorPicker.GetColour()) 3231 self.vPropertiesDict['hwidth'] = self.outWidthSpin.GetValue() 3232 3233 else: 3234 self.vPropertiesDict['hcolor'] = 'none' 3235 3236 if self.colorPickerRadio.GetValue(): 3237 self.vPropertiesDict['color'] = convertRGB( 3238 self.fillColorPicker.GetColour()) 3239 self.vPropertiesDict['rgbcolumn'] = None 3240 if self.colorColRadio.GetValue(): 3241 # this color is taken in case of no record in rgb column 3242 self.vPropertiesDict['color'] = 'none' 3243 self.vPropertiesDict[ 3244 'rgbcolumn'] = self.colorColChoice.GetStringSelection() 3245 # 3246 #size and style 3247 # 3248 3249 if self.type == 'points': 3250 # symbols 3251 if self.symbolRadio.GetValue(): 3252 self.vPropertiesDict['symbol'] = self.symbolName.GetLabel() 3253 self.vPropertiesDict['eps'] = None 3254 else: 3255 self.vPropertiesDict['eps'] = self.epsFileCtrl.GetValue() 3256 # size 3257 if self.sizeRadio.GetValue(): 3258 self.vPropertiesDict['size'] = self.sizeSpin.GetValue() 3259 self.vPropertiesDict['sizecolumn'] = None 3260 self.vPropertiesDict['scale'] = None 3261 else: 3262 self.vPropertiesDict[ 3263 'sizecolumn'] = self.sizeColChoice.GetStringSelection() 3264 self.vPropertiesDict['scale'] = self.scaleSpin.GetValue() 3265 self.vPropertiesDict['size'] = None 3266 3267 # rotation 3268 self.vPropertiesDict['rotate'] = None 3269 self.vPropertiesDict['rotatecolumn'] = None 3270 self.vPropertiesDict['rotation'] = False 3271 if self.rotateCheck.GetValue(): 3272 self.vPropertiesDict['rotation'] = True 3273 if self.rotateRadio.GetValue(): 3274 self.vPropertiesDict['rotate'] = self.rotateSpin.GetValue() 3275 else: 3276 self.vPropertiesDict[ 3277 'rotatecolumn'] = self.rotateColChoice.GetStringSelection() 3278 3279 if self.type == 'areas': 3280 # pattern 3281 self.vPropertiesDict['pat'] = None 3282 if self.patternCheck.GetValue() and bool(self.patFileCtrl.GetValue()): 3283 self.vPropertiesDict['pat'] = self.patFileCtrl.GetValue() 3284 self.vPropertiesDict['pwidth'] = self.patWidthSpin.GetValue() 3285 self.vPropertiesDict['scale'] = self.patScaleSpin.GetValue() 3286 3287 if self.type == 'lines': 3288 # width 3289 if self.cwidthCheck.GetValue(): 3290 self.vPropertiesDict['cwidth'] = self.widthSpin.GetValue() 3291 self.vPropertiesDict['width'] = None 3292 else: 3293 self.vPropertiesDict['width'] = self.widthSpin.GetValue() 3294 self.vPropertiesDict['cwidth'] = None 3295 # line style 3296 if self.styleCombo.GetValue(): 3297 self.vPropertiesDict['style'] = self.styleCombo.GetValue() 3298 else: 3299 self.vPropertiesDict['style'] = 'solid' 3300 3301 self.vPropertiesDict[ 3302 'linecap'] = self.linecapChoice.GetStringSelection() 3303 3304 def OnOK(self, event): 3305 self.update() 3306 event.Skip() 3307 3308 3309class LegendDialog(PsmapDialog): 3310 3311 def __init__(self, parent, id, settings, page, env): 3312 PsmapDialog.__init__( 3313 self, 3314 parent=parent, 3315 id=id, 3316 title="Legend settings", 3317 settings=settings, 3318 env=env) 3319 self.objectType = ('rasterLegend', 'vectorLegend') 3320 self.instruction = settings 3321 map = self.instruction.FindInstructionByType('map') 3322 if map: 3323 self.mapId = map.id 3324 else: 3325 self.mapId = None 3326 3327 vector = self.instruction.FindInstructionByType('vector') 3328 if vector: 3329 self.vectorId = vector.id 3330 else: 3331 self.vectorId = None 3332 3333 raster = self.instruction.FindInstructionByType('raster') 3334 if raster: 3335 self.rasterId = raster.id 3336 else: 3337 self.rasterId = None 3338 3339 self.pageId = self.instruction.FindInstructionByType('page').id 3340 currPage = self.instruction[self.pageId].GetInstruction() 3341 # raster legend 3342 if self.id[0] is not None: 3343 self.rasterLegend = self.instruction[self.id[0]] 3344 self.rLegendDict = self.rasterLegend.GetInstruction() 3345 else: 3346 self.id[0] = NewId() 3347 self.rasterLegend = RasterLegend(self.id[0], env=self.env) 3348 self.rLegendDict = self.rasterLegend.GetInstruction() 3349 self.rLegendDict['where'] = currPage['Left'], currPage['Top'] 3350 3351 # vector legend 3352 if self.id[1] is not None: 3353 self.vLegendDict = self.instruction[self.id[1]].GetInstruction() 3354 else: 3355 self.id[1] = NewId() 3356 vectorLegend = VectorLegend(self.id[1], env=self.env) 3357 self.vLegendDict = vectorLegend.GetInstruction() 3358 self.vLegendDict['where'] = currPage['Left'], currPage['Top'] 3359 3360 if self.rasterId: 3361 self.currRaster = self.instruction[self.rasterId]['raster'] 3362 else: 3363 self.currRaster = None 3364 3365 # notebook 3366 self.notebook = Notebook( 3367 parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT) 3368 self.panelRaster = self._rasterLegend(self.notebook) 3369 self.panelVector = self._vectorLegend(self.notebook) 3370 self.OnRaster(None) 3371 self.OnRange(None) 3372 self.OnIsLegend(None) 3373 self.OnSpan(None) 3374 self.OnBorder(None) 3375 3376 self._layout(self.notebook) 3377 self.notebook.ChangeSelection(page) 3378 self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGING, self.OnPageChanging) 3379 3380 def OnPageChanging(self, event): 3381 """Workaround to scroll up to see the checkbox""" 3382 wx.CallAfter(self.FindWindowByName('rasterPanel').ScrollChildIntoView, 3383 self.FindWindowByName('showRLegend')) 3384 wx.CallAfter(self.FindWindowByName('vectorPanel').ScrollChildIntoView, 3385 self.FindWindowByName('showVLegend')) 3386 3387 def _rasterLegend(self, notebook): 3388 panel = ScrolledPanel( 3389 parent=notebook, id=wx.ID_ANY, size=(-1, 500), 3390 style=wx.TAB_TRAVERSAL) 3391 panel.SetupScrolling(scroll_x=False, scroll_y=True) 3392 panel.SetName('rasterPanel') 3393 notebook.AddPage(page=panel, text=_("Raster legend")) 3394 3395 border = wx.BoxSizer(wx.VERTICAL) 3396 # is legend 3397 self.isRLegend = CheckBox( 3398 panel, id=wx.ID_ANY, label=_("Show raster legend")) 3399 self.isRLegend.SetValue(self.rLegendDict['rLegend']) 3400 self.isRLegend.SetName("showRLegend") 3401 border.Add( 3402 self.isRLegend, 3403 proportion=0, 3404 flag=wx.ALL | wx.EXPAND, 3405 border=5) 3406 3407 # choose raster 3408 box = StaticBox( 3409 parent=panel, 3410 id=wx.ID_ANY, 3411 label=" %s " % 3412 _("Source raster")) 3413 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 3414 flexSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5) 3415 3416 self.rasterDefault = RadioButton( 3417 panel, id=wx.ID_ANY, label=_("current raster"), 3418 style=wx.RB_GROUP) 3419 self.rasterOther = RadioButton( 3420 panel, id=wx.ID_ANY, label=_("select raster")) 3421 self.rasterDefault.SetValue(self.rLegendDict['rasterDefault']) 3422 self.rasterOther.SetValue(not self.rLegendDict['rasterDefault']) 3423 3424 rasterType = getRasterType(map=self.currRaster) 3425 3426 self.rasterCurrent = StaticText( 3427 panel, id=wx.ID_ANY, label=_("%(rast)s: type %(type)s") % 3428 {'rast': self.currRaster, 'type': rasterType}) 3429 self.rasterSelect = Select( 3430 panel, 3431 id=wx.ID_ANY, 3432 size=globalvar.DIALOG_GSELECT_SIZE, 3433 type='raster', 3434 multiple=False, 3435 updateOnPopup=True, 3436 onPopup=None) 3437 if not self.rLegendDict['rasterDefault']: 3438 self.rasterSelect.SetValue(self.rLegendDict['raster']) 3439 else: 3440 self.rasterSelect.SetValue('') 3441 flexSizer.Add( 3442 self.rasterDefault, 3443 proportion=0, 3444 flag=wx.ALIGN_CENTER_VERTICAL, 3445 border=0) 3446 flexSizer.Add( 3447 self.rasterCurrent, 3448 proportion=0, 3449 flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 3450 border=10) 3451 flexSizer.Add( 3452 self.rasterOther, 3453 proportion=0, 3454 flag=wx.ALIGN_CENTER_VERTICAL, 3455 border=0) 3456 flexSizer.Add( 3457 self.rasterSelect, 3458 proportion=0, 3459 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 3460 border=0) 3461 flexSizer.AddGrowableCol(1) 3462 3463 sizer.Add( 3464 flexSizer, 3465 proportion=1, 3466 flag=wx.ALL | wx.EXPAND, 3467 border=1) 3468 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 3469 3470 # type of legend 3471 3472 box = StaticBox( 3473 parent=panel, 3474 id=wx.ID_ANY, 3475 label=" %s " % 3476 _("Type of legend")) 3477 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 3478 vbox = wx.BoxSizer(wx.VERTICAL) 3479 self.discrete = RadioButton( 3480 parent=panel, id=wx.ID_ANY, label=" %s " % 3481 _("discrete legend (categorical maps)"), 3482 style=wx.RB_GROUP) 3483 self.continuous = RadioButton( 3484 parent=panel, id=wx.ID_ANY, label=" %s " % 3485 _("continuous color gradient legend (floating point map)")) 3486 3487 vbox.Add( 3488 self.discrete, 3489 proportion=1, 3490 flag=wx.EXPAND | wx.ALL, 3491 border=0) 3492 vbox.Add( 3493 self.continuous, 3494 proportion=1, 3495 flag=wx.EXPAND | wx.ALL, 3496 border=0) 3497 sizer.Add(vbox, proportion=1, flag=wx.ALL | wx.EXPAND, border=1) 3498 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 3499 3500 # size, position and font 3501 self.sizePositionFont( 3502 legendType='raster', 3503 parent=panel, 3504 mainSizer=border) 3505 3506 # advanced settings 3507 box = StaticBox( 3508 parent=panel, 3509 id=wx.ID_ANY, 3510 label=" %s " % 3511 _("Advanced legend settings")) 3512 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 3513 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 3514 # no data 3515 self.nodata = CheckBox( 3516 panel, id=wx.ID_ANY, label=_('draw "no data" box')) 3517 if self.rLegendDict['nodata'] == 'y': 3518 self.nodata.SetValue(True) 3519 else: 3520 self.nodata.SetValue(False) 3521 # tickbar 3522 self.ticks = CheckBox( 3523 panel, 3524 id=wx.ID_ANY, 3525 label=_("draw ticks across color table")) 3526 if self.rLegendDict['tickbar'] == 'y': 3527 self.ticks.SetValue(True) 3528 else: 3529 self.ticks.SetValue(False) 3530 # range 3531 if self.rasterId and self.instruction[self.rasterId]['raster']: 3532 rinfo = grass.raster_info( 3533 self.instruction[ 3534 self.rasterId]['raster']) 3535 self.minim, self.maxim = rinfo['min'], rinfo['max'] 3536 else: 3537 self.minim, self.maxim = 0, 0 3538 self.range = CheckBox(panel, id=wx.ID_ANY, label=_("range")) 3539 self.range.SetValue(self.rLegendDict['range']) 3540 self.minText = StaticText( 3541 panel, 3542 id=wx.ID_ANY, 3543 label="min (%s)" % 3544 self.minim) 3545 self.maxText = StaticText( 3546 panel, 3547 id=wx.ID_ANY, 3548 label="max (%s)" % 3549 self.maxim) 3550 self.min = TextCtrl( 3551 panel, id=wx.ID_ANY, value=str( 3552 self.rLegendDict['min'])) 3553 self.max = TextCtrl( 3554 panel, id=wx.ID_ANY, value=str( 3555 self.rLegendDict['max'])) 3556 3557 gridBagSizer.Add( 3558 self.nodata, pos=( 3559 0, 0), span=( 3560 1, 5), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3561 gridBagSizer.Add( 3562 self.ticks, pos=( 3563 1, 0), span=( 3564 1, 5), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3565 gridBagSizer.Add( 3566 self.range, pos=(2, 0), 3567 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3568 gridBagSizer.Add( 3569 self.minText, 3570 pos=( 3571 2, 3572 1), 3573 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 3574 border=0) 3575 gridBagSizer.Add( 3576 self.min, pos=(2, 2), 3577 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3578 gridBagSizer.Add( 3579 self.maxText, 3580 pos=( 3581 2, 3582 3), 3583 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT, 3584 border=0) 3585 gridBagSizer.Add( 3586 self.max, pos=(2, 4), 3587 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3588 3589 sizer.Add( 3590 gridBagSizer, 3591 proportion=0, 3592 border=0) 3593 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 3594 3595 panel.SetSizer(border) 3596 panel.Fit() 3597 3598 # bindings 3599 self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterDefault) 3600 self.Bind(wx.EVT_RADIOBUTTON, self.OnRaster, self.rasterOther) 3601 self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isRLegend) 3602 self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.discrete) 3603 self.Bind(wx.EVT_RADIOBUTTON, self.OnDiscrete, self.continuous) 3604## self.Bind(wx.EVT_CHECKBOX, self.OnDefaultSize, panel.defaultSize) 3605 self.Bind(wx.EVT_CHECKBOX, self.OnRange, self.range) 3606 self.rasterSelect.GetTextCtrl().Bind(wx.EVT_TEXT, self.OnRaster) 3607 3608 return panel 3609 3610 def _vectorLegend(self, notebook): 3611 panel = ScrolledPanel( 3612 parent=notebook, id=wx.ID_ANY, size=(-1, 500), 3613 style=wx.TAB_TRAVERSAL) 3614 panel.SetupScrolling(scroll_x=False, scroll_y=True) 3615 panel.SetName('vectorPanel') 3616 notebook.AddPage(page=panel, text=_("Vector legend")) 3617 3618 border = wx.BoxSizer(wx.VERTICAL) 3619 # is legend 3620 self.isVLegend = CheckBox( 3621 panel, id=wx.ID_ANY, label=_("Show vector legend")) 3622 self.isVLegend.SetValue(self.vLegendDict['vLegend']) 3623 self.isVLegend.SetName("showVLegend") 3624 border.Add( 3625 self.isVLegend, 3626 proportion=0, 3627 flag=wx.ALL | wx.EXPAND, 3628 border=5) 3629 3630 # vector maps, their order, labels 3631 box = StaticBox( 3632 parent=panel, 3633 id=wx.ID_ANY, 3634 label=" %s " % 3635 _("Source vector maps")) 3636 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 3637 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 3638 3639 vectorText = StaticText(panel, id=wx.ID_ANY, label=_( 3640 "Choose vector maps and their order in legend")) 3641 3642 self.vectorListCtrl = CheckListCtrl(panel) 3643 3644 self.vectorListCtrl.InsertColumn(0, _("Vector map")) 3645 self.vectorListCtrl.InsertColumn(1, _("Label")) 3646 if self.vectorId: 3647 vectors = sorted( 3648 self.instruction[ 3649 self.vectorId]['list'], 3650 key=lambda x: x[3]) 3651 3652 for vector in vectors: 3653 index = self.vectorListCtrl.InsertItem( 3654 self.vectorListCtrl.GetItemCount(), vector[0].split('@')[0]) 3655 self.vectorListCtrl.SetItem(index, 1, vector[4]) 3656 self.vectorListCtrl.SetItemData(index, index) 3657 self.vectorListCtrl.CheckItem(index, True) 3658 if vector[3] == 0: 3659 self.vectorListCtrl.CheckItem(index, False) 3660 if not self.vectorId: 3661 self.vectorListCtrl.SetColumnWidth(0, 100) 3662 else: 3663 self.vectorListCtrl.SetColumnWidth(0, wx.LIST_AUTOSIZE) 3664 self.vectorListCtrl.SetColumnWidth(1, wx.LIST_AUTOSIZE) 3665 3666 self.btnUp = Button(panel, id=wx.ID_ANY, label=_("Up")) 3667 self.btnDown = Button(panel, id=wx.ID_ANY, label=_("Down")) 3668 self.btnLabel = Button(panel, id=wx.ID_ANY, label=_("Edit label")) 3669 3670 gridBagSizer.Add( 3671 vectorText, pos=( 3672 0, 0), span=( 3673 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3674 gridBagSizer.Add( 3675 self.vectorListCtrl, pos=( 3676 1, 0), span=( 3677 3, 1), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 3678 gridBagSizer.Add( 3679 self.btnUp, pos=(1, 1), 3680 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3681 gridBagSizer.Add( 3682 self.btnDown, pos=(2, 1), 3683 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3684 gridBagSizer.Add( 3685 self.btnLabel, pos=(3, 1), 3686 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3687 3688 gridBagSizer.AddGrowableCol(0, 3) 3689 gridBagSizer.AddGrowableCol(1, 1) 3690 sizer.Add( 3691 gridBagSizer, 3692 proportion=0, 3693 flag=wx.EXPAND, 3694 border=0) 3695 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 3696 3697 # size, position and font 3698 self.sizePositionFont( 3699 legendType='vector', 3700 parent=panel, 3701 mainSizer=border) 3702 3703 # border 3704 # GTC Line around legend or map frame 3705 box = StaticBox( 3706 parent=panel, 3707 id=wx.ID_ANY, 3708 label=" %s " % 3709 _("Border")) 3710 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 3711 flexGridSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5) 3712 3713 self.borderCheck = CheckBox( 3714 panel, id=wx.ID_ANY, label=_("draw border around legend")) 3715 self.borderColorCtrl = ColourPickerCtrl( 3716 panel, id=wx.ID_ANY, style=wx.FNTP_FONTDESC_AS_LABEL) 3717 if self.vLegendDict['border'] == 'none': 3718 self.borderColorCtrl.SetColour(wx.BLACK) 3719 self.borderCheck.SetValue(False) 3720 else: 3721 self.borderColorCtrl.SetColour( 3722 convertRGB(self.vLegendDict['border'])) 3723 self.borderCheck.SetValue(True) 3724 3725 flexGridSizer.Add( 3726 self.borderCheck, 3727 proportion=0, 3728 flag=wx.ALIGN_CENTER_VERTICAL, 3729 border=0) 3730 flexGridSizer.Add( 3731 self.borderColorCtrl, 3732 proportion=0, 3733 flag=wx.ALIGN_CENTER_VERTICAL, 3734 border=0) 3735 sizer.Add( 3736 flexGridSizer, 3737 proportion=1, 3738 flag=wx.ALL | wx.EXPAND, 3739 border=1) 3740 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 3741 3742 self.Bind(wx.EVT_BUTTON, self.OnUp, self.btnUp) 3743 self.Bind(wx.EVT_BUTTON, self.OnDown, self.btnDown) 3744 self.Bind(wx.EVT_BUTTON, self.OnEditLabel, self.btnLabel) 3745 self.Bind(wx.EVT_CHECKBOX, self.OnIsLegend, self.isVLegend) 3746 self.Bind(wx.EVT_CHECKBOX, self.OnSpan, panel.spanRadio) 3747 self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.borderCheck) 3748 self.Bind( 3749 wx.EVT_FONTPICKER_CHANGED, 3750 self.OnFont, 3751 panel.font['fontCtrl']) 3752 3753 panel.SetSizer(border) 3754 3755 panel.Fit() 3756 return panel 3757 3758 def sizePositionFont(self, legendType, parent, mainSizer): 3759 """Insert widgets for size, position and font control""" 3760 if legendType == 'raster': 3761 legendDict = self.rLegendDict 3762 else: 3763 legendDict = self.vLegendDict 3764 panel = parent 3765 border = mainSizer 3766 3767 # size and position 3768 box = StaticBox( 3769 parent=panel, 3770 id=wx.ID_ANY, 3771 label=" %s " % 3772 _("Size and position")) 3773 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 3774 # unit 3775 self.AddUnits(parent=panel, dialogDict=legendDict) 3776 unitBox = wx.BoxSizer(wx.HORIZONTAL) 3777 unitBox.Add( 3778 panel.units['unitsLabel'], 3779 proportion=0, 3780 flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 3781 border=10) 3782 unitBox.Add( 3783 panel.units['unitsCtrl'], 3784 proportion=1, 3785 flag=wx.ALL, 3786 border=5) 3787 sizer.Add( 3788 unitBox, 3789 proportion=0, 3790 border=0) 3791 3792 hBox = wx.BoxSizer(wx.HORIZONTAL) 3793 posBox = StaticBox( 3794 parent=panel, 3795 id=wx.ID_ANY, 3796 label=" %s " % 3797 _("Position")) 3798 posSizer = wx.StaticBoxSizer(posBox, wx.VERTICAL) 3799 sizeBox = StaticBox( 3800 parent=panel, 3801 id=wx.ID_ANY, 3802 label=" %s " % 3803 _("Size")) 3804 sizeSizer = wx.StaticBoxSizer(sizeBox, wx.VERTICAL) 3805 posGridBagSizer = wx.GridBagSizer(hgap=10, vgap=5) 3806 3807 # position 3808 self.AddPosition(parent=panel, dialogDict=legendDict) 3809 3810 posGridBagSizer.Add(panel.position['xLabel'], pos=( 3811 0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3812 posGridBagSizer.Add(panel.position['xCtrl'], pos=( 3813 0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3814 posGridBagSizer.Add(panel.position['yLabel'], pos=( 3815 1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3816 posGridBagSizer.Add(panel.position['yCtrl'], pos=( 3817 1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3818 posGridBagSizer.Add( 3819 panel.position['comment'], pos=( 3820 2, 0), span=( 3821 1, 2), flag=wx.ALIGN_BOTTOM, border=0) 3822 posGridBagSizer.AddGrowableRow(2) 3823 posSizer.Add( 3824 posGridBagSizer, 3825 proportion=1, 3826 flag=wx.EXPAND | wx.ALL, 3827 border=5) 3828 3829 # size 3830 width = StaticText(panel, id=wx.ID_ANY, label=_("Width:")) 3831 if legendDict['width']: 3832 w = self.unitConv.convert( 3833 value=float(legendDict['width']), 3834 fromUnit='inch', toUnit=legendDict['unit']) 3835 else: 3836 w = '' 3837 panel.widthCtrl = TextCtrl( 3838 panel, id=wx.ID_ANY, value=str(w), 3839 validator=TCValidator("DIGIT_ONLY")) 3840 panel.widthCtrl.SetToolTip( 3841 _("Leave the edit field empty, to use default values.")) 3842 3843 if legendType == 'raster': 3844 ## panel.defaultSize = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use default size")) 3845 # panel.defaultSize.SetValue(legendDict['defaultSize']) 3846 3847 panel.heightOrColumnsLabel = StaticText( 3848 panel, id=wx.ID_ANY, label=_("Height:")) 3849 if legendDict['height']: 3850 h = self.unitConv.convert( 3851 value=float(legendDict['height']), 3852 fromUnit='inch', toUnit=legendDict['unit']) 3853 else: 3854 h = '' 3855 panel.heightOrColumnsCtrl = TextCtrl( 3856 panel, id=wx.ID_ANY, value=str(h), 3857 validator=TCValidator("DIGIT_ONLY")) 3858 3859 self.rSizeGBSizer = wx.GridBagSizer(hgap=5, vgap=5) 3860## self.rSizeGBSizer.Add(panel.defaultSize, pos = (0,0), span = (1,2), flag = wx.ALIGN_CENTER_VERTICAL, border = 0) 3861 self.rSizeGBSizer.Add( 3862 width, pos=(0, 0), 3863 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3864 self.rSizeGBSizer.Add( 3865 panel.widthCtrl, pos=(0, 1), 3866 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3867 self.rSizeGBSizer.Add( 3868 panel.heightOrColumnsLabel, pos=( 3869 1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3870 self.rSizeGBSizer.Add( 3871 panel.heightOrColumnsCtrl, pos=( 3872 1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3873 sizeSizer.Add( 3874 self.rSizeGBSizer, 3875 proportion=1, 3876 flag=wx.EXPAND | wx.ALL, 3877 border=5) 3878 3879 if legendType == 'vector': 3880 panel.widthCtrl.SetToolTip( 3881 _("Width of the color symbol (for lines)\nin front of the legend text")) 3882 # columns 3883 minVect, maxVect = 0, 0 3884 if self.vectorId: 3885 minVect = 1 3886 maxVect = min(10, len(self.instruction[self.vectorId]['list'])) 3887 cols = StaticText(panel, id=wx.ID_ANY, label=_("Columns:")) 3888 panel.colsCtrl = SpinCtrl( 3889 panel, 3890 id=wx.ID_ANY, 3891 value="", 3892 min=minVect, 3893 max=maxVect, 3894 initial=legendDict['cols']) 3895 # span 3896 panel.spanRadio = CheckBox( 3897 panel, id=wx.ID_ANY, label=_("column span:")) 3898 panel.spanTextCtrl = TextCtrl(panel, id=wx.ID_ANY, value='') 3899 panel.spanTextCtrl.SetToolTip(_("Column separation distance between the left edges\n" 3900 "of two columns in a multicolumn legend")) 3901 if legendDict['span']: 3902 panel.spanRadio.SetValue(True) 3903 s = self.unitConv.convert( 3904 value=float(legendDict['span']), 3905 fromUnit='inch', toUnit=legendDict['unit']) 3906 panel.spanTextCtrl.SetValue(str(s)) 3907 else: 3908 panel.spanRadio.SetValue(False) 3909 3910 self.vSizeGBSizer = wx.GridBagSizer(hgap=5, vgap=5) 3911 self.vSizeGBSizer.Add( 3912 width, pos=(0, 0), 3913 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3914 self.vSizeGBSizer.Add( 3915 panel.widthCtrl, pos=(0, 1), 3916 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3917 self.vSizeGBSizer.Add( 3918 cols, pos=(1, 0), 3919 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3920 self.vSizeGBSizer.Add( 3921 panel.colsCtrl, pos=(1, 1), 3922 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3923 self.vSizeGBSizer.Add( 3924 panel.spanRadio, pos=(2, 0), 3925 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3926 self.vSizeGBSizer.Add( 3927 panel.spanTextCtrl, pos=(2, 1), 3928 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 3929 self.vSizeGBSizer.AddGrowableCol(1) 3930 sizeSizer.Add( 3931 self.vSizeGBSizer, 3932 proportion=1, 3933 flag=wx.EXPAND | wx.ALL, 3934 border=5) 3935 3936 hBox.Add(posSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=3) 3937 hBox.Add(sizeSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=3) 3938 sizer.Add(hBox, proportion=0, flag=wx.EXPAND, border=0) 3939 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 3940 3941 # font 3942 box = StaticBox( 3943 parent=panel, 3944 id=wx.ID_ANY, 3945 label=" %s " % 3946 _("Font settings")) 3947 fontSizer = wx.StaticBoxSizer(box, wx.VERTICAL) 3948 flexSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5) 3949 3950 if legendType == 'raster': 3951 self.AddFont(parent=panel, dialogDict=legendDict, color=True) 3952 else: 3953 self.AddFont(parent=panel, dialogDict=legendDict, color=False) 3954 flexSizer.Add( 3955 panel.font['fontLabel'], 3956 proportion=0, 3957 flag=wx.ALIGN_CENTER_VERTICAL, 3958 border=0) 3959 flexSizer.Add( 3960 panel.font['fontCtrl'], 3961 proportion=0, 3962 flag=wx.ALIGN_CENTER_VERTICAL, 3963 border=0) 3964 flexSizer.Add( 3965 panel.font['fontSizeLabel'], 3966 proportion=0, 3967 flag=wx.ALIGN_CENTER_VERTICAL, 3968 border=0) 3969 flexSizer.Add( 3970 panel.font['fontSizeCtrl'], 3971 proportion=0, 3972 flag=wx.ALIGN_CENTER_VERTICAL, 3973 border=0) 3974 if legendType == 'raster': 3975 flexSizer.Add( 3976 panel.font['colorLabel'], 3977 proportion=0, 3978 flag=wx.ALIGN_CENTER_VERTICAL, 3979 border=0) 3980 flexSizer.Add( 3981 panel.font['colorCtrl'], 3982 proportion=0, 3983 flag=wx.ALIGN_CENTER_VERTICAL, 3984 border=0) 3985 flexSizer.AddGrowableCol(1) 3986 3987 fontSizer.Add( 3988 flexSizer, 3989 proportion=1, 3990 flag=wx.ALL | wx.EXPAND, 3991 border=1) 3992 border.Add( 3993 fontSizer, 3994 proportion=0, 3995 flag=wx.ALL | wx.EXPAND, 3996 border=5) 3997 3998 # some enable/disable methods 3999 4000 def OnIsLegend(self, event): 4001 """Enables and disables controls, it depends if raster or vector legend is checked""" 4002 page = self.notebook.GetSelection() 4003 if page == 0 or event is None: 4004 children = self.panelRaster.GetChildren() 4005 if self.isRLegend.GetValue(): 4006 for i, widget in enumerate(children): 4007 widget.Enable() 4008 self.OnRaster(None) 4009 self.OnRange(None) 4010 self.OnDiscrete(None) 4011 else: 4012 for widget in children: 4013 if widget.GetName() != 'showRLegend': 4014 widget.Disable() 4015 if page == 1 or event is None: 4016 children = self.panelVector.GetChildren() 4017 if self.isVLegend.GetValue(): 4018 for i, widget in enumerate(children): 4019 widget.Enable() 4020 self.OnSpan(None) 4021 self.OnBorder(None) 4022 else: 4023 for widget in children: 4024 if widget.GetName() != 'showVLegend': 4025 widget.Disable() 4026 4027 def OnRaster(self, event): 4028 if self.rasterDefault.GetValue(): # default 4029 self.rasterSelect.Disable() 4030 type = getRasterType(self.currRaster) 4031 else: # select raster 4032 self.rasterSelect.Enable() 4033 map = self.rasterSelect.GetValue() 4034 type = getRasterType(map) 4035 4036 if type == 'CELL': 4037 self.discrete.SetValue(True) 4038 elif type in ('FCELL', 'DCELL'): 4039 self.continuous.SetValue(True) 4040 if event is None: 4041 if self.rLegendDict['discrete'] == 'y': 4042 self.discrete.SetValue(True) 4043 elif self.rLegendDict['discrete'] == 'n': 4044 self.continuous.SetValue(True) 4045 self.OnDiscrete(None) 4046 4047 def OnDiscrete(self, event): 4048 """Change control according to the type of legend""" 4049 enabledSize = self.panelRaster.heightOrColumnsCtrl.IsEnabled() 4050 self.panelRaster.heightOrColumnsCtrl.Destroy() 4051 if self.discrete.GetValue(): 4052 self.panelRaster.heightOrColumnsLabel.SetLabel(_("Columns:")) 4053 self.panelRaster.heightOrColumnsCtrl = SpinCtrl( 4054 self.panelRaster, id=wx.ID_ANY, value="", min=1, max=10, 4055 initial=self.rLegendDict['cols']) 4056 self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize) 4057 self.nodata.Enable() 4058 self.range.Disable() 4059 self.min.Disable() 4060 self.max.Disable() 4061 self.minText.Disable() 4062 self.maxText.Disable() 4063 self.ticks.Disable() 4064 else: 4065 self.panelRaster.heightOrColumnsLabel.SetLabel(_("Height:")) 4066 if self.rLegendDict['height']: 4067 h = self.unitConv.convert( 4068 value=float( 4069 self.rLegendDict['height']), 4070 fromUnit='inch', 4071 toUnit=self.rLegendDict['unit']) 4072 else: 4073 h = '' 4074 self.panelRaster.heightOrColumnsCtrl = TextCtrl( 4075 self.panelRaster, id=wx.ID_ANY, value=str(h), 4076 validator=TCValidator("DIGIT_ONLY")) 4077 self.panelRaster.heightOrColumnsCtrl.Enable(enabledSize) 4078 self.nodata.Disable() 4079 self.range.Enable() 4080 if self.range.GetValue(): 4081 self.minText.Enable() 4082 self.maxText.Enable() 4083 self.min.Enable() 4084 self.max.Enable() 4085 self.ticks.Enable() 4086 4087 self.rSizeGBSizer.Add( 4088 self.panelRaster.heightOrColumnsCtrl, pos=( 4089 1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4090 self.panelRaster.Layout() 4091 self.panelRaster.Fit() 4092 4093 def OnRange(self, event): 4094 if not self.range.GetValue(): 4095 self.min.Disable() 4096 self.max.Disable() 4097 self.minText.Disable() 4098 self.maxText.Disable() 4099 else: 4100 self.min.Enable() 4101 self.max.Enable() 4102 self.minText.Enable() 4103 self.maxText.Enable() 4104 4105 def OnUp(self, event): 4106 """Moves selected map up, changes order in vector legend""" 4107 if self.vectorListCtrl.GetFirstSelected() != -1: 4108 pos = self.vectorListCtrl.GetFirstSelected() 4109 if pos: 4110 idx1 = self.vectorListCtrl.GetItemData(pos) - 1 4111 idx2 = self.vectorListCtrl.GetItemData(pos - 1) + 1 4112 self.vectorListCtrl.SetItemData(pos, idx1) 4113 self.vectorListCtrl.SetItemData(pos - 1, idx2) 4114 self.vectorListCtrl.SortItems(cmp) 4115 if pos > 0: 4116 selected = (pos - 1) 4117 else: 4118 selected = 0 4119 4120 self.vectorListCtrl.Select(selected) 4121 4122 def OnDown(self, event): 4123 """Moves selected map down, changes order in vector legend""" 4124 if self.vectorListCtrl.GetFirstSelected() != -1: 4125 pos = self.vectorListCtrl.GetFirstSelected() 4126 if pos != self.vectorListCtrl.GetItemCount() - 1: 4127 idx1 = self.vectorListCtrl.GetItemData(pos) + 1 4128 idx2 = self.vectorListCtrl.GetItemData(pos + 1) - 1 4129 self.vectorListCtrl.SetItemData(pos, idx1) 4130 self.vectorListCtrl.SetItemData(pos + 1, idx2) 4131 self.vectorListCtrl.SortItems(cmp) 4132 if pos < self.vectorListCtrl.GetItemCount() - 1: 4133 selected = (pos + 1) 4134 else: 4135 selected = self.vectorListCtrl.GetItemCount() - 1 4136 4137 self.vectorListCtrl.Select(selected) 4138 4139 def OnEditLabel(self, event): 4140 """Change legend label of vector map""" 4141 if self.vectorListCtrl.GetFirstSelected() != -1: 4142 idx = self.vectorListCtrl.GetFirstSelected() 4143 default = self.vectorListCtrl.GetItem(idx, 1).GetText() 4144 dlg = TextEntryDialog( 4145 self, 4146 message=_("Edit legend label:"), 4147 caption=_("Edit label"), 4148 value=default, 4149 style=wx.OK | wx.CANCEL | wx.CENTRE) 4150 if dlg.ShowModal() == wx.ID_OK: 4151 new = dlg.GetValue() 4152 self.vectorListCtrl.SetItem(idx, 1, new) 4153 dlg.Destroy() 4154 4155 def OnSpan(self, event): 4156 self.panelVector.spanTextCtrl.Enable( 4157 self.panelVector.spanRadio.GetValue()) 4158 4159 def OnFont(self, event): 4160 """Changes default width according to fontsize, width [inch] = fontsize[pt]/24""" 4161## fontsize = self.panelVector.font['fontCtrl'].GetSelectedFont().GetPointSize() 4162 fontsize = self.panelVector.font['fontSizeCtrl'].GetValue() 4163 unit = self.unitConv.findUnit( 4164 self.panelVector.units['unitsCtrl'].GetStringSelection()) 4165 w = fontsize / 24. 4166 width = self.unitConv.convert(value=w, fromUnit='inch', toUnit=unit) 4167 self.panelVector.widthCtrl.SetValue("%3.2f" % width) 4168 4169 def OnBorder(self, event): 4170 """Enables/disables colorPickerCtrl for border""" 4171 self.borderColorCtrl.Enable(self.borderCheck.GetValue()) 4172 4173 def updateRasterLegend(self): 4174 """Save information from raster legend dialog to dictionary""" 4175 4176 # is raster legend 4177 if not self.isRLegend.GetValue(): 4178 self.rLegendDict['rLegend'] = False 4179 else: 4180 self.rLegendDict['rLegend'] = True 4181 # units 4182 currUnit = self.unitConv.findUnit( 4183 self.panelRaster.units['unitsCtrl'].GetStringSelection()) 4184 self.rLegendDict['unit'] = currUnit 4185 # raster 4186 if self.rasterDefault.GetValue(): 4187 self.rLegendDict['rasterDefault'] = True 4188 self.rLegendDict['raster'] = self.currRaster 4189 else: 4190 self.rLegendDict['rasterDefault'] = False 4191 self.rLegendDict['raster'] = self.rasterSelect.GetValue() 4192 if self.rLegendDict['rLegend'] and not self.rLegendDict['raster']: 4193 wx.MessageBox(message=_("No raster map selected!"), 4194 caption=_('No raster'), style=wx.OK | wx.ICON_ERROR) 4195 return False 4196 4197 if self.rLegendDict['raster']: 4198 # type and range of map 4199 rasterType = getRasterType(self.rLegendDict['raster']) 4200 if rasterType is None: 4201 return False 4202 self.rLegendDict['type'] = rasterType 4203 4204 # discrete 4205 if self.discrete.GetValue(): 4206 self.rLegendDict['discrete'] = 'y' 4207 else: 4208 self.rLegendDict['discrete'] = 'n' 4209 4210 # font 4211 self.rLegendDict['font'] = self.panelRaster.font[ 4212 'fontCtrl'].GetStringSelection() 4213 self.rLegendDict['fontsize'] = self.panelRaster.font[ 4214 'fontSizeCtrl'].GetValue() 4215 color = self.panelRaster.font['colorCtrl'].GetColour() 4216 self.rLegendDict['color'] = convertRGB(color) 4217 4218 # position 4219 x = self.unitConv.convert( 4220 value=float( 4221 self.panelRaster.position 4222 ['xCtrl'].GetValue()), 4223 fromUnit=currUnit, toUnit='inch') 4224 y = self.unitConv.convert( 4225 value=float( 4226 self.panelRaster.position 4227 ['yCtrl'].GetValue()), 4228 fromUnit=currUnit, toUnit='inch') 4229 self.rLegendDict['where'] = (x, y) 4230 # estimated size 4231 width = self.panelRaster.widthCtrl.GetValue() 4232 try: 4233 width = float(width) 4234 width = self.unitConv.convert( 4235 value=width, fromUnit=currUnit, toUnit='inch') 4236 except ValueError: 4237 width = None 4238 self.rLegendDict['width'] = width 4239 if self.rLegendDict['discrete'] == 'n': 4240 height = self.panelRaster.heightOrColumnsCtrl.GetValue() 4241 try: 4242 height = float(height) 4243 height = self.unitConv.convert( 4244 value=height, fromUnit=currUnit, toUnit='inch') 4245 except ValueError: 4246 height = None 4247 self.rLegendDict['height'] = height 4248 else: 4249 cols = self.panelRaster.heightOrColumnsCtrl.GetValue() 4250 self.rLegendDict['cols'] = cols 4251 drawHeight = self.rasterLegend.EstimateHeight( 4252 raster=self.rLegendDict['raster'], 4253 discrete=self.rLegendDict['discrete'], 4254 fontsize=self.rLegendDict['fontsize'], 4255 cols=self.rLegendDict['cols'], 4256 height=self.rLegendDict['height']) 4257 drawWidth = self.rasterLegend.EstimateWidth( 4258 raster=self.rLegendDict['raster'], 4259 discrete=self.rLegendDict['discrete'], 4260 fontsize=self.rLegendDict['fontsize'], 4261 cols=self.rLegendDict['cols'], 4262 width=self.rLegendDict['width'], 4263 paperInstr=self.instruction[self.pageId]) 4264 self.rLegendDict['rect'] = Rect2D( 4265 x=x, y=y, width=drawWidth, height=drawHeight) 4266 4267 # no data 4268 if self.rLegendDict['discrete'] == 'y': 4269 if self.nodata.GetValue(): 4270 self.rLegendDict['nodata'] = 'y' 4271 else: 4272 self.rLegendDict['nodata'] = 'n' 4273 # tickbar 4274 elif self.rLegendDict['discrete'] == 'n': 4275 if self.ticks.GetValue(): 4276 self.rLegendDict['tickbar'] = 'y' 4277 else: 4278 self.rLegendDict['tickbar'] = 'n' 4279 # range 4280 if self.range.GetValue(): 4281 self.rLegendDict['range'] = True 4282 self.rLegendDict['min'] = self.min.GetValue() 4283 self.rLegendDict['max'] = self.max.GetValue() 4284 else: 4285 self.rLegendDict['range'] = False 4286 4287 if not self.id[0] in self.instruction: 4288 rasterLegend = RasterLegend(self.id[0], env=self.env) 4289 self.instruction.AddInstruction(rasterLegend) 4290 self.instruction[self.id[0]].SetInstruction(self.rLegendDict) 4291 4292 if self.id[0] not in self.parent.objectId: 4293 self.parent.objectId.append(self.id[0]) 4294 return True 4295 4296 def updateVectorLegend(self): 4297 """Save information from vector legend dialog to dictionary""" 4298 4299 vector = self.instruction.FindInstructionByType('vector') 4300 if vector: 4301 self.vectorId = vector.id 4302 else: 4303 self.vectorId = None 4304 4305 # is vector legend 4306 if not self.isVLegend.GetValue(): 4307 self.vLegendDict['vLegend'] = False 4308 else: 4309 self.vLegendDict['vLegend'] = True 4310 if self.vLegendDict['vLegend'] == True and self.vectorId is not None: 4311 # labels 4312 # reindex order 4313 idx = 1 4314 for item in range(self.vectorListCtrl.GetItemCount()): 4315 if self.vectorListCtrl.IsItemChecked(item): 4316 self.vectorListCtrl.SetItemData(item, idx) 4317 idx += 1 4318 else: 4319 self.vectorListCtrl.SetItemData(item, 0) 4320 if idx == 1: 4321 self.vLegendDict['vLegend'] = False 4322 else: 4323 vList = self.instruction[self.vectorId]['list'] 4324 for i, vector in enumerate(vList): 4325 item = self.vectorListCtrl.FindItem( 4326 start=-1, str=vector[0].split('@')[0]) 4327 vList[i][3] = self.vectorListCtrl.GetItemData(item) 4328 vList[i][4] = self.vectorListCtrl.GetItem( 4329 item, 1).GetText() 4330 vmaps = self.instruction.FindInstructionByType( 4331 'vProperties', list=True) 4332 for vmap, vector in zip(vmaps, vList): 4333 self.instruction[vmap.id]['lpos'] = vector[3] 4334 self.instruction[vmap.id]['label'] = vector[4] 4335 # units 4336 currUnit = self.unitConv.findUnit( 4337 self.panelVector.units['unitsCtrl'].GetStringSelection()) 4338 self.vLegendDict['unit'] = currUnit 4339 # position 4340 x = self.unitConv.convert( 4341 value=float( 4342 self.panelVector.position['xCtrl'].GetValue()), 4343 fromUnit=currUnit, 4344 toUnit='inch') 4345 y = self.unitConv.convert( 4346 value=float( 4347 self.panelVector.position['yCtrl'].GetValue()), 4348 fromUnit=currUnit, 4349 toUnit='inch') 4350 self.vLegendDict['where'] = (x, y) 4351 4352 # font 4353 self.vLegendDict['font'] = self.panelVector.font[ 4354 'fontCtrl'].GetStringSelection() 4355 self.vLegendDict['fontsize'] = self.panelVector.font[ 4356 'fontSizeCtrl'].GetValue() 4357 dc = ClientDC(self) 4358 dc.SetFont( 4359 wx.Font( 4360 pointSize=self.vLegendDict['fontsize'], 4361 family=wx.FONTFAMILY_DEFAULT, 4362 style=wx.FONTSTYLE_NORMAL, 4363 weight=wx.FONTWEIGHT_NORMAL)) 4364 # size 4365 width = self.unitConv.convert( 4366 value=float(self.panelVector.widthCtrl.GetValue()), 4367 fromUnit=currUnit, toUnit='inch') 4368 self.vLegendDict['width'] = width 4369 self.vLegendDict['cols'] = self.panelVector.colsCtrl.GetValue() 4370 if self.panelVector.spanRadio.GetValue() and self.panelVector.spanTextCtrl.GetValue(): 4371 self.vLegendDict[ 4372 'span'] = self.panelVector.spanTextCtrl.GetValue() 4373 else: 4374 self.vLegendDict['span'] = None 4375 4376 # size estimation 4377 vectors = self.instruction[self.vectorId]['list'] 4378 labels = [vector[4] for vector in vectors if vector[3] != 0] 4379 extent = dc.GetTextExtent(max(labels, key=len)) 4380 wExtent = self.unitConv.convert( 4381 value=extent[0], fromUnit='pixel', toUnit='inch') 4382 hExtent = self.unitConv.convert( 4383 value=extent[1], fromUnit='pixel', toUnit='inch') 4384 w = (width + wExtent) * self.vLegendDict['cols'] 4385 h = len(labels) * hExtent / self.vLegendDict['cols'] 4386 h *= 1.1 4387 self.vLegendDict['rect'] = Rect2D(x, y, w, h) 4388 4389 # border 4390 if self.borderCheck.GetValue(): 4391 color = self.borderColorCtrl.GetColour() 4392 self.vLegendDict['border'] = convertRGB(color) 4393 4394 else: 4395 self.vLegendDict['border'] = 'none' 4396 4397 if not self.id[1] in self.instruction: 4398 vectorLegend = VectorLegend(self.id[1], env=self.env) 4399 self.instruction.AddInstruction(vectorLegend) 4400 self.instruction[self.id[1]].SetInstruction(self.vLegendDict) 4401 if self.id[1] not in self.parent.objectId: 4402 self.parent.objectId.append(self.id[1]) 4403 return True 4404 4405 def update(self): 4406 okR = self.updateRasterLegend() 4407 okV = self.updateVectorLegend() 4408 if okR and okV: 4409 return True 4410 return False 4411 4412 def updateDialog(self): 4413 """Update legend coordinates after moving""" 4414 4415 # raster legend 4416 if 'rect' in self.rLegendDict: 4417 x, y = self.rLegendDict['rect'][:2] 4418 currUnit = self.unitConv.findUnit( 4419 self.panelRaster.units['unitsCtrl'].GetStringSelection()) 4420 x = self.unitConv.convert( 4421 value=x, fromUnit='inch', toUnit=currUnit) 4422 y = self.unitConv.convert( 4423 value=y, fromUnit='inch', toUnit=currUnit) 4424 self.panelRaster.position['xCtrl'].SetValue("%5.3f" % x) 4425 self.panelRaster.position['yCtrl'].SetValue("%5.3f" % y) 4426 # update name and type of raster 4427 raster = self.instruction.FindInstructionByType('raster') 4428 if raster: 4429 self.rasterId = raster.id 4430 else: 4431 self.rasterId = None 4432 4433 if raster: 4434 currRaster = raster['raster'] 4435 else: 4436 currRaster = None 4437 4438 rasterType = getRasterType(map=currRaster) 4439 self.rasterCurrent.SetLabel( 4440 _("%(rast)s: type %(type)s") % 4441 {'rast': currRaster, 'type': str(rasterType)}) 4442 4443 # vector legend 4444 if 'rect' in self.vLegendDict: 4445 x, y = self.vLegendDict['rect'][:2] 4446 currUnit = self.unitConv.findUnit( 4447 self.panelVector.units['unitsCtrl'].GetStringSelection()) 4448 x = self.unitConv.convert( 4449 value=x, fromUnit='inch', toUnit=currUnit) 4450 y = self.unitConv.convert( 4451 value=y, fromUnit='inch', toUnit=currUnit) 4452 self.panelVector.position['xCtrl'].SetValue("%5.3f" % x) 4453 self.panelVector.position['yCtrl'].SetValue("%5.3f" % y) 4454 # update vector maps 4455 if self.instruction.FindInstructionByType('vector'): 4456 vectors = sorted( 4457 self.instruction.FindInstructionByType('vector')['list'], 4458 key=lambda x: x[3]) 4459 self.vectorListCtrl.DeleteAllItems() 4460 for vector in vectors: 4461 index = self.vectorListCtrl.InsertItem( 4462 self.vectorListCtrl.GetItemCount(), vector[0].split('@')[0]) 4463 self.vectorListCtrl.SetItem(index, 1, vector[4]) 4464 self.vectorListCtrl.SetItemData(index, index) 4465 self.vectorListCtrl.CheckItem(index, True) 4466 if vector[3] == 0: 4467 self.vectorListCtrl.CheckItem(index, False) 4468 self.panelVector.colsCtrl.SetRange( 4469 1, min(10, len(self.instruction.FindInstructionByType('vector')['list']))) 4470 self.panelVector.colsCtrl.SetValue(1) 4471 else: 4472 self.vectorListCtrl.DeleteAllItems() 4473 self.panelVector.colsCtrl.SetRange(0, 0) 4474 self.panelVector.colsCtrl.SetValue(0) 4475 4476 4477class MapinfoDialog(PsmapDialog): 4478 4479 def __init__(self, parent, id, settings, env): 4480 PsmapDialog.__init__( 4481 self, 4482 parent=parent, 4483 id=id, 4484 title=_("Mapinfo settings"), 4485 settings=settings, 4486 env=env) 4487 4488 self.objectType = ('mapinfo',) 4489 if self.id is not None: 4490 self.mapinfo = self.instruction[self.id] 4491 self.mapinfoDict = self.mapinfo.GetInstruction() 4492 else: 4493 self.id = NewId() 4494 self.mapinfo = Mapinfo(self.id, env=self.env) 4495 self.mapinfoDict = self.mapinfo.GetInstruction() 4496 page = self.instruction.FindInstructionByType( 4497 'page').GetInstruction() 4498 self.mapinfoDict['where'] = page['Left'], page['Top'] 4499 4500 self.panel = self._mapinfoPanel() 4501 4502 self._layout(self.panel) 4503 self.OnIsBackground(None) 4504 self.OnIsBorder(None) 4505 4506 def _mapinfoPanel(self): 4507 panel = Panel( 4508 parent=self, id=wx.ID_ANY, size=(-1, -1), 4509 style=wx.TAB_TRAVERSAL) 4510 #panel.SetupScrolling(scroll_x = False, scroll_y = True) 4511 border = wx.BoxSizer(wx.VERTICAL) 4512 4513 # position 4514 box = StaticBox( 4515 parent=panel, 4516 id=wx.ID_ANY, 4517 label=" %s " % 4518 _("Position")) 4519 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 4520 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 4521 4522 self.AddPosition(parent=panel, dialogDict=self.mapinfoDict) 4523 self.AddUnits(parent=panel, dialogDict=self.mapinfoDict) 4524 gridBagSizer.Add(panel.units['unitsLabel'], pos=( 4525 0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4526 gridBagSizer.Add(panel.units['unitsCtrl'], pos=( 4527 0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4528 gridBagSizer.Add(panel.position['xLabel'], pos=( 4529 1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4530 gridBagSizer.Add(panel.position['xCtrl'], pos=( 4531 1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4532 gridBagSizer.Add(panel.position['yLabel'], pos=( 4533 2, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4534 gridBagSizer.Add(panel.position['yCtrl'], pos=( 4535 2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4536 gridBagSizer.Add( 4537 panel.position['comment'], pos=( 4538 3, 0), span=( 4539 1, 2), flag=wx.ALIGN_BOTTOM, border=0) 4540 4541 gridBagSizer.AddGrowableCol(1) 4542 sizer.Add( 4543 gridBagSizer, 4544 proportion=1, 4545 flag=wx.EXPAND | wx.ALL, 4546 border=5) 4547 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 4548 4549 # font 4550 box = StaticBox( 4551 parent=panel, 4552 id=wx.ID_ANY, 4553 label=" %s " % 4554 _("Font settings")) 4555 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 4556 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 4557 4558 # creates font color too, used below 4559 self.AddFont(parent=panel, dialogDict=self.mapinfoDict) 4560 4561 gridBagSizer.Add(panel.font['fontLabel'], pos=( 4562 0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4563 gridBagSizer.Add( 4564 panel.font['fontCtrl'], 4565 pos=(0, 1), 4566 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4567 gridBagSizer.Add(panel.font['fontSizeLabel'], pos=( 4568 1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4569 gridBagSizer.Add(panel.font['fontSizeCtrl'], pos=( 4570 1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4571 gridBagSizer.Add(panel.font['colorLabel'], pos=( 4572 2, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4573 gridBagSizer.Add(panel.font['colorCtrl'], pos=( 4574 2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4575 4576 gridBagSizer.AddGrowableCol(1) 4577 sizer.Add( 4578 gridBagSizer, 4579 proportion=1, 4580 flag=wx.ALL | wx.EXPAND, 4581 border=1) 4582 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 4583 4584 # colors 4585 box = StaticBox( 4586 parent=panel, 4587 id=wx.ID_ANY, 4588 label=" %s " % 4589 _("Color settings")) 4590 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 4591 flexSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5) 4592 4593 self.colors = {} 4594 self.colors['borderCtrl'] = CheckBox( 4595 panel, id=wx.ID_ANY, label=_("use border color:")) 4596 self.colors['backgroundCtrl'] = CheckBox( 4597 panel, id=wx.ID_ANY, label=_("use background color:")) 4598 self.colors['borderColor'] = ColourPickerCtrl(panel, id=wx.ID_ANY) 4599 self.colors['backgroundColor'] = ColourPickerCtrl( 4600 panel, id=wx.ID_ANY) 4601 4602 if self.mapinfoDict['border'] is None: 4603 self.mapinfoDict['border'] = 'none' 4604 if self.mapinfoDict['border'] != 'none': 4605 self.colors['borderCtrl'].SetValue(True) 4606 self.colors['borderColor'].SetColour( 4607 convertRGB(self.mapinfoDict['border'])) 4608 else: 4609 self.colors['borderCtrl'].SetValue(False) 4610 self.colors['borderColor'].SetColour(convertRGB('black')) 4611 4612 if self.mapinfoDict['background'] is None: 4613 self.mapinfoDict['background'] == 'none' 4614 if self.mapinfoDict['background'] != 'none': 4615 self.colors['backgroundCtrl'].SetValue(True) 4616 self.colors['backgroundColor'].SetColour( 4617 convertRGB(self.mapinfoDict['background'])) 4618 else: 4619 self.colors['backgroundCtrl'].SetValue(False) 4620 self.colors['backgroundColor'].SetColour(convertRGB('white')) 4621 4622 flexSizer.Add( 4623 self.colors['borderCtrl'], 4624 proportion=0, 4625 flag=wx.ALIGN_CENTER_VERTICAL, 4626 border=0) 4627 flexSizer.Add( 4628 self.colors['borderColor'], 4629 proportion=0, 4630 flag=wx.ALIGN_CENTER_VERTICAL, 4631 border=0) 4632 flexSizer.Add( 4633 self.colors['backgroundCtrl'], 4634 proportion=0, 4635 flag=wx.ALIGN_CENTER_VERTICAL, 4636 border=0) 4637 flexSizer.Add( 4638 self.colors['backgroundColor'], 4639 proportion=0, 4640 flag=wx.ALIGN_CENTER_VERTICAL, 4641 border=0) 4642 flexSizer.AddGrowableCol(1) 4643 4644 sizer.Add( 4645 flexSizer, 4646 proportion=1, 4647 flag=wx.ALL | wx.EXPAND, 4648 border=1) 4649 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 4650 4651 panel.SetSizer(border) 4652 4653 self.Bind(wx.EVT_CHECKBOX, self.OnIsBorder, self.colors['borderCtrl']) 4654 self.Bind( 4655 wx.EVT_CHECKBOX, 4656 self.OnIsBackground, 4657 self.colors['backgroundCtrl']) 4658 4659 return panel 4660 4661 def OnIsBackground(self, event): 4662 if self.colors['backgroundCtrl'].GetValue(): 4663 self.colors['backgroundColor'].Enable() 4664 self.update() 4665 else: 4666 self.colors['backgroundColor'].Disable() 4667 4668 def OnIsBorder(self, event): 4669 if self.colors['borderCtrl'].GetValue(): 4670 self.colors['borderColor'].Enable() 4671 self.update() 4672 else: 4673 self.colors['borderColor'].Disable() 4674 4675 def update(self): 4676 4677 # units 4678 currUnit = self.unitConv.findUnit( 4679 self.panel.units['unitsCtrl'].GetStringSelection()) 4680 self.mapinfoDict['unit'] = currUnit 4681 4682 # position 4683 if self.panel.position['xCtrl'].GetValue(): 4684 x = self.panel.position['xCtrl'].GetValue() 4685 else: 4686 x = self.mapinfoDict['where'][0] 4687 4688 if self.panel.position['yCtrl'].GetValue(): 4689 y = self.panel.position['yCtrl'].GetValue() 4690 else: 4691 y = self.mapinfoDict['where'][1] 4692 4693 x = self.unitConv.convert( 4694 value=float( 4695 self.panel.position['xCtrl'].GetValue()), 4696 fromUnit=currUnit, 4697 toUnit='inch') 4698 y = self.unitConv.convert( 4699 value=float( 4700 self.panel.position['yCtrl'].GetValue()), 4701 fromUnit=currUnit, 4702 toUnit='inch') 4703 self.mapinfoDict['where'] = (x, y) 4704 4705 # font 4706 self.mapinfoDict['font'] = self.panel.font[ 4707 'fontCtrl'].GetStringSelection() 4708 self.mapinfoDict['fontsize'] = self.panel.font[ 4709 'fontSizeCtrl'].GetValue() 4710 4711 # colors 4712 color = self.panel.font['colorCtrl'].GetColour() 4713 self.mapinfoDict['color'] = convertRGB(color) 4714 4715 if self.colors['backgroundCtrl'].GetValue(): 4716 background = self.colors['backgroundColor'].GetColour() 4717 self.mapinfoDict['background'] = convertRGB(background) 4718 else: 4719 self.mapinfoDict['background'] = 'none' 4720 4721 if self.colors['borderCtrl'].GetValue(): 4722 border = self.colors['borderColor'].GetColour() 4723 self.mapinfoDict['border'] = convertRGB(border) 4724 else: 4725 self.mapinfoDict['border'] = 'none' 4726 4727 # estimation of size 4728 self.mapinfoDict['rect'] = self.mapinfo.EstimateRect(self.mapinfoDict) 4729 4730 if self.id not in self.instruction: 4731 mapinfo = Mapinfo(self.id, env=self.env) 4732 self.instruction.AddInstruction(mapinfo) 4733 4734 self.instruction[self.id].SetInstruction(self.mapinfoDict) 4735 4736 if self.id not in self.parent.objectId: 4737 self.parent.objectId.append(self.id) 4738 4739 self.updateDialog() 4740 4741 return True 4742 4743 def updateDialog(self): 4744 """Update mapinfo coordinates, after moving""" 4745 x, y = self.mapinfoDict['where'] 4746 currUnit = self.unitConv.findUnit( 4747 self.panel.units['unitsCtrl'].GetStringSelection()) 4748 x = self.unitConv.convert(value=x, fromUnit='inch', toUnit=currUnit) 4749 y = self.unitConv.convert(value=y, fromUnit='inch', toUnit=currUnit) 4750 self.panel.position['xCtrl'].SetValue("%5.3f" % x) 4751 self.panel.position['yCtrl'].SetValue("%5.3f" % y) 4752 4753 4754class ScalebarDialog(PsmapDialog): 4755 """Dialog for scale bar""" 4756 4757 def __init__(self, parent, id, settings, env): 4758 PsmapDialog.__init__( 4759 self, 4760 parent=parent, 4761 id=id, 4762 title="Scale bar settings", 4763 settings=settings, 4764 env=env) 4765 self.objectType = ('scalebar',) 4766 if self.id is not None: 4767 self.scalebar = self.instruction[id] 4768 self.scalebarDict = self.scalebar.GetInstruction() 4769 else: 4770 self.id = NewId() 4771 self.scalebar = Scalebar(self.id, env=self.env) 4772 self.scalebarDict = self.scalebar.GetInstruction() 4773 page = self.instruction.FindInstructionByType( 4774 'page').GetInstruction() 4775 self.scalebarDict['where'] = page['Left'], page['Top'] 4776 4777 self.panel = self._scalebarPanel() 4778 4779 self._layout(self.panel) 4780 4781 self.mapUnit = projInfo()['units'].lower() 4782 if projInfo()['proj'] == 'xy': 4783 self.mapUnit = 'meters' 4784 if self.mapUnit not in self.unitConv.getAllUnits(): 4785 self.mapUnit = 'meters' 4786 4787 def _scalebarPanel(self): 4788 panel = Panel(parent=self, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL) 4789 border = wx.BoxSizer(wx.VERTICAL) 4790 # 4791 # position 4792 # 4793 box = StaticBox( 4794 parent=panel, 4795 id=wx.ID_ANY, 4796 label=" %s " % 4797 _("Position")) 4798 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 4799 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 4800 4801 self.AddUnits(parent=panel, dialogDict=self.scalebarDict) 4802 self.AddPosition(parent=panel, dialogDict=self.scalebarDict) 4803 4804 if self.scalebarDict[ 4805 'rect']: # set position, ref point is center and not left top corner 4806 4807 x = self.unitConv.convert( 4808 value=self.scalebarDict['where'][0] - 4809 self.scalebarDict['rect'].Get()[2] / 4810 2, 4811 fromUnit='inch', 4812 toUnit=self.scalebarDict['unit']) 4813 y = self.unitConv.convert( 4814 value=self.scalebarDict['where'][1] - 4815 self.scalebarDict['rect'].Get()[3] / 4816 2, 4817 fromUnit='inch', 4818 toUnit=self.scalebarDict['unit']) 4819 panel.position['xCtrl'].SetValue("%5.3f" % x) 4820 panel.position['yCtrl'].SetValue("%5.3f" % y) 4821 4822 gridBagSizer.Add(panel.units['unitsLabel'], pos=( 4823 0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4824 gridBagSizer.Add(panel.units['unitsCtrl'], pos=( 4825 0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4826 gridBagSizer.Add(panel.position['xLabel'], pos=( 4827 1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4828 gridBagSizer.Add(panel.position['xCtrl'], pos=( 4829 1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4830 gridBagSizer.Add(panel.position['yLabel'], pos=( 4831 2, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4832 gridBagSizer.Add(panel.position['yCtrl'], pos=( 4833 2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4834 gridBagSizer.Add( 4835 panel.position['comment'], pos=( 4836 3, 0), span=( 4837 1, 2), flag=wx.ALIGN_BOTTOM, border=0) 4838 4839 gridBagSizer.AddGrowableCol(1) 4840 sizer.Add( 4841 gridBagSizer, 4842 proportion=1, 4843 flag=wx.EXPAND | wx.ALL, 4844 border=5) 4845 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 4846 # 4847 # size 4848 # 4849 box = StaticBox( 4850 parent=panel, 4851 id=wx.ID_ANY, 4852 label=" %s " % 4853 _("Size")) 4854 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 4855 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 4856 4857 lengthText = StaticText(panel, id=wx.ID_ANY, label=_("Length:")) 4858 heightText = StaticText(panel, id=wx.ID_ANY, label=_("Height:")) 4859 4860 self.lengthTextCtrl = TextCtrl( 4861 panel, id=wx.ID_ANY, validator=TCValidator('DIGIT_ONLY')) 4862 self.lengthTextCtrl.SetToolTip( 4863 _("Scalebar length is given in map units")) 4864 4865 self.heightTextCtrl = TextCtrl( 4866 panel, id=wx.ID_ANY, validator=TCValidator('DIGIT_ONLY')) 4867 self.heightTextCtrl.SetToolTip( 4868 _("Scalebar height is real height on paper")) 4869 4870 choices = [_('default')] + self.unitConv.getMapUnitsNames() 4871 self.unitsLength = Choice(panel, id=wx.ID_ANY, choices=choices) 4872 choices = self.unitConv.getPageUnitsNames() 4873 self.unitsHeight = Choice(panel, id=wx.ID_ANY, choices=choices) 4874 4875 # set values 4876 unitName = self.unitConv.findName(self.scalebarDict['unitsLength']) 4877 if unitName: 4878 self.unitsLength.SetStringSelection(unitName) 4879 else: 4880 if self.scalebarDict['unitsLength'] == 'auto': 4881 self.unitsLength.SetSelection(0) 4882 elif self.scalebarDict['unitsLength'] == 'nautmiles': 4883 self.unitsLength.SetStringSelection( 4884 self.unitConv.findName("nautical miles")) 4885 self.unitsHeight.SetStringSelection( 4886 self.unitConv.findName( 4887 self.scalebarDict['unitsHeight'])) 4888 if self.scalebarDict['length']: 4889 self.lengthTextCtrl.SetValue(str(self.scalebarDict['length'])) 4890 else: # estimate default 4891 reg = grass.region(env=self.env) 4892 w = int((reg['e'] - reg['w']) / 3) 4893 w = round(w, -len(str(w)) + 2) # 12345 -> 12000 4894 self.lengthTextCtrl.SetValue(str(w)) 4895 4896 h = self.unitConv.convert( 4897 value=self.scalebarDict['height'], 4898 fromUnit='inch', 4899 toUnit=self.scalebarDict['unitsHeight']) 4900 self.heightTextCtrl.SetValue(str(h)) 4901 4902 gridBagSizer.Add( 4903 lengthText, pos=(0, 0), 4904 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4905 gridBagSizer.Add( 4906 self.lengthTextCtrl, pos=(0, 1), 4907 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4908 gridBagSizer.Add( 4909 self.unitsLength, 4910 pos=( 4911 0, 4912 2), 4913 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 4914 border=0) 4915 gridBagSizer.Add( 4916 heightText, pos=(1, 0), 4917 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4918 gridBagSizer.Add( 4919 self.heightTextCtrl, pos=(1, 1), 4920 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4921 gridBagSizer.Add( 4922 self.unitsHeight, 4923 pos=( 4924 1, 4925 2), 4926 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 4927 border=0) 4928 4929 gridBagSizer.AddGrowableCol(1) 4930 sizer.Add( 4931 gridBagSizer, 4932 proportion=1, 4933 flag=wx.EXPAND | wx.ALL, 4934 border=5) 4935 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 4936 # 4937 # style 4938 # 4939 box = StaticBox( 4940 parent=panel, 4941 id=wx.ID_ANY, 4942 label=" %s " % 4943 _("Style")) 4944 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 4945 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 4946 4947 sbTypeText = StaticText(panel, id=wx.ID_ANY, label=_("Type:")) 4948 self.sbCombo = BitmapComboBox(panel, style=wx.CB_READONLY) 4949 # only temporary, images must be moved away 4950 imagePath = os.path.join( 4951 globalvar.IMGDIR, "scalebar-fancy.png"), os.path.join( 4952 globalvar.IMGDIR, "scalebar-simple.png") 4953 for item, path in zip(['fancy', 'simple'], imagePath): 4954 if not os.path.exists(path): 4955 bitmap = EmptyBitmap(0, 0) 4956 else: 4957 bitmap = wx.Bitmap(path) 4958 self.sbCombo.Append(item='', bitmap=bitmap, clientData=item[0]) 4959 #self.sbCombo.Append(item = 'simple', bitmap = wx.Bitmap("./images/scalebar-simple.png"), clientData = 's') 4960 if self.scalebarDict['scalebar'] == 'f': 4961 self.sbCombo.SetSelection(0) 4962 elif self.scalebarDict['scalebar'] == 's': 4963 self.sbCombo.SetSelection(1) 4964 4965 sbSegmentsText = StaticText( 4966 panel, id=wx.ID_ANY, label=_("Number of segments:")) 4967 self.sbSegmentsCtrl = SpinCtrl( 4968 panel, id=wx.ID_ANY, min=1, max=30, initial=4) 4969 self.sbSegmentsCtrl.SetValue(self.scalebarDict['segment']) 4970 4971 sbLabelsText1 = StaticText( 4972 panel, id=wx.ID_ANY, label=_("Label every ")) 4973 sbLabelsText2 = StaticText(panel, id=wx.ID_ANY, label=_("segments")) 4974 self.sbLabelsCtrl = SpinCtrl( 4975 panel, id=wx.ID_ANY, min=1, max=30, initial=1) 4976 self.sbLabelsCtrl.SetValue(self.scalebarDict['numbers']) 4977 4978 # font 4979 fontsizeText = StaticText( 4980 panel, id=wx.ID_ANY, label=_("Font size:")) 4981 self.fontsizeCtrl = SpinCtrl( 4982 panel, id=wx.ID_ANY, min=4, max=30, initial=10) 4983 self.fontsizeCtrl.SetValue(self.scalebarDict['fontsize']) 4984 4985 self.backgroundCheck = CheckBox( 4986 panel, id=wx.ID_ANY, label=_("transparent text background")) 4987 if self.scalebarDict['background'] == 'y': 4988 self.backgroundCheck.SetValue(False) 4989 else: 4990 self.backgroundCheck.SetValue(True) 4991 4992 gridBagSizer.Add( 4993 sbTypeText, pos=(0, 0), 4994 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 4995 gridBagSizer.Add( 4996 self.sbCombo, pos=( 4997 0, 1), span=( 4998 1, 2), flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, border=0) 4999 gridBagSizer.Add( 5000 sbSegmentsText, pos=(1, 0), 5001 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5002 gridBagSizer.Add( 5003 self.sbSegmentsCtrl, pos=(1, 1), 5004 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5005 gridBagSizer.Add( 5006 sbLabelsText1, pos=(2, 0), 5007 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5008 gridBagSizer.Add( 5009 self.sbLabelsCtrl, pos=(2, 1), 5010 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5011 gridBagSizer.Add( 5012 sbLabelsText2, pos=(2, 2), 5013 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5014 gridBagSizer.Add( 5015 fontsizeText, pos=(3, 0), 5016 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5017 gridBagSizer.Add( 5018 self.fontsizeCtrl, pos=(3, 1), 5019 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5020 gridBagSizer.Add( 5021 self.backgroundCheck, pos=( 5022 4, 0), span=( 5023 1, 3), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5024 5025 sizer.Add( 5026 gridBagSizer, 5027 proportion=1, 5028 border=5) 5029 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 5030 5031 panel.SetSizer(border) 5032 5033 return panel 5034 5035 def update(self): 5036 """Save information from dialog""" 5037 5038 # units 5039 currUnit = self.unitConv.findUnit( 5040 self.panel.units['unitsCtrl'].GetStringSelection()) 5041 self.scalebarDict['unit'] = currUnit 5042 # position 5043 if self.panel.position['xCtrl'].GetValue(): 5044 x = self.panel.position['xCtrl'].GetValue() 5045 else: 5046 x = self.scalebarDict['where'][0] 5047 5048 if self.panel.position['yCtrl'].GetValue(): 5049 y = self.panel.position['yCtrl'].GetValue() 5050 else: 5051 y = self.scalebarDict['where'][1] 5052 5053 x = self.unitConv.convert( 5054 value=float( 5055 self.panel.position['xCtrl'].GetValue()), 5056 fromUnit=currUnit, 5057 toUnit='inch') 5058 y = self.unitConv.convert( 5059 value=float( 5060 self.panel.position['yCtrl'].GetValue()), 5061 fromUnit=currUnit, 5062 toUnit='inch') 5063 5064 # style 5065 self.scalebarDict['scalebar'] = self.sbCombo.GetClientData( 5066 self.sbCombo.GetSelection()) 5067 self.scalebarDict['segment'] = self.sbSegmentsCtrl.GetValue() 5068 self.scalebarDict['numbers'] = self.sbLabelsCtrl.GetValue() 5069 self.scalebarDict['fontsize'] = self.fontsizeCtrl.GetValue() 5070 if self.backgroundCheck.GetValue(): 5071 self.scalebarDict['background'] = 'n' 5072 else: 5073 self.scalebarDict['background'] = 'y' 5074 5075 # size 5076 5077 # height 5078 self.scalebarDict['unitsHeight'] = self.unitConv.findUnit( 5079 self.unitsHeight.GetStringSelection()) 5080 try: 5081 height = float(self.heightTextCtrl.GetValue()) 5082 height = self.unitConv.convert( 5083 value=height, 5084 fromUnit=self.scalebarDict['unitsHeight'], 5085 toUnit='inch') 5086 except (ValueError, SyntaxError): 5087 height = 0.1 # default in inch 5088 self.scalebarDict['height'] = height 5089 5090 # length 5091 if self.unitsLength.GetSelection() == 0: 5092 selected = 'auto' 5093 else: 5094 selected = self.unitConv.findUnit( 5095 self.unitsLength.GetStringSelection()) 5096 if selected == 'nautical miles': 5097 selected = 'nautmiles' 5098 self.scalebarDict['unitsLength'] = selected 5099 try: 5100 length = float(self.lengthTextCtrl.GetValue()) 5101 except (ValueError, SyntaxError): 5102 wx.MessageBox( 5103 message=_("Length of scale bar is not defined"), 5104 caption=_('Invalid input'), 5105 style=wx.OK | wx.ICON_ERROR) 5106 return False 5107 self.scalebarDict['length'] = length 5108 5109 # estimation of size 5110 map = self.instruction.FindInstructionByType('map') 5111 if not map: 5112 map = self.instruction.FindInstructionByType('initMap') 5113 mapId = map.id 5114 5115 rectSize = self.scalebar.EstimateSize( 5116 scalebarDict=self.scalebarDict, 5117 scale=self.instruction[mapId]['scale']) 5118 self.scalebarDict['rect'] = Rect2D( 5119 x=x, y=y, width=rectSize[0], height=rectSize[1]) 5120 self.scalebarDict['where'] = self.scalebarDict['rect'].GetCentre() 5121 5122 if self.id not in self.instruction: 5123 scalebar = Scalebar(self.id, env=self.env) 5124 self.instruction.AddInstruction(scalebar) 5125 self.instruction[self.id].SetInstruction(self.scalebarDict) 5126 if self.id not in self.parent.objectId: 5127 self.parent.objectId.append(self.id) 5128 5129 return True 5130 5131 def updateDialog(self): 5132 """Update scalebar coordinates, after moving""" 5133 x, y = self.scalebarDict['rect'][:2] 5134 currUnit = self.unitConv.findUnit( 5135 self.panel.units['unitsCtrl'].GetStringSelection()) 5136 x = self.unitConv.convert(value=x, fromUnit='inch', toUnit=currUnit) 5137 y = self.unitConv.convert(value=y, fromUnit='inch', toUnit=currUnit) 5138 self.panel.position['xCtrl'].SetValue("%5.3f" % x) 5139 self.panel.position['yCtrl'].SetValue("%5.3f" % y) 5140 5141 5142class TextDialog(PsmapDialog): 5143 5144 def __init__(self, parent, id, settings, env): 5145 PsmapDialog.__init__( 5146 self, 5147 parent=parent, 5148 id=id, 5149 title="Text settings", 5150 settings=settings, 5151 env=env) 5152 self.objectType = ('text',) 5153 if self.id is not None: 5154 self.textDict = self.instruction[id].GetInstruction() 5155 else: 5156 self.id = NewId() 5157 text = Text(self.id, env=self.env) 5158 self.textDict = text.GetInstruction() 5159 page = self.instruction.FindInstructionByType( 5160 'page').GetInstruction() 5161 self.textDict['where'] = page['Left'], page['Top'] 5162 5163 map = self.instruction.FindInstructionByType('map') 5164 if not map: 5165 map = self.instruction.FindInstructionByType('initMap') 5166 self.mapId = map.id 5167 5168 self.textDict['east'], self.textDict['north'] = PaperMapCoordinates( 5169 mapInstr=map, x=self.textDict['where'][0], 5170 y=self.textDict['where'][1], 5171 paperToMap=True, 5172 env=self.env) 5173 5174 notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT) 5175 self.textPanel = self._textPanel(notebook) 5176 self.positionPanel = self._positionPanel(notebook) 5177 self.OnBackground(None) 5178 self.OnHighlight(None) 5179 self.OnBorder(None) 5180 self.OnPositionType(None) 5181 self.OnRotation(None) 5182 5183 self._layout(notebook) 5184 5185 def _textPanel(self, notebook): 5186 panel = Panel(parent=notebook, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL) 5187 notebook.AddPage(page=panel, text=_("Text")) 5188 5189 border = wx.BoxSizer(wx.VERTICAL) 5190 5191 # text entry 5192 box = StaticBox( 5193 parent=panel, 5194 id=wx.ID_ANY, 5195 label=" %s " % 5196 _("Text")) 5197 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 5198 5199 textLabel = StaticText(panel, id=wx.ID_ANY, label=_("Enter text:")) 5200 self.textCtrl = ExpandoTextCtrl( 5201 panel, id=wx.ID_ANY, value=self.textDict['text']) 5202 5203 sizer.Add( 5204 textLabel, 5205 proportion=0, 5206 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5207 border=5) 5208 sizer.Add( 5209 self.textCtrl, 5210 proportion=1, 5211 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5212 border=5) 5213 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 5214 5215 # font 5216 box = StaticBox( 5217 parent=panel, 5218 id=wx.ID_ANY, 5219 label=" %s " % 5220 _("Font settings")) 5221 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 5222 flexGridSizer = wx.FlexGridSizer(rows=3, cols=2, hgap=5, vgap=5) 5223 5224 self.AddFont(parent=panel, dialogDict=self.textDict) 5225 5226 flexGridSizer.Add( 5227 panel.font['fontLabel'], 5228 proportion=0, 5229 flag=wx.ALIGN_CENTER_VERTICAL, 5230 border=0) 5231 flexGridSizer.Add( 5232 panel.font['fontCtrl'], 5233 proportion=0, 5234 flag=wx.ALIGN_CENTER_VERTICAL, 5235 border=0) 5236 flexGridSizer.Add( 5237 panel.font['fontSizeLabel'], 5238 proportion=0, 5239 flag=wx.ALIGN_CENTER_VERTICAL, 5240 border=0) 5241 flexGridSizer.Add( 5242 panel.font['fontSizeCtrl'], 5243 proportion=0, 5244 flag=wx.ALIGN_CENTER_VERTICAL, 5245 border=0) 5246 flexGridSizer.Add( 5247 panel.font['colorLabel'], 5248 proportion=0, 5249 flag=wx.ALIGN_CENTER_VERTICAL, 5250 border=0) 5251 flexGridSizer.Add( 5252 panel.font['colorCtrl'], 5253 proportion=0, 5254 flag=wx.ALIGN_CENTER_VERTICAL, 5255 border=0) 5256 flexGridSizer.AddGrowableCol(1) 5257 5258 sizer.Add( 5259 flexGridSizer, 5260 proportion=1, 5261 flag=wx.ALL | wx.EXPAND, 5262 border=1) 5263 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 5264 5265 # text effects 5266 box = StaticBox( 5267 parent=panel, 5268 id=wx.ID_ANY, 5269 label=" %s " % 5270 _("Text effects")) 5271 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 5272 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 5273 5274 self.effect = {} 5275 self.effect['backgroundCtrl'] = CheckBox( 5276 panel, id=wx.ID_ANY, label=_("text background")) 5277 self.effect['backgroundColor'] = ColourPickerCtrl( 5278 panel, id=wx.ID_ANY) 5279 5280 self.effect['highlightCtrl'] = CheckBox( 5281 panel, id=wx.ID_ANY, label=_("highlight")) 5282 self.effect['highlightColor'] = ColourPickerCtrl( 5283 panel, id=wx.ID_ANY) 5284 self.effect['highlightWidth'] = SpinCtrl( 5285 panel, id=wx.ID_ANY, size=self.spinCtrlSize, min=0, max=5, initial=1) 5286 self.effect['highlightWidthLabel'] = StaticText( 5287 panel, id=wx.ID_ANY, label=_("Width (pts):")) 5288 5289 self.effect['borderCtrl'] = CheckBox( 5290 panel, id=wx.ID_ANY, label=_("text border")) 5291 self.effect['borderColor'] = ColourPickerCtrl(panel, id=wx.ID_ANY) 5292 self.effect['borderWidth'] = SpinCtrl( 5293 panel, id=wx.ID_ANY, size=self.spinCtrlSize, min=1, max=25, initial=1) 5294 self.effect['borderWidthLabel'] = StaticText( 5295 panel, id=wx.ID_ANY, label=_("Width (pts):")) 5296 5297 # set values 5298 if self.textDict['background'] is None: 5299 self.textDict['background'] = 'none' 5300 if self.textDict['background'] != 'none': 5301 self.effect['backgroundCtrl'].SetValue(True) 5302 self.effect['backgroundColor'].SetColour( 5303 convertRGB(self.textDict['background'])) 5304 else: 5305 self.effect['backgroundCtrl'].SetValue(False) 5306 self.effect['backgroundColor'].SetColour(convertRGB('white')) 5307 5308 if self.textDict['hcolor'] is None: 5309 self.textDict['hcolor'] = 'none' 5310 if self.textDict['hcolor'] != 'none': 5311 self.effect['highlightCtrl'].SetValue(True) 5312 self.effect['highlightColor'].SetColour( 5313 convertRGB(self.textDict['hcolor'])) 5314 else: 5315 self.effect['highlightCtrl'].SetValue(False) 5316 self.effect['highlightColor'].SetColour(convertRGB('grey')) 5317 5318 self.effect['highlightWidth'].SetValue(float(self.textDict['hwidth'])) 5319 5320 if self.textDict['border'] is None: 5321 self.textDict['border'] = 'none' 5322 if self.textDict['border'] != 'none': 5323 self.effect['borderCtrl'].SetValue(True) 5324 self.effect['borderColor'].SetColour( 5325 convertRGB(self.textDict['border'])) 5326 else: 5327 self.effect['borderCtrl'].SetValue(False) 5328 self.effect['borderColor'].SetColour(convertRGB('black')) 5329 5330 self.effect['borderWidth'].SetValue(float(self.textDict['width'])) 5331 5332 gridBagSizer.Add(self.effect['backgroundCtrl'], pos=( 5333 0, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5334 gridBagSizer.Add(self.effect['backgroundColor'], pos=( 5335 0, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5336 gridBagSizer.Add(self.effect['highlightCtrl'], pos=( 5337 1, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5338 gridBagSizer.Add(self.effect['highlightColor'], pos=( 5339 1, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5340 gridBagSizer.Add( 5341 self.effect['highlightWidthLabel'], pos=( 5342 1, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5343 gridBagSizer.Add(self.effect['highlightWidth'], pos=( 5344 1, 3), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5345 gridBagSizer.Add(self.effect['borderCtrl'], pos=( 5346 2, 0), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5347 gridBagSizer.Add(self.effect['borderColor'], pos=( 5348 2, 1), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5349 gridBagSizer.Add(self.effect['borderWidthLabel'], pos=( 5350 2, 2), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5351 gridBagSizer.Add(self.effect['borderWidth'], pos=( 5352 2, 3), flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5353 5354 sizer.Add( 5355 gridBagSizer, 5356 proportion=1, 5357 flag=wx.ALL | wx.EXPAND, 5358 border=1) 5359 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 5360 5361 self.Bind(ExpandoTextCtrl.EVT_ETC_LAYOUT_NEEDED, self.OnRefit, self.textCtrl) 5362 self.Bind( 5363 wx.EVT_CHECKBOX, 5364 self.OnBackground, 5365 self.effect['backgroundCtrl']) 5366 self.Bind( 5367 wx.EVT_CHECKBOX, 5368 self.OnHighlight, 5369 self.effect['highlightCtrl']) 5370 self.Bind(wx.EVT_CHECKBOX, self.OnBorder, self.effect['borderCtrl']) 5371 5372 panel.SetSizer(border) 5373 panel.Fit() 5374 5375 return panel 5376 5377 def _positionPanel(self, notebook): 5378 panel = Panel(parent=notebook, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL) 5379 notebook.AddPage(page=panel, text=_("Position")) 5380 5381 border = wx.BoxSizer(wx.VERTICAL) 5382 5383 box = StaticBox( 5384 parent=panel, 5385 id=wx.ID_ANY, 5386 label=" %s " % 5387 _("Position")) 5388 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 5389 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 5390 5391 # Position 5392 self.AddExtendedPosition(panel, gridBagSizer, self.textDict) 5393 5394 # offset 5395 box3 = StaticBox( 5396 parent=panel, 5397 id=wx.ID_ANY, 5398 label=" %s " % 5399 _("Offset")) 5400 sizerO = wx.StaticBoxSizer(box3, wx.VERTICAL) 5401 gridBagSizerO = wx.GridBagSizer(hgap=5, vgap=5) 5402 self.xoffLabel = StaticText( 5403 panel, id=wx.ID_ANY, label=_("horizontal (pts):")) 5404 self.yoffLabel = StaticText( 5405 panel, id=wx.ID_ANY, label=_("vertical (pts):")) 5406 self.xoffCtrl = SpinCtrl( 5407 panel, id=wx.ID_ANY, size=(50, -1), 5408 min=-50, max=50, initial=0) 5409 self.yoffCtrl = SpinCtrl( 5410 panel, id=wx.ID_ANY, size=(50, -1), 5411 min=-50, max=50, initial=0) 5412 self.xoffCtrl.SetValue(self.textDict['xoffset']) 5413 self.yoffCtrl.SetValue(self.textDict['yoffset']) 5414 gridBagSizerO.Add( 5415 self.xoffLabel, pos=(0, 0), 5416 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5417 gridBagSizerO.Add( 5418 self.yoffLabel, pos=(1, 0), 5419 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5420 gridBagSizerO.Add( 5421 self.xoffCtrl, pos=(0, 1), 5422 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5423 gridBagSizerO.Add( 5424 self.yoffCtrl, pos=(1, 1), 5425 flag=wx.ALIGN_CENTER_VERTICAL, border=0) 5426 5427 sizerO.Add( 5428 gridBagSizerO, 5429 proportion=1, 5430 flag=wx.EXPAND | wx.ALL, 5431 border=5) 5432 gridBagSizer.Add( 5433 sizerO, 5434 pos=( 5435 3, 5436 0), 5437 flag=wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND, 5438 border=0) 5439 # reference point 5440 box = StaticBox( 5441 parent=panel, 5442 id=wx.ID_ANY, 5443 label=" %s " % 5444 _(" Reference point")) 5445 sizerR = wx.StaticBoxSizer(box, wx.VERTICAL) 5446 flexSizer = wx.FlexGridSizer(rows=3, cols=3, hgap=5, vgap=5) 5447 ref = [] 5448 for row in ["upper", "center", "lower"]: 5449 for col in ["left", "center", "right"]: 5450 ref.append(row + " " + col) 5451 self.radio = [ 5452 RadioButton( 5453 panel, 5454 id=wx.ID_ANY, 5455 label='', 5456 style=wx.RB_GROUP, 5457 name=ref[0])] 5458 self.radio[0].SetValue(False) 5459 flexSizer.Add( 5460 self.radio[0], 5461 proportion=0, 5462 flag=wx.ALIGN_CENTER, 5463 border=0) 5464 for i in range(1, 9): 5465 self.radio.append( 5466 RadioButton( 5467 panel, 5468 id=wx.ID_ANY, 5469 label='', 5470 name=ref[i])) 5471 self.radio[-1].SetValue(False) 5472 flexSizer.Add(self.radio[-1], proportion=0, 5473 flag=wx.ALIGN_CENTER, border=0) 5474 self.FindWindowByName(self.textDict['ref']).SetValue(True) 5475 flexSizer.AddGrowableCol(0) 5476 flexSizer.AddGrowableCol(1) 5477 flexSizer.AddGrowableCol(2) 5478 5479 sizerR.Add(flexSizer, proportion=1, flag=wx.EXPAND, border=0) 5480 gridBagSizer.Add( 5481 sizerR, pos=(3, 1), 5482 flag=wx.ALIGN_LEFT | wx.EXPAND, border=0) 5483 gridBagSizer.AddGrowableCol(0) 5484 gridBagSizer.AddGrowableCol(1) 5485 5486 sizer.Add( 5487 gridBagSizer, 5488 proportion=1, 5489 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, 5490 border=5) 5491 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 5492 5493 # rotation 5494 box = StaticBox( 5495 parent=panel, 5496 id=wx.ID_ANY, 5497 label=" %s " % 5498 _("Text rotation")) 5499 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 5500 5501 self.rotCtrl = CheckBox( 5502 panel, 5503 id=wx.ID_ANY, 5504 label=_("rotate text (counterclockwise)")) 5505 self.rotValue = SpinCtrl( 5506 panel, wx.ID_ANY, size=(50, -1), 5507 min=0, max=360, initial=0) 5508 if self.textDict['rotate']: 5509 self.rotValue.SetValue(int(self.textDict['rotate'])) 5510 self.rotCtrl.SetValue(True) 5511 else: 5512 self.rotValue.SetValue(0) 5513 self.rotCtrl.SetValue(False) 5514 sizer.Add( 5515 self.rotCtrl, 5516 proportion=0, 5517 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5518 border=5) 5519 sizer.Add( 5520 self.rotValue, 5521 proportion=0, 5522 flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL, 5523 border=5) 5524 5525 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 5526 5527 panel.SetSizer(border) 5528 panel.Fit() 5529 5530 self.Bind( 5531 wx.EVT_RADIOBUTTON, 5532 self.OnPositionType, 5533 panel.position['toPaper']) 5534 self.Bind( 5535 wx.EVT_RADIOBUTTON, 5536 self.OnPositionType, 5537 panel.position['toMap']) 5538 self.Bind(wx.EVT_CHECKBOX, self.OnRotation, self.rotCtrl) 5539 5540 return panel 5541 5542 def OnRefit(self, event): 5543 self.Fit() 5544 5545 def OnRotation(self, event): 5546 if self.rotCtrl.GetValue(): 5547 self.rotValue.Enable() 5548 else: 5549 self.rotValue.Disable() 5550 5551 def OnPositionType(self, event): 5552 if self.positionPanel.position['toPaper'].GetValue(): 5553 for widget in self.gridBagSizerP.GetChildren(): 5554 widget.GetWindow().Enable() 5555 for widget in self.gridBagSizerM.GetChildren(): 5556 widget.GetWindow().Disable() 5557 else: 5558 for widget in self.gridBagSizerM.GetChildren(): 5559 widget.GetWindow().Enable() 5560 for widget in self.gridBagSizerP.GetChildren(): 5561 widget.GetWindow().Disable() 5562 5563 def OnBackground(self, event): 5564 if self.effect['backgroundCtrl'].GetValue(): 5565 self.effect['backgroundColor'].Enable() 5566 self.update() 5567 else: 5568 self.effect['backgroundColor'].Disable() 5569 5570 def OnHighlight(self, event): 5571 if self.effect['highlightCtrl'].GetValue(): 5572 self.effect['highlightColor'].Enable() 5573 self.effect['highlightWidth'].Enable() 5574 self.effect['highlightWidthLabel'].Enable() 5575 self.update() 5576 else: 5577 self.effect['highlightColor'].Disable() 5578 self.effect['highlightWidth'].Disable() 5579 self.effect['highlightWidthLabel'].Disable() 5580 5581 def OnBorder(self, event): 5582 if self.effect['borderCtrl'].GetValue(): 5583 self.effect['borderColor'].Enable() 5584 self.effect['borderWidth'].Enable() 5585 self.effect['borderWidthLabel'].Enable() 5586 self.update() 5587 else: 5588 self.effect['borderColor'].Disable() 5589 self.effect['borderWidth'].Disable() 5590 self.effect['borderWidthLabel'].Disable() 5591 5592 def update(self): 5593 # text 5594 self.textDict['text'] = self.textCtrl.GetValue() 5595 if not self.textDict['text']: 5596 wx.MessageBox(_("No text entered!"), _("Error")) 5597 return False 5598 5599 # font 5600 self.textDict['font'] = self.textPanel.font[ 5601 'fontCtrl'].GetStringSelection() 5602 self.textDict['fontsize'] = self.textPanel.font[ 5603 'fontSizeCtrl'].GetValue() 5604 color = self.textPanel.font['colorCtrl'].GetColour() 5605 self.textDict['color'] = convertRGB(color) 5606 5607 # effects 5608 if self.effect['backgroundCtrl'].GetValue(): 5609 background = self.effect['backgroundColor'].GetColour() 5610 self.textDict['background'] = convertRGB(background) 5611 else: 5612 self.textDict['background'] = 'none' 5613 5614 if self.effect['borderCtrl'].GetValue(): 5615 border = self.effect['borderColor'].GetColour() 5616 self.textDict['border'] = convertRGB(border) 5617 else: 5618 self.textDict['border'] = 'none' 5619 5620 self.textDict['width'] = self.effect['borderWidth'].GetValue() 5621 5622 if self.effect['highlightCtrl'].GetValue(): 5623 highlight = self.effect['highlightColor'].GetColour() 5624 self.textDict['hcolor'] = convertRGB(highlight) 5625 else: 5626 self.textDict['hcolor'] = 'none' 5627 5628 self.textDict['hwidth'] = self.effect['highlightWidth'].GetValue() 5629 5630 # offset 5631 self.textDict['xoffset'] = self.xoffCtrl.GetValue() 5632 self.textDict['yoffset'] = self.yoffCtrl.GetValue() 5633 5634 # position 5635 if self.positionPanel.position['toPaper'].GetValue(): 5636 self.textDict['XY'] = True 5637 currUnit = self.unitConv.findUnit( 5638 self.positionPanel.units['unitsCtrl'].GetStringSelection()) 5639 self.textDict['unit'] = currUnit 5640 if self.positionPanel.position['xCtrl'].GetValue(): 5641 x = self.positionPanel.position['xCtrl'].GetValue() 5642 else: 5643 x = self.textDict['where'][0] 5644 5645 if self.positionPanel.position['yCtrl'].GetValue(): 5646 y = self.positionPanel.position['yCtrl'].GetValue() 5647 else: 5648 y = self.textDict['where'][1] 5649 5650 x = self.unitConv.convert( 5651 value=float(x), fromUnit=currUnit, toUnit='inch') 5652 y = self.unitConv.convert( 5653 value=float(y), fromUnit=currUnit, toUnit='inch') 5654 self.textDict['where'] = x, y 5655 self.textDict['east'], self.textDict['north'] = PaperMapCoordinates( 5656 self.instruction[self.mapId], x, y, paperToMap=True, env=self.env) 5657 else: 5658 self.textDict['XY'] = False 5659 if self.positionPanel.position['eCtrl'].GetValue(): 5660 self.textDict['east'] = self.positionPanel.position[ 5661 'eCtrl'].GetValue() 5662 else: 5663 self.textDict['east'] = self.textDict['east'] 5664 5665 if self.positionPanel.position['nCtrl'].GetValue(): 5666 self.textDict['north'] = self.positionPanel.position[ 5667 'nCtrl'].GetValue() 5668 else: 5669 self.textDict['north'] = self.textDict['north'] 5670 5671 self.textDict['where'] = PaperMapCoordinates( 5672 mapInstr=self.instruction[ 5673 self.mapId], x=float( 5674 self.textDict['east']), y=float( 5675 self.textDict['north']), paperToMap=False, 5676 env=self.env) 5677 # rotation 5678 if self.rotCtrl.GetValue(): 5679 self.textDict['rotate'] = self.rotValue.GetValue() 5680 else: 5681 self.textDict['rotate'] = None 5682 # reference point 5683 for radio in self.radio: 5684 if radio.GetValue() == True: 5685 self.textDict['ref'] = radio.GetName() 5686 5687 if self.id not in self.instruction: 5688 text = Text(self.id, env=self.env) 5689 self.instruction.AddInstruction(text) 5690 self.instruction[self.id].SetInstruction(self.textDict) 5691 5692 if self.id not in self.parent.objectId: 5693 self.parent.objectId.append(self.id) 5694 5695# self.updateDialog() 5696 5697 return True 5698 5699 def updateDialog(self): 5700 """Update text coordinates, after moving""" 5701 # XY coordinates 5702 x, y = self.textDict['where'][:2] 5703 currUnit = self.unitConv.findUnit( 5704 self.positionPanel.units['unitsCtrl'].GetStringSelection()) 5705 x = self.unitConv.convert(value=x, fromUnit='inch', toUnit=currUnit) 5706 y = self.unitConv.convert(value=y, fromUnit='inch', toUnit=currUnit) 5707 self.positionPanel.position['xCtrl'].SetValue("%5.3f" % x) 5708 self.positionPanel.position['yCtrl'].SetValue("%5.3f" % y) 5709 # EN coordinates 5710 e, n = self.textDict['east'], self.textDict['north'] 5711 self.positionPanel.position['eCtrl'].SetValue( 5712 str(self.textDict['east'])) 5713 self.positionPanel.position['nCtrl'].SetValue( 5714 str(self.textDict['north'])) 5715 5716 5717class ImageDialog(PsmapDialog): 5718 """Dialog for setting image properties. 5719 5720 It's base dialog for North Arrow dialog. 5721 """ 5722 5723 def __init__(self, parent, id, settings, env, imagePanelName=_("Image")): 5724 PsmapDialog.__init__( 5725 self, 5726 parent=parent, 5727 id=id, 5728 title="Image settings", 5729 settings=settings, 5730 env=env) 5731 5732 self.objectType = ('image',) 5733 if self.id is not None: 5734 self.imageObj = self.instruction[self.id] 5735 self.imageDict = self.instruction[id].GetInstruction() 5736 else: 5737 self.id = NewId() 5738 self.imageObj = self._newObject() 5739 self.imageDict = self.imageObj.GetInstruction() 5740 page = self.instruction.FindInstructionByType( 5741 'page').GetInstruction() 5742 self.imageDict['where'] = page['Left'], page['Top'] 5743 5744 map = self.instruction.FindInstructionByType('map') 5745 if not map: 5746 map = self.instruction.FindInstructionByType('initMap') 5747 self.mapId = map.id 5748 5749 self.imageDict['east'], self.imageDict['north'] = PaperMapCoordinates( 5750 mapInstr=map, x=self.imageDict['where'][0], 5751 y=self.imageDict['where'][1], 5752 paperToMap=True, env=self.env) 5753 5754 notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT) 5755 self.imagePanelName = imagePanelName 5756 self.imagePanel = self._imagePanel(notebook) 5757 self.positionPanel = self._positionPanel(notebook) 5758 self.OnPositionType(None) 5759 5760 if self.imageDict['epsfile']: 5761 self.imagePanel.image['dir'].SetValue( 5762 os.path.dirname(self.imageDict['epsfile'])) 5763 else: 5764 self.imagePanel.image['dir'].SetValue(self._getImageDirectory()) 5765 self.OnDirChanged(None) 5766 5767 self._layout(notebook) 5768 5769 def _newObject(self): 5770 """Create corresponding instruction object""" 5771 return Image(self.id, self.instruction, env=self.env) 5772 5773 def _imagePanel(self, notebook): 5774 panel = Panel( 5775 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 5776 style=wx.TAB_TRAVERSAL) 5777 notebook.AddPage(page=panel, text=self.imagePanelName) 5778 border = wx.BoxSizer(wx.VERTICAL) 5779 # 5780 # choose image 5781 # 5782 box = StaticBox( 5783 parent=panel, 5784 id=wx.ID_ANY, 5785 label=" %s " % 5786 _("Image")) 5787 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 5788 5789 # choose directory 5790 panel.image = {} 5791 if self.imageDict['epsfile']: 5792 startDir = os.path.dirname(self.imageDict['epsfile']) 5793 else: 5794 startDir = self._getImageDirectory() 5795 dir = DirBrowseButton( 5796 parent=panel, 5797 id=wx.ID_ANY, 5798 labelText=_("Choose a directory:"), 5799 dialogTitle=_("Choose a directory with images"), 5800 buttonText=_('Browse'), 5801 startDirectory=startDir, 5802 changeCallback=self.OnDirChanged) 5803 panel.image['dir'] = dir 5804 5805 sizer.Add(dir, proportion=0, flag=wx.EXPAND, border=0) 5806 5807 # image list 5808 hSizer = wx.BoxSizer(wx.HORIZONTAL) 5809 5810 imageList = ListBox(parent=panel, id=wx.ID_ANY) 5811 panel.image['list'] = imageList 5812 imageList.Bind(wx.EVT_LISTBOX, self.OnImageSelectionChanged) 5813 5814 hSizer.Add( 5815 imageList, 5816 proportion=1, 5817 flag=wx.EXPAND | wx.RIGHT, 5818 border=10) 5819 5820 # image preview 5821 vSizer = wx.BoxSizer(wx.VERTICAL) 5822 self.previewSize = (150, 150) 5823 img = EmptyImage(*self.previewSize) 5824 panel.image['preview'] = wx.StaticBitmap( 5825 panel, wx.ID_ANY, BitmapFromImage(img)) 5826 vSizer.Add( 5827 panel.image['preview'], 5828 proportion=0, 5829 flag=wx.EXPAND | wx.BOTTOM, 5830 border=5) 5831 panel.image['sizeInfo'] = StaticText(parent=panel, id=wx.ID_ANY) 5832 vSizer.Add( 5833 panel.image['sizeInfo'], 5834 proportion=0, 5835 flag=wx.ALIGN_CENTER, 5836 border=0) 5837 5838 hSizer.Add(vSizer, proportion=0, flag=wx.EXPAND, border=0) 5839 sizer.Add(hSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=3) 5840 5841 epsInfo = StaticText(parent=panel, id=wx.ID_ANY, 5842 label=_("Note: only EPS format supported")) 5843 sizer.Add( 5844 epsInfo, 5845 proportion=0, 5846 flag=wx.ALL, 5847 border=3) 5848 5849 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 5850 5851 # 5852 # rotation 5853 # 5854 box = StaticBox( 5855 parent=panel, 5856 id=wx.ID_ANY, 5857 label=" %s " % 5858 _("Scale And Rotation")) 5859 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 5860 5861 gridSizer = wx.GridBagSizer(hgap=5, vgap=5) 5862 5863 scaleLabel = StaticText( 5864 parent=panel, id=wx.ID_ANY, label=_("Scale:")) 5865 5866 panel.image['scale'] = FloatSpin( 5867 panel, id=wx.ID_ANY, min_val=0, max_val=50, increment=0.5, 5868 value=1, style=fs.FS_RIGHT) 5869 panel.image['scale'].SetFormat("%f") 5870 panel.image['scale'].SetDigits(1) 5871 5872 if self.imageDict['scale']: 5873 value = float(self.imageDict['scale']) 5874 else: 5875 value = 0 5876 5877 panel.image['scale'].SetValue(value) 5878 5879 gridSizer.Add( 5880 scaleLabel, pos=(0, 0), 5881 flag=wx.ALIGN_CENTER_VERTICAL) 5882 gridSizer.Add( 5883 panel.image['scale'], 5884 pos=(0, 1), 5885 flag=wx.ALIGN_CENTER_VERTICAL) 5886 5887 rotLabel = StaticText( 5888 parent=panel, 5889 id=wx.ID_ANY, 5890 label=_("Rotation angle (deg):")) 5891 panel.image['rotate'] = FloatSpin( 5892 panel, id=wx.ID_ANY, min_val=0, max_val=360, increment=0.5, 5893 value=0, style=fs.FS_RIGHT) 5894 panel.image['rotate'].SetFormat("%f") 5895 panel.image['rotate'].SetDigits(1) 5896 5897 panel.image['rotate'].SetToolTip( 5898 _("Counterclockwise rotation in degrees")) 5899 if self.imageDict['rotate']: 5900 panel.image['rotate'].SetValue(int(self.imageDict['rotate'])) 5901 else: 5902 panel.image['rotate'].SetValue(0) 5903 5904 gridSizer.Add( 5905 rotLabel, 5906 pos=( 5907 1, 5908 0), 5909 flag=wx.ALIGN_CENTER_VERTICAL, 5910 border=0) 5911 gridSizer.Add( 5912 panel.image['rotate'], pos=( 5913 1, 1), flag=wx.ALIGN_CENTER_VERTICAL) 5914 5915 self._addConvergence(panel=panel, gridBagSizer=gridSizer) 5916 sizer.Add( 5917 gridSizer, 5918 proportion=0, 5919 flag=wx.EXPAND | wx.ALL, 5920 border=5) 5921 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 5922 5923 panel.SetSizer(border) 5924 panel.Fit() 5925 5926 return panel 5927 5928 def _positionPanel(self, notebook): 5929 panel = Panel( 5930 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 5931 style=wx.TAB_TRAVERSAL) 5932 notebook.AddPage(page=panel, text=_("Position")) 5933 border = wx.BoxSizer(wx.VERTICAL) 5934 # 5935 # set position 5936 # 5937 box = StaticBox( 5938 parent=panel, 5939 id=wx.ID_ANY, 5940 label=" %s " % 5941 _("Position")) 5942 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 5943 5944 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 5945 5946 self.AddExtendedPosition(panel, gridBagSizer, self.imageDict) 5947 5948 self.Bind( 5949 wx.EVT_RADIOBUTTON, 5950 self.OnPositionType, 5951 panel.position['toPaper']) 5952 self.Bind( 5953 wx.EVT_RADIOBUTTON, 5954 self.OnPositionType, 5955 panel.position['toMap']) 5956 5957 gridBagSizer.AddGrowableCol(0) 5958 gridBagSizer.AddGrowableCol(1) 5959 sizer.Add( 5960 gridBagSizer, 5961 proportion=1, 5962 flag=wx.ALL, 5963 border=5) 5964 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 5965 5966 panel.SetSizer(border) 5967 panel.Fit() 5968 5969 return panel 5970 5971 def OnDirChanged(self, event): 5972 """Image directory changed""" 5973 path = self.imagePanel.image['dir'].GetValue() 5974 try: 5975 files = os.listdir(path) 5976 except OSError: # no such directory 5977 files = [] 5978 imageList = [] 5979 5980 # no setter for startDirectory? 5981 try: 5982 self.imagePanel.image['dir'].startDirectory = path 5983 except AttributeError: # for sure 5984 pass 5985 for file in files: 5986 if os.path.splitext(file)[1].lower() == '.eps': 5987 imageList.append(file) 5988 5989 imageList.sort() 5990 self.imagePanel.image['list'].SetItems(imageList) 5991 if self.imageDict['epsfile']: 5992 file = os.path.basename(self.imageDict['epsfile']) 5993 self.imagePanel.image['list'].SetStringSelection(file) 5994 elif imageList: 5995 self.imagePanel.image['list'].SetSelection(0) 5996 self.OnImageSelectionChanged(None) 5997 5998 def OnPositionType(self, event): 5999 if self.positionPanel.position['toPaper'].GetValue(): 6000 for widget in self.gridBagSizerP.GetChildren(): 6001 widget.GetWindow().Enable() 6002 for widget in self.gridBagSizerM.GetChildren(): 6003 widget.GetWindow().Disable() 6004 else: 6005 for widget in self.gridBagSizerM.GetChildren(): 6006 widget.GetWindow().Enable() 6007 for widget in self.gridBagSizerP.GetChildren(): 6008 widget.GetWindow().Disable() 6009 6010 def _getImageDirectory(self): 6011 """Default image directory""" 6012 return os.getcwd() 6013 6014 def _addConvergence(self, panel, gridBagSizer): 6015 pass 6016 6017 def OnImageSelectionChanged(self, event): 6018 """Image selected, show preview and size""" 6019 if not self.imagePanel.image[ 6020 'dir']: # event is emitted when closing dialog an it causes error 6021 return 6022 6023 if not havePILImage: 6024 self.DrawWarningText(_("PIL\nmissing")) 6025 return 6026 6027 imageName = self.imagePanel.image['list'].GetStringSelection() 6028 if not imageName: 6029 self.ClearPreview() 6030 return 6031 basePath = self.imagePanel.image['dir'].GetValue() 6032 file = os.path.join(basePath, imageName) 6033 if not os.path.exists(file): 6034 return 6035 6036 if os.path.splitext(file)[1].lower() == '.eps': 6037 try: 6038 pImg = PILImage.open(file) 6039 if sys.platform == 'win32': 6040 import types 6041 pImg.load = types.MethodType(loadPSForWindows, pImg) 6042 img = PilImageToWxImage(pImg) 6043 except IOError as e: 6044 GError(message=_("Unable to read file %s") % file) 6045 self.ClearPreview() 6046 return 6047 self.SetSizeInfoLabel(img) 6048 img = self.ScaleToPreview(img) 6049 bitmap = img.ConvertToBitmap() 6050 self.DrawBitmap(bitmap) 6051 6052 else: 6053 # TODO: read other formats and convert by PIL to eps 6054 pass 6055 6056 def ScaleToPreview(self, img): 6057 """Scale image to preview size""" 6058 w = img.GetWidth() 6059 h = img.GetHeight() 6060 if w <= self.previewSize[0] and h <= self.previewSize[1]: 6061 return img 6062 if w > h: 6063 newW = self.previewSize[0] 6064 newH = self.previewSize[0] * h / w 6065 else: 6066 newH = self.previewSize[0] 6067 newW = self.previewSize[0] * w / h 6068 return img.Scale(newW, newH, wx.IMAGE_QUALITY_HIGH) 6069 6070 def DrawWarningText(self, warning): 6071 """Draw text on preview window""" 6072 buffer = EmptyBitmap(*self.previewSize) 6073 dc = wx.MemoryDC() 6074 dc.SelectObject(buffer) 6075 dc.SetBrush(wx.Brush(wx.Colour(250, 250, 250))) 6076 dc.Clear() 6077 extent = dc.GetTextExtent(warning) 6078 posX = self.previewSize[0] / 2 - extent[0] / 2 6079 posY = self.previewSize[1] / 2 - extent[1] / 2 6080 dc.DrawText(warning, posX, posY) 6081 self.imagePanel.image['preview'].SetBitmap(buffer) 6082 dc.SelectObject(wx.NullBitmap) 6083 6084 def DrawBitmap(self, bitmap): 6085 """Draw bitmap, center it if smaller than preview size""" 6086 if bitmap.GetWidth() <= self.previewSize[ 6087 0] and bitmap.GetHeight() <= self.previewSize[1]: 6088 buffer = EmptyBitmap(*self.previewSize) 6089 dc = wx.MemoryDC() 6090 dc.SelectObject(buffer) 6091 dc.SetBrush(dc.GetBrush()) 6092 dc.Clear() 6093 posX = self.previewSize[0] / 2 - bitmap.GetWidth() / 2 6094 posY = self.previewSize[1] / 2 - bitmap.GetHeight() / 2 6095 dc.DrawBitmap(bitmap, posX, posY) 6096 self.imagePanel.image['preview'].SetBitmap(buffer) 6097 dc.SelectObject(wx.NullBitmap) 6098 else: 6099 self.imagePanel.image['preview'].SetBitmap(bitmap) 6100 self.imagePanel.Refresh() 6101 6102 def SetSizeInfoLabel(self, image): 6103 """Update image size label""" 6104 self.imagePanel.image['sizeInfo'].SetLabel( 6105 _("size: %(width)s x %(height)s pts") % 6106 {'width': image.GetWidth(), 6107 'height': image.GetHeight()}) 6108 self.imagePanel.image['sizeInfo'].GetContainingSizer().Layout() 6109 6110 def ClearPreview(self): 6111 """Clear preview window""" 6112 buffer = EmptyBitmap(*self.previewSize) 6113 dc = wx.MemoryDC() 6114 dc.SelectObject(buffer) 6115 dc.SetBrush(wx.WHITE_BRUSH) 6116 dc.Clear() 6117 dc.SelectObject(wx.NullBitmap) 6118 mask = wx.Mask(buffer, wx.WHITE) 6119 buffer.SetMask(mask) 6120 self.imagePanel.image['preview'].SetBitmap(buffer) 6121 6122 def update(self): 6123 # epsfile 6124 selected = self.imagePanel.image['list'].GetStringSelection() 6125 basePath = self.imagePanel.image['dir'].GetValue() 6126 if not selected: 6127 GMessage(parent=self, message=_("No image selected.")) 6128 return False 6129 6130 self.imageDict['epsfile'] = os.path.join(basePath, selected) 6131 6132 # position 6133 if self.positionPanel.position['toPaper'].GetValue(): 6134 self.imageDict['XY'] = True 6135 currUnit = self.unitConv.findUnit( 6136 self.positionPanel.units['unitsCtrl'].GetStringSelection()) 6137 self.imageDict['unit'] = currUnit 6138 if self.positionPanel.position['xCtrl'].GetValue(): 6139 x = self.positionPanel.position['xCtrl'].GetValue() 6140 else: 6141 x = self.imageDict['where'][0] 6142 6143 if self.positionPanel.position['yCtrl'].GetValue(): 6144 y = self.positionPanel.position['yCtrl'].GetValue() 6145 else: 6146 y = self.imageDict['where'][1] 6147 6148 x = self.unitConv.convert( 6149 value=float(x), fromUnit=currUnit, toUnit='inch') 6150 y = self.unitConv.convert( 6151 value=float(y), fromUnit=currUnit, toUnit='inch') 6152 self.imageDict['where'] = x, y 6153 6154 else: 6155 self.imageDict['XY'] = False 6156 if self.positionPanel.position['eCtrl'].GetValue(): 6157 e = self.positionPanel.position['eCtrl'].GetValue() 6158 else: 6159 self.imageDict['east'] = self.imageDict['east'] 6160 6161 if self.positionPanel.position['nCtrl'].GetValue(): 6162 n = self.positionPanel.position['nCtrl'].GetValue() 6163 else: 6164 self.imageDict['north'] = self.imageDict['north'] 6165 6166 x, y = PaperMapCoordinates( 6167 mapInstr=self.instruction[ 6168 self.mapId], x=float( 6169 self.imageDict['east']), y=float( 6170 self.imageDict['north']), paperToMap=False, 6171 env=self.env) 6172 6173 # rotation 6174 rot = self.imagePanel.image['rotate'].GetValue() 6175 if rot == 0: 6176 self.imageDict['rotate'] = None 6177 else: 6178 self.imageDict['rotate'] = rot 6179 6180 # scale 6181 self.imageDict['scale'] = self.imagePanel.image['scale'].GetValue() 6182 6183 # scale 6184 w, h = self.imageObj.GetImageOrigSize(self.imageDict['epsfile']) 6185 if self.imageDict['rotate']: 6186 self.imageDict['size'] = BBoxAfterRotation( 6187 w, h, self.imageDict['rotate']) 6188 else: 6189 self.imageDict['size'] = w, h 6190 6191 w = self.unitConv.convert(value=self.imageDict['size'][0], 6192 fromUnit='point', toUnit='inch') 6193 h = self.unitConv.convert(value=self.imageDict['size'][1], 6194 fromUnit='point', toUnit='inch') 6195 6196 self.imageDict['rect'] = Rect2D(x=x, y=y, 6197 width=w * self.imageDict['scale'], 6198 height=h * self.imageDict['scale']) 6199 6200 if self.id not in self.instruction: 6201 image = self._newObject() 6202 self.instruction.AddInstruction(image) 6203 self.instruction[self.id].SetInstruction(self.imageDict) 6204 6205 if self.id not in self.parent.objectId: 6206 self.parent.objectId.append(self.id) 6207 6208 return True 6209 6210 def updateDialog(self): 6211 """Update text coordinates, after moving""" 6212 # XY coordinates 6213 x, y = self.imageDict['where'][:2] 6214 currUnit = self.unitConv.findUnit( 6215 self.positionPanel.units['unitsCtrl'].GetStringSelection()) 6216 x = self.unitConv.convert(value=x, fromUnit='inch', toUnit=currUnit) 6217 y = self.unitConv.convert(value=y, fromUnit='inch', toUnit=currUnit) 6218 self.positionPanel.position['xCtrl'].SetValue("%5.3f" % x) 6219 self.positionPanel.position['yCtrl'].SetValue("%5.3f" % y) 6220 # EN coordinates 6221 e, n = self.imageDict['east'], self.imageDict['north'] 6222 self.positionPanel.position['eCtrl'].SetValue( 6223 str(self.imageDict['east'])) 6224 self.positionPanel.position['nCtrl'].SetValue( 6225 str(self.imageDict['north'])) 6226 6227 6228class NorthArrowDialog(ImageDialog): 6229 6230 def __init__(self, parent, id, settings, env): 6231 ImageDialog.__init__(self, parent=parent, id=id, settings=settings, 6232 imagePanelName=_("North Arrow"), env=env) 6233 6234 self.objectType = ('northArrow',) 6235 self.SetTitle(_("North Arrow settings")) 6236 6237 def _newObject(self): 6238 return NorthArrow(self.id, self.instruction, env=self.env) 6239 6240 def _getImageDirectory(self): 6241 gisbase = os.getenv("GISBASE") 6242 return os.path.join(gisbase, 'etc', 'paint', 'decorations') 6243 6244 def _addConvergence(self, panel, gridBagSizer): 6245 convergence = Button(parent=panel, id=wx.ID_ANY, 6246 label=_("Compute convergence")) 6247 gridBagSizer.Add(convergence, pos=(1, 2), 6248 flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND) 6249 convergence.Bind(wx.EVT_BUTTON, self.OnConvergence) 6250 panel.image['convergence'] = convergence 6251 6252 def OnConvergence(self, event): 6253 ret = RunCommand('g.region', read=True, flags='nug', env=self.env) 6254 if ret: 6255 convergence = float(ret.strip().split('=')[1]) 6256 if convergence < 0: 6257 self.imagePanel.image['rotate'].SetValue(abs(convergence)) 6258 else: 6259 self.imagePanel.image['rotate'].SetValue(360 - convergence) 6260 6261 6262class PointDialog(PsmapDialog): 6263 """Dialog for setting point properties.""" 6264 6265 def __init__( 6266 self, parent, id, settings, env, coordinates=None, 6267 pointPanelName=_("Point")): 6268 PsmapDialog.__init__( 6269 self, 6270 parent=parent, 6271 id=id, 6272 title="Point settings", 6273 settings=settings, 6274 env=env) 6275 6276 self.objectType = ('point',) 6277 if self.id is not None: 6278 self.pointObj = self.instruction[self.id] 6279 self.pointDict = self.instruction[id].GetInstruction() 6280 else: 6281 self.id = NewId() 6282 self.pointObj = Point(self.id, env=self.env) 6283 self.pointDict = self.pointObj.GetInstruction() 6284 self.pointDict['where'] = coordinates 6285 self.defaultDict = self.pointObj.defaultInstruction 6286 6287 mapObj = self.instruction.FindInstructionByType('map') 6288 if not mapObj: 6289 mapObj = self.instruction.FindInstructionByType('initMap') 6290 self.mapId = mapObj.id 6291 6292 self.pointDict['east'], self.pointDict['north'] = PaperMapCoordinates( 6293 mapInstr=mapObj, x=self.pointDict['where'][0], 6294 y=self.pointDict['where'][1], 6295 paperToMap=True, 6296 env=self.env) 6297 6298 notebook = Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT) 6299 self.pointPanelName = pointPanelName 6300 self.pointPanel = self._pointPanel(notebook) 6301 self.positionPanel = self._positionPanel(notebook) 6302 self.OnPositionType(None) 6303 6304 self._layout(notebook) 6305 6306 def _pointPanel(self, notebook): 6307 panel = Panel( 6308 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 6309 style=wx.TAB_TRAVERSAL) 6310 notebook.AddPage(page=panel, text=self.pointPanelName) 6311 border = wx.BoxSizer(wx.VERTICAL) 6312 # 6313 # choose image 6314 # 6315 box = StaticBox( 6316 parent=panel, 6317 id=wx.ID_ANY, 6318 label=" %s " % 6319 _("Symbol")) 6320 sizer = wx.StaticBoxSizer(box, wx.HORIZONTAL) 6321 6322 gridSizer = wx.GridBagSizer(hgap=5, vgap=5) 6323 6324 gridSizer.Add( 6325 StaticText( 6326 parent=panel, id=wx.ID_ANY, label=_("Select symbol:")), pos=( 6327 0, 0), flag=wx.ALIGN_CENTER_VERTICAL) 6328 6329 self.symbolLabel = StaticText(parent=panel, id=wx.ID_ANY, 6330 label=self.pointDict['symbol']) 6331 gridSizer.Add(self.symbolLabel, pos=(0, 1), 6332 flag=wx.ALIGN_CENTER_VERTICAL) 6333 bitmap = wx.Bitmap(os.path.join(globalvar.SYMBDIR, 6334 self.pointDict['symbol']) + '.png') 6335 self.symbolButton = BitmapButton(panel, id=wx.ID_ANY, bitmap=bitmap) 6336 self.symbolButton.Bind(wx.EVT_BUTTON, self.OnSymbolSelection) 6337 6338 gridSizer.Add( 6339 self.symbolButton, pos=(0, 2), 6340 flag=wx.ALIGN_CENTER_VERTICAL) 6341 self.noteLabel = StaticText( 6342 parent=panel, id=wx.ID_ANY, label=_( 6343 "Note: Selected symbol is not displayed\n" 6344 "in draft mode (only in preview mode)")) 6345 gridSizer.Add( 6346 self.noteLabel, pos=( 6347 1, 0), span=( 6348 1, 2), flag=wx.ALIGN_CENTER_VERTICAL) 6349 6350 gridSizer.AddGrowableCol(1) 6351 sizer.Add( 6352 gridSizer, 6353 proportion=1, 6354 flag=wx.EXPAND | wx.ALL, 6355 border=5) 6356 6357 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 6358 6359 # 6360 # outline/fill color 6361 # 6362 6363 # outline 6364 box = StaticBox( 6365 parent=panel, 6366 id=wx.ID_ANY, 6367 label=" %s " % 6368 _("Color")) 6369 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 6370 6371 gridSizer = wx.GridBagSizer(hgap=5, vgap=5) 6372 6373 outlineLabel = StaticText( 6374 parent=panel, 6375 id=wx.ID_ANY, 6376 label=_("Outline color:")) 6377 self.outlineColorCtrl = ColourPickerCtrl(panel, id=wx.ID_ANY) 6378 self.outlineTranspCtrl = CheckBox( 6379 panel, id=wx.ID_ANY, label=_("transparent")) 6380 6381 if self.pointDict['color'] != 'none': 6382 self.outlineTranspCtrl.SetValue(False) 6383 self.outlineColorCtrl.SetColour( 6384 convertRGB(self.pointDict['color'])) 6385 else: 6386 self.outlineTranspCtrl.SetValue(True) 6387 self.outlineColorCtrl.SetColour( 6388 convertRGB(self.defaultDict['color'])) 6389 6390 gridSizer.Add( 6391 outlineLabel, pos=(0, 0), 6392 flag=wx.ALIGN_CENTER_VERTICAL) 6393 gridSizer.Add( 6394 self.outlineColorCtrl, pos=( 6395 0, 1), flag=wx.ALIGN_CENTER_VERTICAL) 6396 gridSizer.Add( 6397 self.outlineTranspCtrl, pos=( 6398 0, 2), flag=wx.ALIGN_CENTER_VERTICAL) 6399 6400 fillLabel = StaticText( 6401 parent=panel, 6402 id=wx.ID_ANY, 6403 label=_("Fill color:")) 6404 self.fillColorCtrl = ColourPickerCtrl(panel, id=wx.ID_ANY) 6405 self.fillTranspCtrl = CheckBox( 6406 panel, id=wx.ID_ANY, label=_("transparent")) 6407 6408 if self.pointDict['fcolor'] != 'none': 6409 self.fillTranspCtrl.SetValue(False) 6410 self.fillColorCtrl.SetColour(convertRGB(self.pointDict['fcolor'])) 6411 else: 6412 self.fillTranspCtrl.SetValue(True) 6413 self.fillColorCtrl.SetColour( 6414 convertRGB(self.defaultDict['fcolor'])) 6415 6416 gridSizer.Add( 6417 fillLabel, pos=(1, 0), 6418 flag=wx.ALIGN_CENTER_VERTICAL) 6419 gridSizer.Add( 6420 self.fillColorCtrl, pos=( 6421 1, 1), flag=wx.ALIGN_CENTER_VERTICAL) 6422 gridSizer.Add( 6423 self.fillTranspCtrl, pos=( 6424 1, 2), flag=wx.ALIGN_CENTER_VERTICAL) 6425 6426 sizer.Add( 6427 gridSizer, 6428 proportion=0, 6429 flag=wx.EXPAND | wx.ALL, 6430 border=5) 6431 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 6432 6433 # 6434 # size and rotation 6435 # 6436 6437 # size 6438 box = StaticBox( 6439 parent=panel, 6440 id=wx.ID_ANY, 6441 label=" %s " % 6442 _("Size and Rotation")) 6443 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 6444 6445 gridSizer = wx.GridBagSizer(hgap=5, vgap=5) 6446 6447 sizeLabel = StaticText( 6448 parent=panel, 6449 id=wx.ID_ANY, 6450 label=_("Size (pt):")) 6451 self.sizeCtrl = SpinCtrl( 6452 panel, id=wx.ID_ANY, size=self.spinCtrlSize) 6453 self.sizeCtrl.SetToolTip(_("Symbol size in points")) 6454 self.sizeCtrl.SetValue(self.pointDict['size']) 6455 6456 gridSizer.Add( 6457 sizeLabel, pos=(0, 0), 6458 flag=wx.ALIGN_CENTER_VERTICAL) 6459 gridSizer.Add( 6460 self.sizeCtrl, pos=( 6461 0, 1), flag=wx.ALIGN_CENTER_VERTICAL) 6462 6463 # rotation 6464 rotLabel = StaticText( 6465 parent=panel, 6466 id=wx.ID_ANY, 6467 label=_("Rotation angle (deg):")) 6468 6469 self.rotCtrl = FloatSpin( 6470 panel, 6471 id=wx.ID_ANY, 6472 min_val=-360, 6473 max_val=360, 6474 increment=1, 6475 value=0, 6476 style=fs.FS_RIGHT) 6477 self.rotCtrl.SetFormat("%f") 6478 self.rotCtrl.SetDigits(1) 6479 6480 self.rotCtrl.SetToolTip( 6481 _("Counterclockwise rotation in degrees")) 6482 self.rotCtrl.SetValue(float(self.pointDict['rotate'])) 6483 6484 gridSizer.Add( 6485 rotLabel, 6486 pos=( 6487 1, 6488 0), 6489 flag=wx.ALIGN_CENTER_VERTICAL, 6490 border=0) 6491 gridSizer.Add( 6492 self.rotCtrl, pos=(1, 1), 6493 flag=wx.ALIGN_CENTER_VERTICAL) 6494 6495 sizer.Add( 6496 gridSizer, 6497 proportion=0, 6498 flag=wx.EXPAND | wx.ALL, 6499 border=5) 6500 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 6501 6502 panel.SetSizer(border) 6503 panel.Fit() 6504 6505 return panel 6506 6507 def _positionPanel(self, notebook): 6508 panel = Panel( 6509 parent=notebook, id=wx.ID_ANY, size=(-1, -1), 6510 style=wx.TAB_TRAVERSAL) 6511 notebook.AddPage(page=panel, text=_("Position")) 6512 border = wx.BoxSizer(wx.VERTICAL) 6513 # 6514 # set position 6515 # 6516 box = StaticBox( 6517 parent=panel, 6518 id=wx.ID_ANY, 6519 label=" %s " % 6520 _("Position")) 6521 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 6522 6523 gridBagSizer = wx.GridBagSizer(hgap=5, vgap=5) 6524 6525 self.AddExtendedPosition(panel, gridBagSizer, self.pointDict) 6526 6527 self.Bind( 6528 wx.EVT_RADIOBUTTON, 6529 self.OnPositionType, 6530 panel.position['toPaper']) 6531 self.Bind( 6532 wx.EVT_RADIOBUTTON, 6533 self.OnPositionType, 6534 panel.position['toMap']) 6535 6536 gridBagSizer.AddGrowableCol(0) 6537 gridBagSizer.AddGrowableCol(1) 6538 sizer.Add( 6539 gridBagSizer, 6540 proportion=1, 6541 flag=wx.ALL, 6542 border=5) 6543 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 6544 6545 panel.SetSizer(border) 6546 panel.Fit() 6547 6548 return panel 6549 6550 def OnPositionType(self, event): 6551 if self.positionPanel.position['toPaper'].GetValue(): 6552 for widget in self.gridBagSizerP.GetChildren(): 6553 widget.GetWindow().Enable() 6554 for widget in self.gridBagSizerM.GetChildren(): 6555 widget.GetWindow().Disable() 6556 else: 6557 for widget in self.gridBagSizerM.GetChildren(): 6558 widget.GetWindow().Enable() 6559 for widget in self.gridBagSizerP.GetChildren(): 6560 widget.GetWindow().Disable() 6561 6562 def OnSymbolSelection(self, event): 6563 dlg = SymbolDialog(self, symbolPath=globalvar.SYMBDIR, 6564 currentSymbol=self.symbolLabel.GetLabel()) 6565 if dlg.ShowModal() == wx.ID_OK: 6566 img = dlg.GetSelectedSymbolPath() 6567 name = dlg.GetSelectedSymbolName() 6568 self.symbolButton.SetBitmapLabel(wx.Bitmap(img + '.png')) 6569 self.symbolLabel.SetLabel(name) 6570 6571 dlg.Destroy() 6572 6573 def update(self): 6574 # symbol 6575 self.pointDict['symbol'] = self.symbolLabel.GetLabel() 6576 6577 # position 6578 if self.positionPanel.position['toPaper'].GetValue(): 6579 self.pointDict['XY'] = True 6580 currUnit = self.unitConv.findUnit( 6581 self.positionPanel.units['unitsCtrl'].GetStringSelection()) 6582 self.pointDict['unit'] = currUnit 6583 if self.positionPanel.position['xCtrl'].GetValue(): 6584 x = self.positionPanel.position['xCtrl'].GetValue() 6585 else: 6586 x = self.pointDict['where'][0] 6587 6588 if self.positionPanel.position['yCtrl'].GetValue(): 6589 y = self.positionPanel.position['yCtrl'].GetValue() 6590 else: 6591 y = self.pointDict['where'][1] 6592 6593 x = self.unitConv.convert( 6594 value=float(x), fromUnit=currUnit, toUnit='inch') 6595 y = self.unitConv.convert( 6596 value=float(y), fromUnit=currUnit, toUnit='inch') 6597 self.pointDict['where'] = x, y 6598 6599 else: 6600 self.pointDict['XY'] = False 6601 if self.positionPanel.position['eCtrl'].GetValue(): 6602 e = self.positionPanel.position['eCtrl'].GetValue() 6603 else: 6604 self.pointDict['east'] = self.pointDict['east'] 6605 6606 if self.positionPanel.position['nCtrl'].GetValue(): 6607 n = self.positionPanel.position['nCtrl'].GetValue() 6608 else: 6609 self.pointDict['north'] = self.pointDict['north'] 6610 6611 x, y = PaperMapCoordinates( 6612 mapInstr=self.instruction[ 6613 self.mapId], x=float( 6614 self.pointDict['east']), y=float( 6615 self.pointDict['north']), paperToMap=False, 6616 env=self.env) 6617 6618 # rotation 6619 self.pointDict['rotate'] = self.rotCtrl.GetValue() 6620 6621 # size 6622 self.pointDict['size'] = self.sizeCtrl.GetValue() 6623 6624 w = h = self.unitConv.convert(value=self.pointDict['size'], 6625 fromUnit='point', toUnit='inch') 6626 6627 # outline color 6628 if self.outlineTranspCtrl.GetValue(): 6629 self.pointDict['color'] = 'none' 6630 else: 6631 self.pointDict['color'] = convertRGB( 6632 self.outlineColorCtrl.GetColour()) 6633 6634 # fill color 6635 if self.fillTranspCtrl.GetValue(): 6636 self.pointDict['fcolor'] = 'none' 6637 else: 6638 self.pointDict['fcolor'] = convertRGB( 6639 self.fillColorCtrl.GetColour()) 6640 6641 self.pointDict['rect'] = Rect2D( 6642 x=x - w / 2, y=y - h / 2, width=w, height=h) 6643 6644 if self.id not in self.instruction: 6645 point = Point(self.id, env=self.env) 6646 self.instruction.AddInstruction(point) 6647 self.instruction[self.id].SetInstruction(self.pointDict) 6648 6649 if self.id not in self.parent.objectId: 6650 self.parent.objectId.append(self.id) 6651 6652 return True 6653 6654 def updateDialog(self): 6655 """Update text coordinates, after moving""" 6656 # XY coordinates 6657 x, y = self.pointDict['where'][:2] 6658 currUnit = self.unitConv.findUnit( 6659 self.positionPanel.units['unitsCtrl'].GetStringSelection()) 6660 x = self.unitConv.convert(value=x, fromUnit='inch', toUnit=currUnit) 6661 y = self.unitConv.convert(value=y, fromUnit='inch', toUnit=currUnit) 6662 self.positionPanel.position['xCtrl'].SetValue("%5.3f" % x) 6663 self.positionPanel.position['yCtrl'].SetValue("%5.3f" % y) 6664 # EN coordinates 6665 e, n = self.pointDict['east'], self.pointDict['north'] 6666 self.positionPanel.position['eCtrl'].SetValue( 6667 str(self.pointDict['east'])) 6668 self.positionPanel.position['nCtrl'].SetValue( 6669 str(self.pointDict['north'])) 6670 6671 6672class RectangleDialog(PsmapDialog): 6673 6674 def __init__(self, parent, id, settings, env, 6675 type='rectangle', coordinates=None): 6676 """ 6677 6678 :param coordinates: begin and end point coordinate (wx.Point, wx.Point) 6679 """ 6680 if type == 'rectangle': 6681 title = _("Rectangle settings") 6682 else: 6683 title = _("Line settings") 6684 PsmapDialog.__init__( 6685 self, 6686 parent=parent, 6687 id=id, 6688 title=title, 6689 settings=settings, 6690 env=env) 6691 6692 self.objectType = (type,) 6693 6694 if self.id is not None: 6695 self.rectObj = self.instruction[self.id] 6696 self.rectDict = self.rectObj.GetInstruction() 6697 else: 6698 self.id = NewId() 6699 if type == 'rectangle': 6700 self.rectObj = Rectangle(self.id, env=self.env) 6701 else: 6702 self.rectObj = Line(self.id, env=self.env) 6703 self.rectDict = self.rectObj.GetInstruction() 6704 6705 self.rectDict['rect'] = Rect2DPP(coordinates[0], coordinates[1]) 6706 self.rectDict['where'] = coordinates 6707 6708 self.defaultDict = self.rectObj.defaultInstruction 6709 self.panel = self._rectPanel() 6710 6711 self._layout(self.panel) 6712 6713 def _rectPanel(self): 6714 panel = Panel(parent=self, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL) 6715 border = wx.BoxSizer(wx.VERTICAL) 6716 6717 # color 6718 box = StaticBox( 6719 parent=panel, 6720 id=wx.ID_ANY, 6721 label=" %s " % 6722 _("Color")) 6723 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 6724 gridSizer = wx.GridBagSizer(hgap=5, vgap=5) 6725 6726 outlineLabel = StaticText( 6727 parent=panel, 6728 id=wx.ID_ANY, 6729 label=_("Outline color:")) 6730 self.outlineColorCtrl = ColourPickerCtrl(panel, id=wx.ID_ANY) 6731 self.outlineTranspCtrl = CheckBox( 6732 panel, id=wx.ID_ANY, label=_("transparent")) 6733 6734 if self.rectDict['color'] != 'none': 6735 self.outlineTranspCtrl.SetValue(False) 6736 self.outlineColorCtrl.SetColour(convertRGB(self.rectDict['color'])) 6737 else: 6738 self.outlineTranspCtrl.SetValue(True) 6739 self.outlineColorCtrl.SetColour( 6740 convertRGB(self.defaultDict['color'])) 6741 6742 # transparent outline makes sense only for rectangle 6743 if self.objectType == ('line',): 6744 self.outlineTranspCtrl.Hide() 6745 6746 gridSizer.Add( 6747 outlineLabel, pos=(0, 0), 6748 flag=wx.ALIGN_CENTER_VERTICAL) 6749 gridSizer.Add( 6750 self.outlineColorCtrl, pos=( 6751 0, 1), flag=wx.ALIGN_CENTER_VERTICAL) 6752 gridSizer.Add( 6753 self.outlineTranspCtrl, pos=( 6754 0, 2), flag=wx.ALIGN_CENTER_VERTICAL) 6755 6756 # fill color only in rectangle 6757 if self.objectType == ('rectangle',): 6758 fillLabel = StaticText( 6759 parent=panel, id=wx.ID_ANY, label=_("Fill color:")) 6760 self.fillColorCtrl = ColourPickerCtrl(panel, id=wx.ID_ANY) 6761 self.fillTranspCtrl = CheckBox( 6762 panel, id=wx.ID_ANY, label=_("transparent")) 6763 6764 if self.rectDict['fcolor'] != 'none': 6765 self.fillTranspCtrl.SetValue(False) 6766 self.fillColorCtrl.SetColour( 6767 convertRGB(self.rectDict['fcolor'])) 6768 else: 6769 self.fillTranspCtrl.SetValue(True) 6770 self.fillColorCtrl.SetColour(wx.WHITE) 6771 6772 gridSizer.Add( 6773 fillLabel, pos=(1, 0), 6774 flag=wx.ALIGN_CENTER_VERTICAL) 6775 gridSizer.Add( 6776 self.fillColorCtrl, pos=( 6777 1, 1), flag=wx.ALIGN_CENTER_VERTICAL) 6778 gridSizer.Add( 6779 self.fillTranspCtrl, pos=( 6780 1, 2), flag=wx.ALIGN_CENTER_VERTICAL) 6781 6782 sizer.Add(gridSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5) 6783 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 6784 gridSizer = wx.GridBagSizer(hgap=5, vgap=5) 6785 6786 # width 6787 box = StaticBox( 6788 parent=panel, 6789 id=wx.ID_ANY, 6790 label=" %s " % 6791 _("Line style")) 6792 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 6793 6794 widthLabel = StaticText( 6795 parent=panel, 6796 id=wx.ID_ANY, 6797 label=_("Line width:")) 6798 6799 self.widthCtrl = FloatSpin( 6800 panel, 6801 id=wx.ID_ANY, 6802 min_val=0, 6803 max_val=50, 6804 increment=1, 6805 value=0, 6806 style=fs.FS_RIGHT) 6807 self.widthCtrl.SetFormat("%f") 6808 self.widthCtrl.SetDigits(1) 6809 6810 self.widthCtrl.SetToolTip(_("Line width in points")) 6811 self.widthCtrl.SetValue(float(self.rectDict['width'])) 6812 6813 gridSizer.Add( 6814 widthLabel, pos=(0, 0), 6815 flag=wx.ALIGN_CENTER_VERTICAL) 6816 gridSizer.Add( 6817 self.widthCtrl, pos=( 6818 0, 1), flag=wx.ALIGN_CENTER_VERTICAL) 6819 6820 sizer.Add(gridSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5) 6821 border.Add(sizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) 6822 6823 panel.SetSizer(border) 6824 6825 return panel 6826 6827 def update(self): 6828 mapInstr = self.instruction.FindInstructionByType('map') 6829 if not mapInstr: 6830 mapInstr = self.instruction.FindInstructionByType('initMap') 6831 self.mapId = mapInstr.id 6832 point1 = self.rectDict['where'][0] 6833 point2 = self.rectDict['where'][1] 6834 self.rectDict['east1'], self.rectDict['north1'] = PaperMapCoordinates( 6835 mapInstr=mapInstr, x=point1[0], y=point1[1], paperToMap=True, 6836 env=self.env) 6837 self.rectDict['east2'], self.rectDict['north2'] = PaperMapCoordinates( 6838 mapInstr=mapInstr, x=point2[0], y=point2[1], paperToMap=True, 6839 env=self.env) 6840 # width 6841 self.rectDict['width'] = self.widthCtrl.GetValue() 6842 6843 # outline color 6844 if self.outlineTranspCtrl.GetValue(): 6845 self.rectDict['color'] = 'none' 6846 else: 6847 self.rectDict['color'] = convertRGB( 6848 self.outlineColorCtrl.GetColour()) 6849 6850 # fill color 6851 if self.objectType == ('rectangle',): 6852 if self.fillTranspCtrl.GetValue(): 6853 self.rectDict['fcolor'] = 'none' 6854 else: 6855 self.rectDict['fcolor'] = convertRGB( 6856 self.fillColorCtrl.GetColour()) 6857 6858 if self.id not in self.instruction: 6859 if self.objectType == ('rectangle',): 6860 rect = Rectangle(self.id, env=self.env) 6861 else: 6862 rect = Line(self.id, env=self.env) 6863 self.instruction.AddInstruction(rect) 6864 6865 self.instruction[self.id].SetInstruction(self.rectDict) 6866 6867 if self.id not in self.parent.objectId: 6868 self.parent.objectId.append(self.id) 6869 6870 self.updateDialog() 6871 6872 return True 6873 6874 def updateDialog(self): 6875 """Update text coordinates, after moving""" 6876 pass 6877 6878 6879class LabelsDialog(PsmapDialog): 6880 6881 def __init__(self, parent, id, settings, env): 6882 PsmapDialog.__init__( 6883 self, 6884 parent=parent, 6885 id=id, 6886 title=_("Vector labels"), 6887 settings=settings, 6888 env=env) 6889 self.objectType = ('labels',) 6890 if self.id is not None: 6891 self.labels = self.instruction[self.id] 6892 else: 6893 self.id = NewId() 6894 self.labels = Labels(self.id, env=self.env) 6895 self.labelsDict = self.labels.GetInstruction() 6896 self.panel = self._labelPanel() 6897 6898 self._layout(self.panel) 6899 6900 def _labelPanel(self): 6901 panel = Panel(parent=self, id=wx.ID_ANY, style=wx.TAB_TRAVERSAL) 6902 6903 border = wx.BoxSizer(wx.VERTICAL) 6904 6905 box = StaticBox( 6906 parent=panel, id=wx.ID_ANY, label=" %s " % 6907 _("Vector label files created beforehand by v.label module")) 6908 sizer = wx.StaticBoxSizer(box, wx.VERTICAL) 6909 6910 self.select = Select( 6911 parent=panel, 6912 multiple=True, 6913 type='label', 6914 fullyQualified=False) 6915 self.select.SetValue(','.join(self.labelsDict['labels'])) 6916 self.select.SetFocus() 6917 sizer.Add( 6918 self.select, 6919 proportion=1, 6920 flag=wx.EXPAND | wx.ALL, 6921 border=5) 6922 helpText = StaticText( 6923 panel, id=wx.ID_ANY, 6924 label=_("You can select multiple label files.")) 6925 helpText.SetForegroundColour( 6926 wx.SystemSettings.GetColour( 6927 wx.SYS_COLOUR_GRAYTEXT)) 6928 sizer.Add( 6929 helpText, 6930 proportion=0, 6931 flag=wx.EXPAND | wx.LEFT | wx.RIGHT, 6932 border=5) 6933 6934 border.Add(sizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5) 6935 panel.SetSizer(border) 6936 6937 return panel 6938 6939 def update(self): 6940 value = self.select.GetValue() 6941 if not value: 6942 self.labelsDict['labels'] = [] 6943 else: 6944 self.labelsDict['labels'] = value.split(',') 6945 if self.id not in self.instruction: 6946 labels = Labels(self.id, env=self.env) 6947 self.instruction.AddInstruction(labels) 6948 6949 self.instruction[self.id].SetInstruction(self.labelsDict) 6950 6951 return True 6952