gdialogs.py 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. """
  2. @package gdialogs.py
  3. @brief Common dialog used in wxGUI.
  4. List of classes:
  5. - NewVectorDialog
  6. - SavedRegion
  7. - DecorationDialog
  8. - TextLayerDialog
  9. - LoadMapLayersDialog
  10. (C) 2008 by the GRASS Development Team
  11. This program is free software under the GNU General Public
  12. License (>=v2). Read the file COPYING that comes with GRASS
  13. for details.
  14. @author Martin Landa <landa.martin gmail.com>
  15. """
  16. import sys
  17. import re
  18. import wx
  19. import gcmd
  20. import grassenv
  21. import globalvar
  22. import gselect
  23. import menuform
  24. import utils
  25. from preferences import globalSettings as UserSettings
  26. class NewVectorDialog(wx.Dialog):
  27. """Create new vector map layer"""
  28. def __init__(self, parent, id, title,
  29. style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
  30. wx.Dialog.__init__(self, parent, id, title, style=style)
  31. self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
  32. self.btnCancel = wx.Button(self.panel, wx.ID_CANCEL)
  33. self.btnOK = wx.Button(self.panel, wx.ID_OK)
  34. self.btnOK.SetDefault()
  35. self.btnOK.Enable(False)
  36. self.label = wx.StaticText(parent=self.panel, id=wx.ID_ANY,
  37. label=_("Name for new vector map:"))
  38. self.mapName = gselect.Select(parent=self.panel, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
  39. type='vector', mapsets=[grassenv.GetGRASSVariable('MAPSET'),])
  40. self.mapName.Bind(wx.EVT_TEXT, self.OnMapName)
  41. # TODO remove (see Preferences dialog)
  42. self.overwrite = wx.CheckBox(parent=self.panel, id=wx.ID_ANY,
  43. label=_("Allow output files to overwrite existing files"))
  44. self.overwrite.SetValue(UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))
  45. self.__Layout()
  46. self.SetMinSize(self.GetSize())
  47. def OnMapName(self, event):
  48. """Name for vector map layer given"""
  49. if len(event.GetString()) > 0:
  50. self.btnOK.Enable(True)
  51. else:
  52. self.btnOK.Enable(False)
  53. def __Layout(self):
  54. """Do layout"""
  55. sizer = wx.BoxSizer(wx.VERTICAL)
  56. dataSizer = wx.BoxSizer(wx.VERTICAL)
  57. dataSizer.Add(self.label, proportion=0,
  58. flag=wx.ALL, border=1)
  59. dataSizer.Add(self.mapName, proportion=0,
  60. flag=wx.EXPAND | wx.ALL, border=1)
  61. dataSizer.Add(self.overwrite, proportion=0,
  62. flag=wx.ALL, border=1)
  63. # buttons
  64. btnSizer = wx.StdDialogButtonSizer()
  65. btnSizer.AddButton(self.btnCancel)
  66. btnSizer.AddButton(self.btnOK)
  67. btnSizer.Realize()
  68. sizer.Add(item=dataSizer, proportion=1,
  69. flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
  70. sizer.Add(item=btnSizer, proportion=0,
  71. flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
  72. self.panel.SetSizer(sizer)
  73. sizer.Fit(self)
  74. def GetName(self):
  75. """Return (mapName, overwrite)"""
  76. mapName = self.mapName.GetValue().split('@', 1)[0]
  77. return (mapName,
  78. self.overwrite.IsChecked())
  79. def CreateNewVector(parent, title=_('Create new vector map'),
  80. exceptMap=None):
  81. """Create new vector map layer
  82. @return name of create vector map
  83. @return None of failure
  84. """
  85. dlg = NewVectorDialog(parent=parent, id=wx.ID_ANY, title=title)
  86. if dlg.ShowModal() == wx.ID_OK:
  87. outmap, overwrite = dlg.GetName()
  88. if outmap == exceptMap:
  89. wx.MessageBox(parent=parent,
  90. message=_("Unable to create vector map <%s>.") % outmap,
  91. caption=_("Error"),
  92. style=wx.ID_OK | wx.ICON_ERROR | wx.CENTRE)
  93. return False
  94. if outmap == '': # should not happen
  95. return False
  96. cmd = ["v.edit",
  97. "map=%s" % outmap,
  98. "tool=create"]
  99. if overwrite is True:
  100. cmd.append('--overwrite')
  101. try:
  102. p = gcmd.Command(cmd, stderr=None)
  103. except gcmd.CmdError, e:
  104. print >> sys.stderr, e
  105. return None
  106. if p.returncode == 0:
  107. # return fully qualified map name
  108. return outmap + '@' + grassenv.GetGRASSVariable('MAPSET')
  109. return None
  110. class SavedRegion(wx.Dialog):
  111. def __init__(self, parent, id, title="", pos=wx.DefaultPosition, size=wx.DefaultSize,
  112. style=wx.DEFAULT_DIALOG_STYLE,
  113. loadsave='load'):
  114. """
  115. Loading and saving of display extents to saved region file
  116. """
  117. wx.Dialog.__init__(self, parent, id, title, pos, size, style)
  118. self.loadsave = loadsave
  119. self.wind = ''
  120. sizer = wx.BoxSizer(wx.VERTICAL)
  121. box = wx.BoxSizer(wx.HORIZONTAL)
  122. if loadsave == 'load':
  123. label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Load region:"))
  124. box.Add(item=label, proportion=0, flag=wx.ALIGN_CENTRE | wx.ALL, border=5)
  125. self.selection = gselect.Select(parent=self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE,
  126. type='windows')
  127. box.Add(item=self.selection, proportion=0, flag=wx.ALIGN_CENTRE | wx.ALL, border=5)
  128. self.selection.Bind(wx.EVT_TEXT, self.OnSelection)
  129. elif loadsave == 'save':
  130. label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Save region:"))
  131. box.Add(item=label, proportion=0, flag=wx.ALIGN_CENTRE | wx.ALL, border=5)
  132. self.textentry = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="",
  133. size=globalvar.DIALOG_TEXTCTRL_SIZE)
  134. box.Add(item=self.textentry, proportion=0, flag=wx.ALIGN_CENTRE | wx.ALL, border=5)
  135. self.textentry.Bind(wx.EVT_TEXT, self.OnText)
  136. sizer.Add(item=box, proportion=0, flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL,
  137. border=5)
  138. line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL)
  139. sizer.Add(item=line, proportion=0,
  140. flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border=5)
  141. btnsizer = wx.StdDialogButtonSizer()
  142. btn = wx.Button(self, wx.ID_OK)
  143. btn.SetDefault()
  144. btnsizer.AddButton(btn)
  145. btn = wx.Button(self, wx.ID_CANCEL)
  146. btnsizer.AddButton(btn)
  147. btnsizer.Realize()
  148. sizer.Add(item=btnsizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5)
  149. self.SetSizer(sizer)
  150. sizer.Fit(self)
  151. def OnSelection(self, event):
  152. self.wind = event.GetString()
  153. def OnText(self, event):
  154. self.wind = event.GetString()
  155. class DecorationDialog(wx.Dialog):
  156. """
  157. Controls setting options and displaying/hiding map overlay decorations
  158. """
  159. def __init__(self, parent, ovlId, title, cmd, name=None,
  160. pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE,
  161. checktxt='', ctrltxt=''):
  162. wx.Dialog.__init__(self, parent, wx.ID_ANY, title, pos, size, style)
  163. self.ovlId = ovlId # PseudoDC id
  164. self.cmd = cmd
  165. self.name = name # overlay name
  166. self.parent = parent # MapFrame
  167. sizer = wx.BoxSizer(wx.VERTICAL)
  168. box = wx.BoxSizer(wx.HORIZONTAL)
  169. self.chkbox = wx.CheckBox(parent=self, id=wx.ID_ANY, label=checktxt)
  170. if self.parent.Map.GetOverlay(self.ovlId) is None:
  171. self.chkbox.SetValue(True)
  172. else:
  173. self.chkbox.SetValue(self.parent.MapWindow.overlays[self.ovlId]['layer'].IsActive())
  174. box.Add(item=self.chkbox, proportion=0,
  175. flag=wx.ALIGN_CENTRE|wx.ALL, border=5)
  176. sizer.Add(item=box, proportion=0,
  177. flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=5)
  178. box = wx.BoxSizer(wx.HORIZONTAL)
  179. optnbtn = wx.Button(parent=self, id=wx.ID_ANY, label=_("Set options"))
  180. box.Add(item=optnbtn, proportion=0, flag=wx.ALIGN_CENTRE|wx.ALL, border=5)
  181. sizer.Add(item=box, proportion=0,
  182. flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=5)
  183. box = wx.BoxSizer(wx.HORIZONTAL)
  184. label = wx.StaticText(parent=self, id=wx.ID_ANY,
  185. label=_("Drag %s with mouse in pointer mode to position.\n"
  186. "Double-click to change options." % ctrltxt))
  187. if self.name == 'legend':
  188. label.SetLabel(label.GetLabel() + _('\nDefine raster map name for legend in '
  189. 'properties dialog.'))
  190. box.Add(item=label, proportion=0,
  191. flag=wx.ALIGN_CENTRE|wx.ALL, border=5)
  192. sizer.Add(item=box, proportion=0,
  193. flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=5)
  194. line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20,-1), style=wx.LI_HORIZONTAL)
  195. sizer.Add(item=line, proportion=0,
  196. flag=wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border=5)
  197. # buttons
  198. btnsizer = wx.StdDialogButtonSizer()
  199. self.btnOK = wx.Button(parent=self, id=wx.ID_OK)
  200. self.btnOK.SetDefault()
  201. if self.name == 'legend':
  202. self.btnOK.Enable(False)
  203. btnsizer.AddButton(self.btnOK)
  204. btnCancel = wx.Button(parent=self, id=wx.ID_CANCEL)
  205. btnsizer.AddButton(btnCancel)
  206. btnsizer.Realize()
  207. sizer.Add(item=btnsizer, proportion=0,
  208. flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5)
  209. #
  210. # bindings
  211. #
  212. self.Bind(wx.EVT_BUTTON, self.OnOptions, optnbtn)
  213. self.Bind(wx.EVT_BUTTON, self.OnCancel, btnCancel)
  214. self.Bind(wx.EVT_BUTTON, self.OnOK, self.btnOK)
  215. self.SetSizer(sizer)
  216. sizer.Fit(self)
  217. # create overlay if doesn't exist
  218. self._CreateOverlay()
  219. if len(self.parent.MapWindow.overlays[self.ovlId]['cmd']) > 1:
  220. mapName = utils.GetLayerNameFromCmd(self.parent.MapWindow.overlays[self.ovlId]['cmd'])
  221. if self.parent.MapWindow.overlays[self.ovlId]['propwin'] is None and mapName:
  222. # build properties dialog
  223. menuform.GUI().ParseCommand(cmd=self.cmd,
  224. completed=(self.GetOptData, self.name, ''),
  225. parentframe=self.parent, show=False)
  226. if mapName:
  227. # enable 'OK' button
  228. self.btnOK.Enable()
  229. # set title
  230. self.SetTitle(_('Legend of raster map <%s>') % \
  231. mapName)
  232. def _CreateOverlay(self):
  233. if not self.parent.Map.GetOverlay(self.ovlId):
  234. overlay = self.parent.Map.AddOverlay(id=self.ovlId, type=self.name,
  235. command=self.cmd,
  236. l_active=False, l_render=False, l_hidden=True)
  237. self.parent.MapWindow.overlays[self.ovlId] = {}
  238. self.parent.MapWindow.overlays[self.ovlId] = { 'layer' : overlay,
  239. 'params' : None,
  240. 'propwin' : None,
  241. 'cmd' : self.cmd,
  242. 'coords': (10, 10),
  243. 'pdcType': 'image' }
  244. else:
  245. self.parent.MapWindow.overlays[self.ovlId]['propwin'].get_dcmd = self.GetOptData
  246. def OnOptions(self, event):
  247. """ self.SetSizer(sizer)
  248. sizer.Fit(self)
  249. Sets option for decoration map overlays
  250. """
  251. if self.parent.MapWindow.overlays[self.ovlId]['propwin'] is None:
  252. # build properties dialog
  253. menuform.GUI().ParseCommand(cmd=self.cmd,
  254. completed=(self.GetOptData, self.name, ''),
  255. parentframe=self.parent)
  256. else:
  257. if self.parent.MapWindow.overlays[self.ovlId]['propwin'].IsShown():
  258. self.parent.MapWindow.overlays[self.ovlId]['propwin'].SetFocus()
  259. else:
  260. self.parent.MapWindow.overlays[self.ovlId]['propwin'].Show()
  261. def OnCancel(self, event):
  262. """Cancel dialog"""
  263. self.parent.dialogs['barscale'] = None
  264. self.Destroy()
  265. def OnOK(self, event):
  266. """Button 'OK' pressed"""
  267. # enable or disable overlay
  268. self.parent.Map.GetOverlay(self.ovlId).SetActive(self.chkbox.IsChecked())
  269. # update map
  270. self.parent.MapWindow.UpdateMap()
  271. # close dialog
  272. self.OnCancel(None)
  273. def GetOptData(self, dcmd, layer, params, propwin):
  274. """Process decoration layer data"""
  275. # update layer data
  276. if params:
  277. self.parent.MapWindow.overlays[self.ovlId]['params'] = params
  278. if dcmd:
  279. self.parent.MapWindow.overlays[self.ovlId]['cmd'] = dcmd
  280. self.parent.MapWindow.overlays[self.ovlId]['propwin'] = propwin
  281. # change parameters for item in layers list in render.Map
  282. # "Use mouse..." (-m) flag causes GUI freeze, trac #119
  283. try:
  284. self.parent.MapWindow.overlays[self.ovlId]['cmd'].remove('-m')
  285. except ValueError:
  286. pass
  287. self.parent.Map.ChangeOverlay(id=self.ovlId, type=self.name,
  288. command=self.parent.MapWindow.overlays[self.ovlId]['cmd'],
  289. l_active=self.parent.MapWindow.overlays[self.ovlId]['layer'].IsActive(),
  290. l_render=False, l_hidden=True)
  291. if self.name == 'legend' and \
  292. params and \
  293. not self.btnOK.IsEnabled():
  294. self.btnOK.Enable()
  295. self.SetTitle(_('Legend of raster map <%s>') % \
  296. utils.GetLayerNameFromCmd(self.parent.MapWindow.overlays[self.ovlId]['cmd']))
  297. class TextLayerDialog(wx.Dialog):
  298. """
  299. Controls setting options and displaying/hiding map overlay decorations
  300. """
  301. def __init__(self, parent, ovlId, title, name='text',
  302. pos=wx.DefaultPosition, size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE):
  303. wx.Dialog.__init__(self, parent, wx.ID_ANY, title, pos, size, style)
  304. self.ovlId = ovlId
  305. self.parent = parent
  306. if self.ovlId in self.parent.MapWindow.textdict:
  307. self.currText, self.currFont, self.currClr, self.currRot = self.parent.MapWindow.textdict[drawid]
  308. else:
  309. self.currClr = wx.BLACK
  310. self.currText = ''
  311. self.currFont = self.GetFont()
  312. self.currRot = 0.0
  313. sizer = wx.BoxSizer(wx.VERTICAL)
  314. box = wx.GridBagSizer(vgap=5, hgap=5)
  315. # text entry
  316. label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Enter text:"))
  317. box.Add(item=label,
  318. flag=wx.ALIGN_CENTER_VERTICAL,
  319. pos=(0, 0))
  320. self.textentry = wx.TextCtrl(parent=self, id=wx.ID_ANY, value="", size=(300,-1))
  321. self.textentry.SetFont(self.currFont)
  322. self.textentry.SetForegroundColour(self.currClr)
  323. self.textentry.SetValue(self.currText)
  324. box.Add(item=self.textentry,
  325. pos=(0, 1))
  326. # rotation
  327. label = wx.StaticText(parent=self, id=wx.ID_ANY, label=_("Rotation:"))
  328. box.Add(item=label,
  329. flag=wx.ALIGN_CENTER_VERTICAL,
  330. pos=(1, 0))
  331. self.rotation = wx.SpinCtrl(parent=self, id=wx.ID_ANY, value="", pos=(30, 50),
  332. size=(75,-1), style=wx.SP_ARROW_KEYS)
  333. self.rotation.SetRange(-360, 360)
  334. self.rotation.SetValue(int(self.currRot))
  335. box.Add(item=self.rotation,
  336. flag=wx.ALIGN_RIGHT,
  337. pos=(1, 1))
  338. # font
  339. fontbtn = wx.Button(parent=self, id=wx.ID_ANY, label=_("Set font"))
  340. box.Add(item=fontbtn,
  341. flag=wx.ALIGN_RIGHT,
  342. pos=(2, 1))
  343. sizer.Add(item=box, proportion=1,
  344. flag=wx.ALL, border=10)
  345. # note
  346. box = wx.BoxSizer(wx.HORIZONTAL)
  347. label = wx.StaticText(parent=self, id=wx.ID_ANY,
  348. label=_("Drag text with mouse in pointer mode "
  349. "to position.\nDouble-click to change options"))
  350. box.Add(item=label, proportion=0,
  351. flag=wx.ALIGN_CENTRE | wx.ALL, border=5)
  352. sizer.Add(item=box, proportion=0,
  353. flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER | wx.ALL, border=5)
  354. line = wx.StaticLine(parent=self, id=wx.ID_ANY,
  355. size=(20,-1), style=wx.LI_HORIZONTAL)
  356. sizer.Add(item=line, proportion=0,
  357. flag=wx.EXPAND | wx.ALIGN_CENTRE | wx.ALL, border=5)
  358. btnsizer = wx.StdDialogButtonSizer()
  359. btn = wx.Button(parent=self, id=wx.ID_OK)
  360. btn.SetDefault()
  361. btnsizer.AddButton(btn)
  362. btn = wx.Button(parent=self, id=wx.ID_CANCEL)
  363. btnsizer.AddButton(btn)
  364. btnsizer.Realize()
  365. sizer.Add(item=btnsizer, proportion=0,
  366. flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
  367. self.SetSizer(sizer)
  368. sizer.Fit(self)
  369. # bindings
  370. self.Bind(wx.EVT_BUTTON, self.OnSelectFont, fontbtn)
  371. self.Bind(wx.EVT_TEXT, self.OnText, self.textentry)
  372. self.Bind(wx.EVT_SPINCTRL, self.OnRotation, self.rotation)
  373. def OnText(self, event):
  374. """Change text string"""
  375. self.currText = event.GetString()
  376. def OnRotation(self, event):
  377. """Change rotation"""
  378. self.currRot = event.GetInt()
  379. event.Skip()
  380. def OnSelectFont(self, event):
  381. """Change font"""
  382. data = wx.FontData()
  383. data.EnableEffects(True)
  384. data.SetColour(self.currClr) # set colour
  385. data.SetInitialFont(self.currFont)
  386. dlg = wx.FontDialog(self, data)
  387. if dlg.ShowModal() == wx.ID_OK:
  388. data = dlg.GetFontData()
  389. self.currFont = data.GetChosenFont()
  390. self.currClr = data.GetColour()
  391. self.textentry.SetFont(self.currFont)
  392. self.textentry.SetForegroundColour(self.currClr)
  393. self.Layout()
  394. dlg.Destroy()
  395. def GetValues(self):
  396. """Get text properties"""
  397. return (self.currText, self.currFont,
  398. self.currClr, self.currRot)
  399. class LoadMapLayersDialog(wx.Dialog):
  400. """Load selected map layers (raster, vector) into layer tree"""
  401. def __init__(self, parent, title, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
  402. wx.Dialog.__init__(self, parent=parent, id=wx.ID_ANY, title=title, style=style)
  403. self.parent = parent # GMFrame
  404. #
  405. # dialog body
  406. #
  407. self.bodySizer = self.__createDialogBody()
  408. # update list of layer to be loaded
  409. self.map_layers = [] # list of map layers (full list type/mapset)
  410. self.LoadMapLayers(self.layerType.GetStringSelection()[:4],
  411. self.mapset.GetStringSelection())
  412. #
  413. # buttons
  414. #
  415. btnCancel = wx.Button(self, wx.ID_CANCEL)
  416. btnOk = wx.Button(self, wx.ID_OK, _("Load") )
  417. btnOk.SetDefault()
  418. #
  419. # bindigs
  420. #
  421. #btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
  422. #btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  423. #
  424. # sizers & do layout
  425. #
  426. btnSizer = wx.StdDialogButtonSizer()
  427. btnSizer.AddButton(btnCancel)
  428. btnSizer.AddButton(btnOk)
  429. btnSizer.Realize()
  430. mainSizer = wx.BoxSizer(wx.VERTICAL)
  431. mainSizer.Add(item=self.bodySizer, proportion=1,
  432. flag=wx.EXPAND | wx.ALL, border=5)
  433. mainSizer.Add(item=btnSizer, proportion=0,
  434. flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
  435. self.SetSizer(mainSizer)
  436. mainSizer.Fit(self)
  437. # set dialog min size
  438. self.SetMinSize(self.GetSize())
  439. def __createDialogBody(self):
  440. bodySizer = wx.GridBagSizer(vgap=3, hgap=3)
  441. bodySizer.AddGrowableCol(1)
  442. bodySizer.AddGrowableRow(3)
  443. # layer type
  444. bodySizer.Add(item=wx.StaticText(parent=self, label=_("Map layer type:")),
  445. flag=wx.ALIGN_CENTER_VERTICAL,
  446. pos=(0,0))
  447. self.layerType = wx.Choice(parent=self, id=wx.ID_ANY,
  448. choices=['raster', 'vector'], size=(100,-1))
  449. self.layerType.SetSelection(0)
  450. bodySizer.Add(item=self.layerType,
  451. pos=(0,1))
  452. # mapset filter
  453. bodySizer.Add(item=wx.StaticText(parent=self, label=_("Mapset:")),
  454. flag=wx.ALIGN_CENTER_VERTICAL,
  455. pos=(1,0))
  456. self.mapset = wx.ComboBox(parent=self, id=wx.ID_ANY,
  457. style=wx.CB_SIMPLE | wx.CB_READONLY,
  458. choices=utils.ListOfMapsets(),
  459. size=(250,-1))
  460. self.mapset.SetStringSelection(grassenv.GetGRASSVariable("MAPSET"))
  461. bodySizer.Add(item=self.mapset,
  462. pos=(1,1))
  463. # map name filter
  464. bodySizer.Add(item=wx.StaticText(parent=self, label=_("Filter:")),
  465. flag=wx.ALIGN_CENTER_VERTICAL,
  466. pos=(2,0))
  467. self.filter = wx.TextCtrl(parent=self, id=wx.ID_ANY,
  468. value="",
  469. size=(250,-1))
  470. bodySizer.Add(item=self.filter,
  471. flag=wx.EXPAND,
  472. pos=(2,1))
  473. # layer list
  474. bodySizer.Add(item=wx.StaticText(parent=self, label=_("List of maps:")),
  475. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_TOP,
  476. pos=(3,0))
  477. self.layers = wx.CheckListBox(parent=self, id=wx.ID_ANY,
  478. size=(250, 100),
  479. choices=[])
  480. bodySizer.Add(item=self.layers,
  481. flag=wx.EXPAND,
  482. pos=(3,1))
  483. # bindings
  484. self.layerType.Bind(wx.EVT_CHOICE, self.OnChangeParams)
  485. self.mapset.Bind(wx.EVT_COMBOBOX, self.OnChangeParams)
  486. self.layers.Bind(wx.EVT_RIGHT_DOWN, self.OnMenu)
  487. self.filter.Bind(wx.EVT_TEXT, self.OnFilter)
  488. return bodySizer
  489. def LoadMapLayers(self, type, mapset):
  490. """Load list of map layers
  491. @param type layer type ('raster' or 'vector')
  492. @param mapset mapset name
  493. """
  494. list = gcmd.Command(['g.mlist',
  495. 'type=%s' % type,
  496. 'mapset=%s' % mapset])
  497. self.map_layers = []
  498. for map in list.ReadStdOutput():
  499. self.map_layers.append(map)
  500. self.layers.Set(self.map_layers)
  501. # check all items by default
  502. for item in range(self.layers.GetCount()):
  503. self.layers.Check(item)
  504. def OnChangeParams(self, event):
  505. """Filter parameters changed by user"""
  506. # update list of layer to be loaded
  507. self.LoadMapLayers(self.layerType.GetStringSelection()[:4],
  508. self.mapset.GetStringSelection())
  509. event.Skip()
  510. def OnMenu(self, event):
  511. """Table description area, context menu"""
  512. if not hasattr(self, "popupID1"):
  513. self.popupDataID1 = wx.NewId()
  514. self.popupDataID2 = wx.NewId()
  515. self.Bind(wx.EVT_MENU, self.OnSelectAll, id=self.popupDataID1)
  516. self.Bind(wx.EVT_MENU, self.OnDeselectAll, id=self.popupDataID2)
  517. # generate popup-menu
  518. menu = wx.Menu()
  519. menu.Append(self.popupDataID1, _("Select all"))
  520. menu.Append(self.popupDataID2, _("Deselect all"))
  521. self.PopupMenu(menu)
  522. menu.Destroy()
  523. def OnSelectAll(self, event):
  524. """Select all map layer from list"""
  525. for item in range(self.layers.GetCount()):
  526. self.layers.Check(item, True)
  527. def OnDeselectAll(self, event):
  528. """Select all map layer from list"""
  529. for item in range(self.layers.GetCount()):
  530. self.layers.Check(item, False)
  531. def OnFilter(self, event):
  532. """Apply filter for map names"""
  533. if len(event.GetString()) == 0:
  534. self.layers.Set(self.map_layers)
  535. return
  536. list = []
  537. for layer in self.map_layers:
  538. if re.compile('^' + event.GetString()).search(layer):
  539. list.append(layer)
  540. self.layers.Set(list)
  541. event.Skip()
  542. def GetMapLayers(self):
  543. """Return list of checked map layers"""
  544. layerNames = []
  545. for indx in self.layers.GetSelections():
  546. # layers.append(self.layers.GetStringSelec(indx))
  547. pass
  548. # return fully qualified map names
  549. mapset = self.mapset.GetStringSelection()
  550. for item in range(self.layers.GetCount()):
  551. if not self.layers.IsChecked(item):
  552. continue
  553. layerNames.append(self.layers.GetString(item) + '@' + mapset)
  554. return layerNames
  555. def GetLayerType(self):
  556. """Get selected layer type"""
  557. return self.layerType.GetStringSelection()