dialogs.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. """
  2. @package location_wizard.dialogs
  3. @brief Location wizard - dialogs
  4. Classes:
  5. - dialogs::RegionDef
  6. - dialogs::TransList
  7. - dialogs::SelectTransformDialog
  8. (C) 2007-2011 by the GRASS Development Team
  9. This program is free software under the GNU General Public License
  10. (>=v2). Read the file COPYING that comes with GRASS for details.
  11. @author Michael Barton
  12. @author Jachym Cepicky
  13. @author Martin Landa <landa.martin gmail.com>
  14. """
  15. import os
  16. import wx
  17. import wx.lib.scrolledpanel as scrolled
  18. from core import globalvar
  19. from core.gcmd import RunCommand
  20. from location_wizard.base import BaseClass
  21. from gui_core.wrap import Button, StaticText, StaticBox, \
  22. TextCtrl
  23. from grass.script import core as grass
  24. class RegionDef(BaseClass, wx.Dialog):
  25. """Page for setting default region extents and resolution
  26. """
  27. def __init__(self, parent, id=wx.ID_ANY, size=(800, 600), title=_(
  28. "Set default region extent and resolution"), location=None):
  29. wx.Dialog.__init__(self, parent, id, title, size=size)
  30. panel = wx.Panel(self, id=wx.ID_ANY)
  31. self.SetIcon(
  32. wx.Icon(
  33. os.path.join(
  34. globalvar.ICONDIR,
  35. 'grass.ico'),
  36. wx.BITMAP_TYPE_ICO))
  37. self.parent = parent
  38. self.location = location
  39. #
  40. # default values
  41. #
  42. # 2D
  43. self.north = 1.0
  44. self.south = 0.0
  45. self.east = 1.0
  46. self.west = 0.0
  47. self.nsres = 1.0
  48. self.ewres = 1.0
  49. # 3D
  50. self.top = 1.0
  51. self.bottom = 0.0
  52. # self.nsres3 = 1.0
  53. # self.ewres3 = 1.0
  54. self.tbres = 1.0
  55. #
  56. # inputs
  57. #
  58. # 2D
  59. self.tnorth = self.MakeTextCtrl(
  60. text=str(
  61. self.north), size=(
  62. 150, -1), parent=panel)
  63. self.tsouth = self.MakeTextCtrl(
  64. str(self.south),
  65. size=(150, -1),
  66. parent=panel)
  67. self.twest = self.MakeTextCtrl(
  68. str(self.west),
  69. size=(150, -1),
  70. parent=panel)
  71. self.teast = self.MakeTextCtrl(
  72. str(self.east),
  73. size=(150, -1),
  74. parent=panel)
  75. self.tnsres = self.MakeTextCtrl(
  76. str(self.nsres),
  77. size=(150, -1),
  78. parent=panel)
  79. self.tewres = self.MakeTextCtrl(
  80. str(self.ewres),
  81. size=(150, -1),
  82. parent=panel)
  83. #
  84. # labels
  85. #
  86. self.lrows = self.MakeLabel(parent=panel)
  87. self.lcols = self.MakeLabel(parent=panel)
  88. self.lcells = self.MakeLabel(parent=panel)
  89. #
  90. # buttons
  91. #
  92. self.bset = self.MakeButton(
  93. text=_("&Set region"),
  94. id=wx.ID_OK, parent=panel)
  95. self.bcancel = Button(panel, id=wx.ID_CANCEL)
  96. self.bset.SetDefault()
  97. #
  98. # image
  99. #
  100. self.img = wx.Image(os.path.join(globalvar.IMGDIR, "qgis_world.png"),
  101. wx.BITMAP_TYPE_PNG).ConvertToBitmap()
  102. #
  103. # set current working environment to PERMANENT mapset
  104. # in selected location in order to set default region (WIND)
  105. #
  106. envval = {}
  107. ret = RunCommand('g.gisenv',
  108. read=True)
  109. if ret:
  110. for line in ret.splitlines():
  111. key, val = line.split('=')
  112. envval[key] = val
  113. self.currlocation = envval['LOCATION_NAME'].strip("';")
  114. self.currmapset = envval['MAPSET'].strip("';")
  115. if self.currlocation != self.location or self.currmapset != 'PERMANENT':
  116. RunCommand('g.gisenv',
  117. set='LOCATION_NAME=%s' % self.location)
  118. RunCommand('g.gisenv',
  119. set='MAPSET=PERMANENT')
  120. else:
  121. dlg = wx.MessageBox(
  122. parent=self,
  123. message=_('Invalid location selected.'),
  124. caption=_("Error"),
  125. style=wx.ID_OK | wx.ICON_ERROR)
  126. return
  127. #
  128. # get current region settings
  129. #
  130. region = {}
  131. ret = RunCommand('g.region',
  132. read=True,
  133. flags='gp3')
  134. if ret:
  135. for line in ret.splitlines():
  136. key, val = line.split('=')
  137. region[key] = float(val)
  138. else:
  139. dlg = wx.MessageBox(
  140. parent=self,
  141. message=_("Invalid region"),
  142. caption=_("Error"),
  143. style=wx.ID_OK | wx.ICON_ERROR)
  144. dlg.ShowModal()
  145. dlg.Destroy()
  146. return
  147. #
  148. # update values
  149. # 2D
  150. self.north = float(region['n'])
  151. self.south = float(region['s'])
  152. self.east = float(region['e'])
  153. self.west = float(region['w'])
  154. self.nsres = float(region['nsres'])
  155. self.ewres = float(region['ewres'])
  156. self.rows = int(region['rows'])
  157. self.cols = int(region['cols'])
  158. self.cells = int(region['cells'])
  159. # 3D
  160. self.top = float(region['t'])
  161. self.bottom = float(region['b'])
  162. # self.nsres3 = float(region['nsres3'])
  163. # self.ewres3 = float(region['ewres3'])
  164. self.tbres = float(region['tbres'])
  165. self.depth = int(region['depths'])
  166. self.cells3 = int(region['cells3'])
  167. #
  168. # 3D box collapsable
  169. #
  170. self.infoCollapseLabelExp = _("Click here to show 3D settings")
  171. self.infoCollapseLabelCol = _("Click here to hide 3D settings")
  172. self.settings3D = wx.CollapsiblePane(parent=panel,
  173. label=self.infoCollapseLabelExp,
  174. style=wx.CP_DEFAULT_STYLE |
  175. wx.CP_NO_TLW_RESIZE | wx.EXPAND)
  176. self.MakeSettings3DPaneContent(self.settings3D.GetPane())
  177. self.settings3D.Collapse(False) # FIXME
  178. self.Bind(
  179. wx.EVT_COLLAPSIBLEPANE_CHANGED,
  180. self.OnSettings3DPaneChanged,
  181. self.settings3D)
  182. #
  183. # set current region settings
  184. #
  185. self.tnorth.SetValue(str(self.north))
  186. self.tsouth.SetValue(str(self.south))
  187. self.twest.SetValue(str(self.west))
  188. self.teast.SetValue(str(self.east))
  189. self.tnsres.SetValue(str(self.nsres))
  190. self.tewres.SetValue(str(self.ewres))
  191. self.ttop.SetValue(str(self.top))
  192. self.tbottom.SetValue(str(self.bottom))
  193. # self.tnsres3.SetValue(str(self.nsres3))
  194. # self.tewres3.SetValue(str(self.ewres3))
  195. self.ttbres.SetValue(str(self.tbres))
  196. self.lrows.SetLabel(_("Rows: %d") % self.rows)
  197. self.lcols.SetLabel(_("Cols: %d") % self.cols)
  198. self.lcells.SetLabel(_("Cells: %d") % self.cells)
  199. #
  200. # bindings
  201. #
  202. self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset)
  203. self.Bind(wx.EVT_BUTTON, self.OnCancel, self.bcancel)
  204. self.tnorth.Bind(wx.EVT_TEXT, self.OnValue)
  205. self.tsouth.Bind(wx.EVT_TEXT, self.OnValue)
  206. self.teast.Bind(wx.EVT_TEXT, self.OnValue)
  207. self.twest.Bind(wx.EVT_TEXT, self.OnValue)
  208. self.tnsres.Bind(wx.EVT_TEXT, self.OnValue)
  209. self.tewres.Bind(wx.EVT_TEXT, self.OnValue)
  210. self.ttop.Bind(wx.EVT_TEXT, self.OnValue)
  211. self.tbottom.Bind(wx.EVT_TEXT, self.OnValue)
  212. # self.tnsres3.Bind(wx.EVT_TEXT, self.OnValue)
  213. # self.tewres3.Bind(wx.EVT_TEXT, self.OnValue)
  214. self.ttbres.Bind(wx.EVT_TEXT, self.OnValue)
  215. self.__DoLayout(panel)
  216. self.SetMinSize(self.GetBestSize())
  217. self.minWindowSize = self.GetMinSize()
  218. wx.CallAfter(self.settings3D.Collapse, True)
  219. def MakeSettings3DPaneContent(self, pane):
  220. """Create 3D region settings pane"""
  221. border = wx.BoxSizer(wx.VERTICAL)
  222. gridSizer = wx.GridBagSizer(vgap=0, hgap=0)
  223. # inputs
  224. self.ttop = TextCtrl(parent=pane, id=wx.ID_ANY, value=str(self.top),
  225. size=(150, -1))
  226. self.tbottom = TextCtrl(
  227. parent=pane, id=wx.ID_ANY, value=str(
  228. self.bottom), size=(
  229. 150, -1))
  230. self.ttbres = TextCtrl(
  231. parent=pane, id=wx.ID_ANY, value=str(
  232. self.tbres), size=(
  233. 150, -1))
  234. # self.tnsres3 = wx.TextCtrl(parent = pane, id = wx.ID_ANY, value = str(self.nsres3),
  235. # size = (150, -1))
  236. # self.tewres3 = wx.TextCtrl(parent = pane, id = wx.ID_ANY, value = str(self.ewres3),
  237. # size = (150, -1))
  238. # labels
  239. self.ldepth = StaticText(
  240. parent=pane,
  241. label=_("Depth: %d") %
  242. self.depth)
  243. self.lcells3 = StaticText(
  244. parent=pane,
  245. label=_("3D Cells: %d") %
  246. self.cells3)
  247. # top
  248. gridSizer.Add(StaticText(parent=pane, label=_("Top")),
  249. flag=wx.ALIGN_CENTER |
  250. wx.LEFT | wx.RIGHT | wx.TOP, border=5,
  251. pos=(0, 1))
  252. gridSizer.Add(self.ttop,
  253. flag=wx.ALIGN_CENTER_HORIZONTAL |
  254. wx.ALL, border=5, pos=(1, 1))
  255. # bottom
  256. gridSizer.Add(StaticText(parent=pane, label=_("Bottom")),
  257. flag=wx.ALIGN_CENTER |
  258. wx.LEFT | wx.RIGHT | wx.TOP, border=5,
  259. pos=(0, 2))
  260. gridSizer.Add(self.tbottom,
  261. flag=wx.ALIGN_CENTER_HORIZONTAL |
  262. wx.ALL, border=5, pos=(1, 2))
  263. # tbres
  264. gridSizer.Add(
  265. StaticText(
  266. parent=pane,
  267. label=_("T-B resolution")),
  268. flag=wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.TOP,
  269. border=5,
  270. pos=(
  271. 0,
  272. 3))
  273. gridSizer.Add(self.ttbres,
  274. flag=wx.ALIGN_CENTER_HORIZONTAL |
  275. wx.ALL, border=5, pos=(1, 3))
  276. # res
  277. # gridSizer.Add(item = wx.StaticText(parent = pane, label = _("3D N-S resolution")),
  278. # flag = wx.ALIGN_CENTER |
  279. # wx.LEFT | wx.RIGHT | wx.TOP, border = 5,
  280. # pos = (2, 1))
  281. # gridSizer.Add(item = self.tnsres3,
  282. # flag = wx.ALIGN_CENTER_HORIZONTAL |
  283. # wx.ALL, border = 5, pos = (3, 1))
  284. # gridSizer.Add(item = wx.StaticText(parent = pane, label = _("3D E-W resolution")),
  285. # flag = wx.ALIGN_CENTER |
  286. # wx.LEFT | wx.RIGHT | wx.TOP, border = 5,
  287. # pos = (2, 3))
  288. # gridSizer.Add(item = self.tewres3,
  289. # flag = wx.ALIGN_CENTER_HORIZONTAL |
  290. # wx.ALL, border = 5, pos = (3, 3))
  291. # rows/cols/cells
  292. gridSizer.Add(self.ldepth,
  293. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
  294. wx.ALL, border=5, pos=(2, 1))
  295. gridSizer.Add(self.lcells3,
  296. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
  297. wx.ALL, border=5, pos=(2, 2))
  298. border.Add(gridSizer, proportion=1,
  299. flag=wx.ALL | wx.ALIGN_CENTER | wx.EXPAND, border=5)
  300. pane.SetSizer(border)
  301. border.Fit(pane)
  302. def OnSettings3DPaneChanged(self, event):
  303. """Collapse 3D settings box"""
  304. if self.settings3D.IsExpanded():
  305. self.settings3D.SetLabel(self.infoCollapseLabelCol)
  306. self.Layout()
  307. self.SetSize(self.GetBestSize())
  308. self.SetMinSize(self.GetSize())
  309. else:
  310. self.settings3D.SetLabel(self.infoCollapseLabelExp)
  311. self.Layout()
  312. self.SetSize(self.minWindowSize)
  313. self.SetMinSize(self.minWindowSize)
  314. self.SendSizeEvent()
  315. def __DoLayout(self, panel):
  316. """Window layout"""
  317. frameSizer = wx.BoxSizer(wx.VERTICAL)
  318. gridSizer = wx.GridBagSizer(vgap=0, hgap=0)
  319. settings3DSizer = wx.BoxSizer(wx.VERTICAL)
  320. buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
  321. # north
  322. gridSizer.Add(self.MakeLabel(text=_("North"), parent=panel),
  323. flag=wx.ALIGN_BOTTOM | wx.ALIGN_CENTER_HORIZONTAL |
  324. wx.TOP | wx.LEFT | wx.RIGHT, border=5, pos=(0, 2))
  325. gridSizer.Add(self.tnorth,
  326. flag=wx.ALIGN_CENTER_HORIZONTAL |
  327. wx.ALIGN_CENTER_VERTICAL |
  328. wx.ALL, border=5, pos=(1, 2))
  329. # west
  330. gridSizer.Add(self.MakeLabel(text=_("West"), parent=panel),
  331. flag=wx.ALIGN_RIGHT |
  332. wx.ALIGN_CENTER_VERTICAL |
  333. wx.LEFT | wx.TOP | wx.BOTTOM, border=5, pos=(2, 0))
  334. gridSizer.Add(self.twest,
  335. flag=wx.ALIGN_RIGHT |
  336. wx.ALIGN_CENTER_VERTICAL |
  337. wx.ALL, border=5, pos=(2, 1))
  338. gridSizer.Add(
  339. wx.StaticBitmap(
  340. panel, wx.ID_ANY, self.img, (-1, -1),
  341. (self.img.GetWidth(),
  342. self.img.GetHeight())),
  343. flag=wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
  344. pos=(2, 2))
  345. # east
  346. gridSizer.Add(self.teast,
  347. flag=wx.ALIGN_CENTER_HORIZONTAL |
  348. wx.ALIGN_CENTER_VERTICAL |
  349. wx.ALL, border=5, pos=(2, 3))
  350. gridSizer.Add(self.MakeLabel(text=_("East"), parent=panel),
  351. flag=wx.ALIGN_LEFT |
  352. wx.ALIGN_CENTER_VERTICAL |
  353. wx.RIGHT | wx.TOP | wx.BOTTOM, border=5, pos=(2, 4))
  354. # south
  355. gridSizer.Add(self.tsouth,
  356. flag=wx.ALIGN_CENTER_HORIZONTAL |
  357. wx.ALIGN_CENTER_VERTICAL |
  358. wx.ALL, border=5, pos=(3, 2))
  359. gridSizer.Add(self.MakeLabel(text=_("South"), parent=panel),
  360. flag=wx.ALIGN_TOP | wx.ALIGN_CENTER_HORIZONTAL |
  361. wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5, pos=(4, 2))
  362. # ns-res
  363. gridSizer.Add(self.MakeLabel(text=_("N-S resolution"), parent=panel),
  364. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
  365. wx.TOP | wx.LEFT | wx.RIGHT, border=5, pos=(5, 1))
  366. gridSizer.Add(self.tnsres,
  367. flag=wx.ALIGN_RIGHT |
  368. wx.ALIGN_CENTER_VERTICAL |
  369. wx.ALL, border=5, pos=(6, 1))
  370. # ew-res
  371. gridSizer.Add(self.MakeLabel(text=_("E-W resolution"), parent=panel),
  372. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
  373. wx.TOP | wx.LEFT | wx.RIGHT, border=5, pos=(5, 3))
  374. gridSizer.Add(self.tewres,
  375. flag=wx.ALIGN_RIGHT |
  376. wx.ALIGN_CENTER_VERTICAL |
  377. wx.ALL, border=5, pos=(6, 3))
  378. # rows/cols/cells
  379. gridSizer.Add(self.lrows,
  380. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
  381. wx.ALL, border=5, pos=(7, 1))
  382. gridSizer.Add(self.lcells,
  383. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
  384. wx.ALL, border=5, pos=(7, 2))
  385. gridSizer.Add(self.lcols,
  386. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
  387. wx.ALL, border=5, pos=(7, 3))
  388. # 3D
  389. settings3DSizer.Add(self.settings3D,
  390. flag=wx.ALL,
  391. border=5)
  392. # buttons
  393. buttonSizer.Add(self.bcancel, proportion=1,
  394. flag=wx.ALIGN_RIGHT |
  395. wx.ALIGN_CENTER_VERTICAL |
  396. wx.ALL, border=10)
  397. buttonSizer.Add(self.bset, proportion=1,
  398. flag=wx.ALIGN_CENTER |
  399. wx.ALIGN_CENTER_VERTICAL |
  400. wx.ALL, border=10)
  401. frameSizer.Add(gridSizer, proportion=1,
  402. flag=wx.ALL | wx.ALIGN_CENTER, border=5)
  403. frameSizer.Add(settings3DSizer, proportion=0,
  404. flag=wx.ALL | wx.ALIGN_CENTER, border=5)
  405. frameSizer.Add(buttonSizer, proportion=0,
  406. flag=wx.ALL | wx.ALIGN_RIGHT, border=5)
  407. self.SetAutoLayout(True)
  408. panel.SetSizer(frameSizer)
  409. frameSizer.Fit(panel)
  410. self.Layout()
  411. def OnValue(self, event):
  412. """Set given value"""
  413. try:
  414. if event.GetId() == self.tnorth.GetId():
  415. self.north = float(event.GetString())
  416. elif event.GetId() == self.tsouth.GetId():
  417. self.south = float(event.GetString())
  418. elif event.GetId() == self.teast.GetId():
  419. self.east = float(event.GetString())
  420. elif event.GetId() == self.twest.GetId():
  421. self.west = float(event.GetString())
  422. elif event.GetId() == self.tnsres.GetId():
  423. self.nsres = float(event.GetString())
  424. elif event.GetId() == self.tewres.GetId():
  425. self.ewres = float(event.GetString())
  426. elif event.GetId() == self.ttop.GetId():
  427. self.top = float(event.GetString())
  428. elif event.GetId() == self.tbottom.GetId():
  429. self.bottom = float(event.GetString())
  430. # elif event.GetId() == self.tnsres3.GetId():
  431. # self.nsres3 = float(event.GetString())
  432. # elif event.GetId() == self.tewres3.GetId():
  433. # self.ewres3 = float(event.GetString())
  434. elif event.GetId() == self.ttbres.GetId():
  435. self.tbres = float(event.GetString())
  436. self.__UpdateInfo()
  437. except ValueError as e:
  438. if len(event.GetString()) > 0 and event.GetString() != '-':
  439. dlg = wx.MessageBox(parent=self,
  440. message=_("Invalid value: %s") % e,
  441. caption=_("Error"),
  442. style=wx.OK | wx.ICON_ERROR)
  443. # reset values
  444. self.tnorth.SetValue(str(self.north))
  445. self.tsouth.SetValue(str(self.south))
  446. self.teast.SetValue(str(self.east))
  447. self.twest.SetValue(str(self.west))
  448. self.tnsres.SetValue(str(self.nsres))
  449. self.tewres.SetValue(str(self.ewres))
  450. self.ttop.SetValue(str(self.top))
  451. self.tbottom.SetValue(str(self.bottom))
  452. self.ttbres.SetValue(str(self.tbres))
  453. # self.tnsres3.SetValue(str(self.nsres3))
  454. # self.tewres3.SetValue(str(self.ewres3))
  455. event.Skip()
  456. def __UpdateInfo(self):
  457. """Update number of rows/cols/cells"""
  458. try:
  459. rows = int((self.north - self.south) / self.nsres)
  460. cols = int((self.east - self.west) / self.ewres)
  461. except ZeroDivisionError:
  462. return
  463. self.rows = rows
  464. self.cols = cols
  465. self.cells = self.rows * self.cols
  466. try:
  467. depth = int((self.top - self.bottom) / self.tbres)
  468. except ZeroDivisionError:
  469. return
  470. self.depth = depth
  471. self.cells3 = self.rows * self.cols * self.depth
  472. # 2D
  473. self.lrows.SetLabel(_("Rows: %d") % self.rows)
  474. self.lcols.SetLabel(_("Cols: %d") % self.cols)
  475. self.lcells.SetLabel(_("Cells: %d") % self.cells)
  476. # 3D
  477. self.ldepth.SetLabel(_("Depth: %d" % self.depth))
  478. self.lcells3.SetLabel(_("3D Cells: %d" % self.cells3))
  479. def OnSetButton(self, event=None):
  480. """Set default region"""
  481. ret = RunCommand('g.region',
  482. flags='sa',
  483. n=self.north,
  484. s=self.south,
  485. e=self.east,
  486. w=self.west,
  487. nsres=self.nsres,
  488. ewres=self.ewres,
  489. t=self.top,
  490. b=self.bottom,
  491. tbres=self.tbres)
  492. if ret == 0:
  493. self.Destroy()
  494. def OnCancel(self, event):
  495. self.Destroy()
  496. class TransList(wx.VListBox):
  497. """Creates a multiline listbox for selecting datum transforms"""
  498. def OnDrawItem(self, dc, rect, n):
  499. if self.GetSelection() == n:
  500. c = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHTTEXT)
  501. else:
  502. c = self.GetForegroundColour()
  503. dc.SetFont(self.GetFont())
  504. dc.SetTextForeground(c)
  505. dc.DrawLabel(self._getItemText(n), rect,
  506. wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL)
  507. def OnMeasureItem(self, n):
  508. height = 0
  509. if self._getItemText(n) is None:
  510. return height
  511. for line in self._getItemText(n).splitlines():
  512. w, h = self.GetTextExtent(line)
  513. height += h
  514. return height + 5
  515. def _getItemText(self, item):
  516. global transformlist
  517. transitem = transformlist[item]
  518. if transitem.strip() != '':
  519. return transitem
  520. class SelectTransformDialog(wx.Dialog):
  521. """Dialog for selecting datum transformations"""
  522. def __init__(self, parent, transforms,
  523. title=_("Select datum transformation"),
  524. pos=wx.DefaultPosition, size=wx.DefaultSize,
  525. style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
  526. wx.Dialog.__init__(self, parent, wx.ID_ANY, title, pos, size, style)
  527. global transformlist
  528. self.CentreOnParent()
  529. # default transform number
  530. self.transnum = 0
  531. panel = scrolled.ScrolledPanel(self, wx.ID_ANY)
  532. sizer = wx.BoxSizer(wx.VERTICAL)
  533. #
  534. # set panel sizer
  535. #
  536. panel.SetSizer(sizer)
  537. panel.SetupScrolling()
  538. #
  539. # dialog body
  540. #
  541. bodyBox = StaticBox(
  542. parent=panel, id=wx.ID_ANY, label=" %s " %
  543. _("Select from list of datum transformations"))
  544. bodySizer = wx.StaticBoxSizer(bodyBox)
  545. # add no transform option
  546. transforms = '---\n\n0\nDo not apply any datum transformations\n\n' + transforms
  547. transformlist = transforms.split('---')
  548. tlistlen = len(transformlist)
  549. # calculate size for transform list
  550. height = 0
  551. width = 0
  552. for line in transforms.splitlines():
  553. w, h = self.GetTextExtent(line)
  554. height += h
  555. width = max(width, w)
  556. height = height + 5
  557. if height > 400:
  558. height = 400
  559. width = width + 5
  560. if width > 400:
  561. width = 400
  562. #
  563. # VListBox for displaying and selecting transformations
  564. #
  565. self.translist = TransList(
  566. panel, id=-1, size=(width, height),
  567. style=wx.SUNKEN_BORDER)
  568. self.translist.SetItemCount(tlistlen)
  569. self.translist.SetSelection(2)
  570. self.translist.SetFocus()
  571. self.Bind(wx.EVT_LISTBOX, self.ClickTrans, self.translist)
  572. bodySizer.Add(
  573. self.translist,
  574. proportion=1,
  575. flag=wx.ALIGN_CENTER | wx.ALL | wx.EXPAND)
  576. #
  577. # buttons
  578. #
  579. btnsizer = wx.StdDialogButtonSizer()
  580. btn = Button(parent=panel, id=wx.ID_OK)
  581. btn.SetDefault()
  582. btnsizer.AddButton(btn)
  583. btn = Button(parent=panel, id=wx.ID_CANCEL)
  584. btnsizer.AddButton(btn)
  585. btnsizer.Realize()
  586. sizer.Add(bodySizer, proportion=1,
  587. flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)
  588. sizer.Add(btnsizer, proportion=0,
  589. flag=wx.ALL | wx.ALIGN_RIGHT, border=5)
  590. sizer.Fit(panel)
  591. self.SetSize(self.GetBestSize())
  592. self.Layout()
  593. def ClickTrans(self, event):
  594. """Get the number of the datum transform to use in g.proj"""
  595. self.transnum = event.GetSelection()
  596. self.transnum = self.transnum - 1
  597. def GetTransform(self):
  598. """Get the number of the datum transform to use in g.proj"""
  599. self.transnum = self.translist.GetSelection()
  600. self.transnum = self.transnum - 1
  601. return self.transnum
  602. def testRegionDef():
  603. import sys
  604. import wx.lib.inspection
  605. import grass.script as grass
  606. app = wx.App()
  607. dlg = RegionDef(None, location=grass.gisenv()["LOCATION_NAME"])
  608. dlg.Show()
  609. wx.lib.inspection.InspectionTool().Show()
  610. app.MainLoop()
  611. if __name__ == '__main__':
  612. testRegionDef()