dialogs.py 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264
  1. """!
  2. @package wxplot.dialogs
  3. @brief Dialogs for different plotting routines
  4. Classes:
  5. - dialogs::ProfileRasterDialog
  6. - dialogs::ScatterRasterDialog
  7. - dialogs::PlotStatsFrame
  8. - dialogs::HistRasterDialog
  9. - dialogs::TextDialog
  10. - dialogs::OptDialog
  11. (C) 2011-2012 by the GRASS Development Team
  12. This program is free software under the GNU General Public License
  13. (>=v2). Read the file COPYING that comes with GRASS for details.
  14. @author Michael Barton, Arizona State University
  15. """
  16. import wx
  17. import wx.lib.colourselect as csel
  18. import wx.lib.scrolledpanel as scrolled
  19. from core import globalvar
  20. from core.settings import UserSettings
  21. from core.utils import _
  22. from gui_core.gselect import Select
  23. from grass.script import core as grass
  24. class ProfileRasterDialog(wx.Dialog):
  25. def __init__(self, parent, id = wx.ID_ANY,
  26. title = _("Select raster maps to profile"),
  27. style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
  28. """!Dialog to select raster maps to profile.
  29. """
  30. wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
  31. self.parent = parent
  32. self.colorList = ["blue", "red", "green", "yellow", "magenta", "cyan", \
  33. "aqua", "black", "grey", "orange", "brown", "purple", "violet", \
  34. "indigo"]
  35. self.rasterList = self.parent.rasterList
  36. self._do_layout()
  37. def _do_layout(self):
  38. sizer = wx.BoxSizer(wx.VERTICAL)
  39. box = wx.GridBagSizer (hgap = 3, vgap = 3)
  40. rastText = ''
  41. for r in self.rasterList:
  42. rastText += '%s,' % r
  43. rastText = rastText.rstrip(',')
  44. txt = _("Select raster map(s) to profile:")
  45. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = txt)
  46. box.Add(item = label,
  47. flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  48. selection = Select(self, id = wx.ID_ANY,
  49. size = globalvar.DIALOG_GSELECT_SIZE,
  50. type = 'cell', multiple=True)
  51. selection.SetValue(rastText)
  52. selection.Bind(wx.EVT_TEXT, self.OnSelection)
  53. box.Add(item = selection, pos = (0, 1))
  54. sizer.Add(item = box, proportion = 0,
  55. flag = wx.ALL, border = 10)
  56. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  57. sizer.Add(item = line, proportion = 0,
  58. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 5)
  59. btnsizer = wx.StdDialogButtonSizer()
  60. btn = wx.Button(self, wx.ID_OK)
  61. btn.SetDefault()
  62. btnsizer.AddButton(btn)
  63. btn = wx.Button(self, wx.ID_CANCEL)
  64. btnsizer.AddButton(btn)
  65. btnsizer.Realize()
  66. sizer.Add(item = btnsizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  67. self.SetSizer(sizer)
  68. sizer.Fit(self)
  69. def OnSelection(self, event):
  70. """!Choose maps to profile. Convert these into a list
  71. """
  72. self.rasterList = []
  73. self.rasterList = event.GetString().split(',')
  74. class ScatterRasterDialog(wx.Dialog):
  75. def __init__(self, parent, id = wx.ID_ANY,
  76. title = _("Select pairs of raster maps for scatterplots"),
  77. style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
  78. """!Dialog to select raster maps to profile.
  79. """
  80. wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
  81. self.parent = parent
  82. self.rasterList = self.parent.rasterList
  83. self.bins = self.parent.bins
  84. self.scattertype = self.parent.scattertype
  85. self.maptype = self.parent.maptype
  86. self.spinbins = ''
  87. self.colorList = ["blue", "red", "green", "yellow", "magenta", "cyan", \
  88. "aqua", "black", "grey", "orange", "brown", "purple", "violet", \
  89. "indigo"]
  90. self._do_layout()
  91. def _do_layout(self):
  92. sizer = wx.BoxSizer(wx.VERTICAL)
  93. box = wx.GridBagSizer (hgap = 3, vgap = 3)
  94. # parse raster pair tuples
  95. rastText = ''
  96. if len(self.rasterList) > 0:
  97. for r in self.rasterList:
  98. if isinstance(r, tuple):
  99. rastText += '%s,%s,' % r
  100. else:
  101. rastText += '%s,' % r
  102. rastText = rastText.rstrip(',')
  103. # select rasters
  104. txt = _("Select pairs of raster maps for bivariate scatterplots:")
  105. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = txt)
  106. box.Add(item = label,
  107. flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  108. selection = Select(self, id = wx.ID_ANY,
  109. size = globalvar.DIALOG_GSELECT_SIZE,
  110. type = 'cell', multiple=True)
  111. selection.SetValue(rastText)
  112. selection.Bind(wx.EVT_TEXT, self.OnSelection)
  113. box.Add(item = selection, pos = (0, 1))
  114. # Nsteps for FP maps
  115. label = wx.StaticText(parent = self, id = wx.ID_ANY,
  116. label = _("Number of bins (for FP maps)"))
  117. box.Add(item = label,
  118. flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  119. self.spinbins = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "", pos = (30, 50),
  120. size = (100,-1), style = wx.SP_ARROW_KEYS)
  121. self.spinbins.SetRange(1,1000)
  122. self.spinbins.SetValue(self.bins)
  123. box.Add(item = self.spinbins,
  124. flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 1))
  125. #### TODO possibly make bubble plots with marker size proportional to cell counts
  126. # # scatterplot type
  127. # label = wx.StaticText(parent = self, id = wx.ID_ANY,
  128. # label = _("Scatterplot type"))
  129. # box.Add(item = label,
  130. # flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  131. # types = ['normal', 'bubble']
  132. # scattertype = wx.ComboBox(parent = self, id = wx.ID_ANY, size = (250, -1),
  133. # choices = types, style = wx.CB_DROPDOWN)
  134. # scattertype.SetStringSelection(self.scattertype)
  135. # box.Add(item = scattertype,
  136. # flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 1))
  137. sizer.Add(item = box, proportion = 0,
  138. flag = wx.ALL, border = 10)
  139. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  140. sizer.Add(item = line, proportion = 0,
  141. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 5)
  142. btnsizer = wx.StdDialogButtonSizer()
  143. btn = wx.Button(self, wx.ID_OK)
  144. btn.SetDefault()
  145. btnsizer.AddButton(btn)
  146. btn = wx.Button(self, wx.ID_CANCEL)
  147. btnsizer.AddButton(btn)
  148. btnsizer.Realize()
  149. sizer.Add(item = btnsizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  150. self.spinbins.Bind(wx.EVT_TEXT, self.OnSetBins)
  151. self.spinbins.Bind(wx.EVT_SPINCTRL, self.OnSetBins)
  152. # scattertype.Bind(wx.EVT_TEXT, self.OnSetScattertypes)
  153. self.SetSizer(sizer)
  154. sizer.Fit(self)
  155. def OnSelection(self, event):
  156. """!Select raster maps for scatterplot. Must select maps in pairs.
  157. """
  158. self.rasterList = event.GetString().split(',', 1)
  159. def OnSetBins(self, event):
  160. """!Bins for histogramming FP maps (=nsteps in r.stats)
  161. """
  162. self.bins = self.spinbins.GetValue()
  163. def OnSetScattertypes(self, event):
  164. self.scattertype = event.GetString()
  165. def GetRasterPairs(self):
  166. """!Get raster pairs"""
  167. pairsList = list()
  168. pair = list()
  169. for r in self.rasterList:
  170. pair.append(r)
  171. if len(pair) == 2:
  172. pairsList.append(tuple(pair))
  173. pair = list()
  174. return list(pairsList)
  175. def GetSettings(self):
  176. """!Get type and bins"""
  177. return self.scattertype, self.bins
  178. class PlotStatsFrame(wx.Frame):
  179. def __init__(self, parent, id, message = '', title = '',
  180. style = wx.DEFAULT_FRAME_STYLE, **kwargs):
  181. """!Dialog to display and save statistics for plots
  182. """
  183. wx.Frame.__init__(self, parent, id, style = style, **kwargs)
  184. self.SetLabel(_("Statistics"))
  185. sp = scrolled.ScrolledPanel(self, -1, size=(400, 400),
  186. style = wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER, name="Statistics" )
  187. #
  188. # initialize variables
  189. #
  190. self.parent = parent
  191. self.message = message
  192. self.title = title
  193. self.CenterOnParent()
  194. #
  195. # Display statistics
  196. #
  197. sizer = wx.BoxSizer(wx.VERTICAL)
  198. txtSizer = wx.BoxSizer(wx.VERTICAL)
  199. statstitle = wx.StaticText(parent = self, id = wx.ID_ANY, label = self.title)
  200. sizer.Add(item = statstitle, proportion = 0,
  201. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 3)
  202. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  203. sizer.Add(item = line, proportion = 0,
  204. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 3)
  205. for stats in self.message:
  206. statstxt = wx.StaticText(parent = sp, id = wx.ID_ANY, label = stats)
  207. statstxt.SetBackgroundColour("WHITE")
  208. txtSizer.Add(item = statstxt, proportion = 1,
  209. flag = wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 3)
  210. line = wx.StaticLine(parent = sp, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  211. txtSizer.Add(item = line, proportion = 0,
  212. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, border = 3)
  213. sp.SetSizer(txtSizer)
  214. sp.SetAutoLayout(1)
  215. sp.SetupScrolling()
  216. sizer.Add(item = sp, proportion = 1,
  217. flag = wx.GROW | wx.LEFT | wx.RIGHT | wx.BOTTOM, border = 3)
  218. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  219. sizer.Add(item = line, proportion = 0,
  220. flag = wx.GROW |wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 3)
  221. #
  222. # buttons
  223. #
  224. btnSizer = wx.BoxSizer(wx.HORIZONTAL)
  225. btn_clipboard = wx.Button(self, id = wx.ID_COPY, label = _('C&opy'))
  226. btn_clipboard.SetToolTipString(_("Copy regression statistics the clipboard (Ctrl+C)"))
  227. btnSizer.Add(item = btn_clipboard, proportion = 0, flag = wx.ALIGN_LEFT | wx.ALL, border = 5)
  228. btnCancel = wx.Button(self, wx.ID_CLOSE)
  229. btnCancel.SetDefault()
  230. btnSizer.Add(item = btnCancel, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  231. sizer.Add(item = btnSizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  232. # bindings
  233. btnCancel.Bind(wx.EVT_BUTTON, self.OnClose)
  234. btn_clipboard.Bind(wx.EVT_BUTTON, self.OnCopy)
  235. self.SetSizer(sizer)
  236. sizer.Fit(self)
  237. def OnCopy(self, event):
  238. """!Copy the regression stats to the clipboard
  239. """
  240. str = self.title + '\n'
  241. for item in self.message:
  242. str += item
  243. rdata = wx.TextDataObject()
  244. rdata.SetText(str)
  245. if wx.TheClipboard.Open():
  246. wx.TheClipboard.SetData(rdata)
  247. wx.TheClipboard.Close()
  248. wx.MessageBox(_("Regression statistics copied to clipboard"))
  249. def OnClose(self, event):
  250. """!Button 'Close' pressed
  251. """
  252. self.Close(True)
  253. class HistRasterDialog(wx.Dialog):
  254. def __init__(self, parent, id = wx.ID_ANY,
  255. title = _("Select raster map or imagery group to histogram"),
  256. style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
  257. """!Dialog to select raster maps to histogram.
  258. """
  259. wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
  260. self.parent = parent
  261. self.rasterList = self.parent.rasterList
  262. self.group = self.parent.group
  263. self.bins = self.parent.bins
  264. self.histtype = self.parent.histtype
  265. self.maptype = self.parent.maptype
  266. self.spinbins = ''
  267. self._do_layout()
  268. def _do_layout(self):
  269. sizer = wx.BoxSizer(wx.VERTICAL)
  270. box = wx.GridBagSizer (hgap = 3, vgap = 3)
  271. #
  272. # select single raster or image group to histogram radio buttons
  273. #
  274. self.rasterRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("Histogram single raster"), style = wx.RB_GROUP)
  275. self.groupRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("Histogram imagery group"))
  276. if self.maptype == 'raster':
  277. self.rasterRadio.SetValue(True)
  278. elif self.maptype == 'group':
  279. self.groupRadio.SetValue(True)
  280. box.Add(item = self.rasterRadio, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  281. box.Add(item = self.groupRadio, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 1))
  282. #
  283. # Select a raster to histogram
  284. #
  285. label = wx.StaticText(parent = self, id = wx.ID_ANY,
  286. label = _("Select raster map:"))
  287. box.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  288. self.rselection = Select(self, id = wx.ID_ANY,
  289. size = globalvar.DIALOG_GSELECT_SIZE,
  290. type = 'cell')
  291. if self.groupRadio.GetValue() == True:
  292. self.rselection.Disable()
  293. else:
  294. rastText = ''
  295. for r in self.rasterList:
  296. rastText += '%s,' % r
  297. rastText = rastText.rstrip(',')
  298. self.rselection.SetValue(rastText)
  299. box.Add(item = self.rselection, pos = (1, 1))
  300. #
  301. # Select an image group to histogram
  302. #
  303. label = wx.StaticText(parent = self, id = wx.ID_ANY,
  304. label = _("Select image group:"))
  305. box.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  306. self.gselection = Select(self, id = wx.ID_ANY,
  307. size = globalvar.DIALOG_GSELECT_SIZE,
  308. type = 'group')
  309. if self.rasterRadio.GetValue() == True:
  310. self.gselection.Disable()
  311. else:
  312. if self.group != None: self.gselection.SetValue(self.group)
  313. box.Add(item = self.gselection, pos = (2, 1))
  314. #
  315. # Nsteps for FP maps and histogram type selection
  316. #
  317. label = wx.StaticText(parent = self, id = wx.ID_ANY,
  318. label = _("Number of bins (for FP maps)"))
  319. box.Add(item = label,
  320. flag = wx.ALIGN_CENTER_VERTICAL, pos = (3, 0))
  321. self.spinbins = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "", pos = (30, 50),
  322. size = (100,-1), style = wx.SP_ARROW_KEYS)
  323. self.spinbins.SetRange(1,1000)
  324. self.spinbins.SetValue(self.bins)
  325. box.Add(item = self.spinbins,
  326. flag = wx.ALIGN_CENTER_VERTICAL, pos = (3, 1))
  327. label = wx.StaticText(parent = self, id = wx.ID_ANY,
  328. label = _("Histogram type"))
  329. box.Add(item = label,
  330. flag = wx.ALIGN_CENTER_VERTICAL, pos = (4, 0))
  331. types = ['count', 'percent', 'area']
  332. histtype = wx.ComboBox(parent = self, id = wx.ID_ANY, size = (250, -1),
  333. choices = types, style = wx.CB_DROPDOWN)
  334. histtype.SetStringSelection(self.histtype)
  335. box.Add(item = histtype,
  336. flag = wx.ALIGN_CENTER_VERTICAL, pos = (4, 1))
  337. sizer.Add(item = box, proportion = 0,
  338. flag = wx.ALL, border = 10)
  339. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  340. sizer.Add(item = line, proportion = 0,
  341. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 5)
  342. btnsizer = wx.StdDialogButtonSizer()
  343. btn = wx.Button(self, wx.ID_OK)
  344. btn.SetDefault()
  345. btnsizer.AddButton(btn)
  346. btn = wx.Button(self, wx.ID_CANCEL)
  347. btnsizer.AddButton(btn)
  348. btnsizer.Realize()
  349. sizer.Add(item = btnsizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  350. #
  351. # bindings
  352. #
  353. self.Bind(wx.EVT_RADIOBUTTON, self.OnHistMap, self.rasterRadio)
  354. self.Bind(wx.EVT_RADIOBUTTON, self.OnHistMap, self.groupRadio)
  355. self.rselection.Bind(wx.EVT_TEXT, self.OnRasterSelection)
  356. self.gselection.Bind(wx.EVT_TEXT, self.OnGroupSelection)
  357. self.spinbins.Bind(wx.EVT_TEXT, self.OnSetBins)
  358. self.spinbins.Bind(wx.EVT_SPINCTRL, self.OnSetBins)
  359. histtype.Bind(wx.EVT_TEXT, self.OnSetHisttypes)
  360. self.SetSizer(sizer)
  361. sizer.Fit(self)
  362. def OnHistMap(self, event):
  363. """!Hander for radio buttons to choose between histogramming a
  364. single raster and an imagery group
  365. """
  366. if self.rasterRadio.GetValue() == True:
  367. self.maptype = 'raster'
  368. self.rselection.Enable()
  369. self.gselection.Disable()
  370. self.gselection.SetValue('')
  371. elif self.groupRadio.GetValue() == True:
  372. self.maptype = 'group'
  373. self.gselection.Enable()
  374. self.rselection.Disable()
  375. self.rselection.SetValue('')
  376. else:
  377. pass
  378. def OnRasterSelection(self, event):
  379. """!Handler for selecting a single raster map
  380. """
  381. self.rasterList = []
  382. self.rasterList.append(event.GetString())
  383. def OnGroupSelection(self, event):
  384. """!Handler for selecting imagery group
  385. """
  386. self.rasterList = []
  387. self.group = event.GetString()
  388. ret = grass.read_command('i.group',
  389. group = '%s' % self.group,
  390. quiet = True,
  391. flags = 'g').strip().split('\n')
  392. if ret not in [None, '', ['']]:
  393. self.rasterList = ret
  394. else:
  395. wx.MessageBox(message = _("Selected group must be in current mapset"),
  396. caption = _('Invalid input'),
  397. style = wx.OK|wx.ICON_ERROR)
  398. def OnSetBins(self, event):
  399. """!Bins for histogramming FP maps (=nsteps in r.stats)
  400. """
  401. self.bins = self.spinbins.GetValue()
  402. def OnSetHisttypes(self, event):
  403. self.histtype = event.GetString()
  404. class TextDialog(wx.Dialog):
  405. def __init__(self, parent, id, title, plottype = '',
  406. style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
  407. """!Dialog to set histogram text options: font, title
  408. and font size, axis labels and font size
  409. """
  410. wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
  411. #
  412. # initialize variables
  413. #
  414. # combo box entry lists
  415. self.ffamilydict = { 'default' : wx.FONTFAMILY_DEFAULT,
  416. 'decorative' : wx.FONTFAMILY_DECORATIVE,
  417. 'roman' : wx.FONTFAMILY_ROMAN,
  418. 'script' : wx.FONTFAMILY_SCRIPT,
  419. 'swiss' : wx.FONTFAMILY_SWISS,
  420. 'modern' : wx.FONTFAMILY_MODERN,
  421. 'teletype' : wx.FONTFAMILY_TELETYPE }
  422. self.fstyledict = { 'normal' : wx.FONTSTYLE_NORMAL,
  423. 'slant' : wx.FONTSTYLE_SLANT,
  424. 'italic' : wx.FONTSTYLE_ITALIC }
  425. self.fwtdict = { 'normal' : wx.FONTWEIGHT_NORMAL,
  426. 'light' : wx.FONTWEIGHT_LIGHT,
  427. 'bold' : wx.FONTWEIGHT_BOLD }
  428. self.parent = parent
  429. self.plottype = plottype
  430. self.ptitle = self.parent.ptitle
  431. self.xlabel = self.parent.xlabel
  432. self.ylabel = self.parent.ylabel
  433. self.properties = self.parent.properties # read-only
  434. # font size
  435. self.fontfamily = self.properties['font']['wxfont'].GetFamily()
  436. self.fontstyle = self.properties['font']['wxfont'].GetStyle()
  437. self.fontweight = self.properties['font']['wxfont'].GetWeight()
  438. self._do_layout()
  439. def _do_layout(self):
  440. """!Do layout"""
  441. # dialog layout
  442. sizer = wx.BoxSizer(wx.VERTICAL)
  443. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  444. label = " %s " % _("Text settings"))
  445. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  446. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  447. #
  448. # profile title
  449. #
  450. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Profile title:"))
  451. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  452. self.ptitleentry = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (250,-1))
  453. # self.ptitleentry.SetFont(self.font)
  454. self.ptitleentry.SetValue(self.ptitle)
  455. gridSizer.Add(item = self.ptitleentry, pos = (0, 1))
  456. #
  457. # title font
  458. #
  459. tlabel = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Title font size (pts):"))
  460. gridSizer.Add(item = tlabel, flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  461. self.ptitlesize = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "", pos = (30, 50),
  462. size = (50,-1), style = wx.SP_ARROW_KEYS)
  463. self.ptitlesize.SetRange(5,100)
  464. self.ptitlesize.SetValue(int(self.properties['font']['prop']['titleSize']))
  465. gridSizer.Add(item = self.ptitlesize, pos = (1, 1))
  466. #
  467. # x-axis label
  468. #
  469. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("X-axis label:"))
  470. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  471. self.xlabelentry = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (250,-1))
  472. # self.xlabelentry.SetFont(self.font)
  473. self.xlabelentry.SetValue(self.xlabel)
  474. gridSizer.Add(item = self.xlabelentry, pos = (2, 1))
  475. #
  476. # y-axis label
  477. #
  478. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Y-axis label:"))
  479. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (3, 0))
  480. self.ylabelentry = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (250,-1))
  481. # self.ylabelentry.SetFont(self.font)
  482. self.ylabelentry.SetValue(self.ylabel)
  483. gridSizer.Add(item = self.ylabelentry, pos = (3, 1))
  484. #
  485. # font size
  486. #
  487. llabel = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Label font size (pts):"))
  488. gridSizer.Add(item = llabel, flag = wx.ALIGN_CENTER_VERTICAL, pos = (4, 0))
  489. self.axislabelsize = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "", pos = (30, 50),
  490. size = (50, -1), style = wx.SP_ARROW_KEYS)
  491. self.axislabelsize.SetRange(5, 100)
  492. self.axislabelsize.SetValue(int(self.properties['font']['prop']['axisSize']))
  493. gridSizer.Add(item = self.axislabelsize, pos = (4,1))
  494. boxSizer.Add(item = gridSizer)
  495. sizer.Add(item = boxSizer, flag = wx.ALL | wx.EXPAND, border = 3)
  496. #
  497. # font settings
  498. #
  499. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  500. label = " %s " % _("Font settings"))
  501. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  502. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  503. #
  504. # font family
  505. #
  506. label1 = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Font family:"))
  507. gridSizer.Add(item = label1, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  508. self.ffamilycb = wx.ComboBox(parent = self, id = wx.ID_ANY, size = (250, -1),
  509. choices = self.ffamilydict.keys(), style = wx.CB_DROPDOWN)
  510. self.ffamilycb.SetStringSelection('swiss')
  511. for item in self.ffamilydict.items():
  512. if self.fontfamily == item[1]:
  513. self.ffamilycb.SetStringSelection(item[0])
  514. break
  515. gridSizer.Add(item = self.ffamilycb, pos = (0, 1), flag = wx.ALIGN_RIGHT)
  516. #
  517. # font style
  518. #
  519. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Style:"))
  520. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  521. self.fstylecb = wx.ComboBox(parent = self, id = wx.ID_ANY, size = (250, -1),
  522. choices = self.fstyledict.keys(), style = wx.CB_DROPDOWN)
  523. self.fstylecb.SetStringSelection('normal')
  524. for item in self.fstyledict.items():
  525. if self.fontstyle == item[1]:
  526. self.fstylecb.SetStringSelection(item[0])
  527. break
  528. gridSizer.Add(item = self.fstylecb, pos = (1, 1), flag = wx.ALIGN_RIGHT)
  529. #
  530. # font weight
  531. #
  532. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Weight:"))
  533. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  534. self.fwtcb = wx.ComboBox(parent = self, size = (250, -1),
  535. choices = self.fwtdict.keys(), style = wx.CB_DROPDOWN)
  536. self.fwtcb.SetStringSelection('normal')
  537. for item in self.fwtdict.items():
  538. if self.fontweight == item[1]:
  539. self.fwtcb.SetStringSelection(item[0])
  540. break
  541. gridSizer.Add(item = self.fwtcb, pos = (2, 1), flag = wx.ALIGN_RIGHT)
  542. gridSizer.AddGrowableCol(1)
  543. boxSizer.Add(item = gridSizer, flag = wx.EXPAND)
  544. sizer.Add(item = boxSizer, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
  545. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  546. sizer.Add(item = line, proportion = 0,
  547. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 3)
  548. #
  549. # buttons
  550. #
  551. btnSave = wx.Button(self, wx.ID_SAVE)
  552. btnApply = wx.Button(self, wx.ID_APPLY)
  553. btnOk = wx.Button(self, wx.ID_OK)
  554. btnCancel = wx.Button(self, wx.ID_CANCEL)
  555. btnOk.SetDefault()
  556. # bindings
  557. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  558. btnApply.SetToolTipString(_("Apply changes for the current session"))
  559. btnOk.Bind(wx.EVT_BUTTON, self.OnOk)
  560. btnOk.SetToolTipString(_("Apply changes for the current session and close dialog"))
  561. btnOk.SetDefault()
  562. btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
  563. btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
  564. btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  565. btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
  566. # sizers
  567. btnStdSizer = wx.StdDialogButtonSizer()
  568. btnStdSizer.AddButton(btnOk)
  569. btnStdSizer.AddButton(btnApply)
  570. btnStdSizer.AddButton(btnCancel)
  571. btnStdSizer.Realize()
  572. btnSizer = wx.BoxSizer(wx.HORIZONTAL)
  573. btnSizer.Add(item = btnSave, proportion = 0, flag = wx.ALIGN_LEFT | wx.ALL, border = 5)
  574. btnSizer.Add(item = btnStdSizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  575. sizer.Add(item = btnSizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  576. #
  577. # bindings
  578. #
  579. self.ptitleentry.Bind(wx.EVT_TEXT, self.OnTitle)
  580. self.xlabelentry.Bind(wx.EVT_TEXT, self.OnXLabel)
  581. self.ylabelentry.Bind(wx.EVT_TEXT, self.OnYLabel)
  582. self.SetSizer(sizer)
  583. sizer.Fit(self)
  584. def OnTitle(self, event):
  585. self.ptitle = event.GetString()
  586. def OnXLabel(self, event):
  587. self.xlabel = event.GetString()
  588. def OnYLabel(self, event):
  589. self.ylabel = event.GetString()
  590. def UpdateSettings(self):
  591. self.properties['font']['prop']['titleSize'] = self.ptitlesize.GetValue()
  592. self.properties['font']['prop']['axisSize'] = self.axislabelsize.GetValue()
  593. family = self.ffamilydict[self.ffamilycb.GetStringSelection()]
  594. self.properties['font']['wxfont'].SetFamily(family)
  595. style = self.fstyledict[self.fstylecb.GetStringSelection()]
  596. self.properties['font']['wxfont'].SetStyle(style)
  597. weight = self.fwtdict[self.fwtcb.GetStringSelection()]
  598. self.properties['font']['wxfont'].SetWeight(weight)
  599. def OnSave(self, event):
  600. """!Button 'Save' pressed"""
  601. self.OnApply(None)
  602. fileSettings = {}
  603. UserSettings.ReadSettingsFile(settings = fileSettings)
  604. fileSettings[self.plottype] = UserSettings.Get(group = self.plottype)
  605. UserSettings.SaveToFile(fileSettings)
  606. self.parent.parent.GetLayerManager().GetLogWindow().WriteLog(_('Plot text sizes saved to file \'%s\'.') % UserSettings.filePath)
  607. self.EndModal(wx.ID_OK)
  608. def OnApply(self, event):
  609. """!Button 'Apply' pressed"""
  610. self.UpdateSettings()
  611. self.parent.OnPlotText(self)
  612. def OnOk(self, event):
  613. """!Button 'OK' pressed"""
  614. self.OnApply(None)
  615. self.EndModal(wx.ID_OK)
  616. def OnCancel(self, event):
  617. """!Button 'Cancel' pressed"""
  618. self.EndModal(wx.ID_CANCEL)
  619. class OptDialog(wx.Dialog):
  620. def __init__(self, parent, id, title, plottype = '',
  621. style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
  622. """!Dialog to set various options for data plotted, including: line
  623. width, color, style; marker size, color, fill, and style; grid
  624. and legend options.
  625. """
  626. wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
  627. # init variables
  628. self.parent = parent
  629. self.linestyledict = parent.linestyledict
  630. self.ptfilldict = parent.ptfilldict
  631. self.parent = parent
  632. self.plottype = plottype
  633. self.pttypelist = ['circle',
  634. 'dot',
  635. 'square',
  636. 'triangle',
  637. 'triangle_down',
  638. 'cross',
  639. 'plus']
  640. self.axislist = ['min',
  641. 'auto',
  642. 'custom']
  643. # widgets ids
  644. self.wxId = {}
  645. self.parent = parent
  646. # read-only
  647. self.raster = self.parent.raster
  648. self.rasterList = self.parent.rasterList
  649. self.properties = self.parent.properties
  650. self.map = ''
  651. if len(self.rasterList) == 0:
  652. wx.MessageBox(parent = self,
  653. message = _("No map or image group selected to plot."),
  654. caption = _("Warning"), style = wx.OK | wx.ICON_ERROR)
  655. self._do_layout()
  656. def ConvertTuples(self, tlist):
  657. """!Converts tuples to strings when rasterList contains raster pairs
  658. for scatterplot
  659. """
  660. list = []
  661. for i in tlist:
  662. i = str(i).strip('()')
  663. list.append(i)
  664. return list
  665. def _do_layout(self):
  666. """!Options dialog layout
  667. """
  668. sizer = wx.BoxSizer(wx.VERTICAL)
  669. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  670. label = " %s " % _("Plot settings"))
  671. boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  672. self.wxId['pcolor'] = 0
  673. self.wxId['pwidth'] = 0
  674. self.wxId['pstyle'] = 0
  675. self.wxId['psize'] = 0
  676. self.wxId['ptype'] = 0
  677. self.wxId['pfill'] = 0
  678. self.wxId['plegend'] = 0
  679. self.wxId['marker'] = {}
  680. self.wxId['x-axis'] = {}
  681. self.wxId['y-axis'] = {}
  682. #
  683. # plot line settings and point settings
  684. #
  685. if len(self.rasterList) == 0: return
  686. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  687. label = _("Map/image plotted"))
  688. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  689. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  690. row = 0
  691. choicelist = []
  692. for i in self.rasterList:
  693. choicelist.append(str(i))
  694. self.mapchoice = wx.Choice(parent = self, id = wx.ID_ANY, size = (300, -1),
  695. choices = choicelist)
  696. self.mapchoice.SetToolTipString(_("Settings for selected map"))
  697. if not self.map:
  698. self.map = self.rasterList[self.mapchoice.GetCurrentSelection()]
  699. else:
  700. self.mapchoice.SetStringSelection(str(self.map))
  701. gridSizer.Add(item = self.mapchoice, flag = wx.ALIGN_CENTER_VERTICAL,
  702. pos = (row, 0), span = (1, 2))
  703. #
  704. # options for line plots (profiles and histograms)
  705. #
  706. if self.plottype != 'scatter':
  707. row +=1
  708. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Line color"))
  709. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  710. color = csel.ColourSelect(parent = self, id = wx.ID_ANY, colour = self.raster[self.map]['pcolor'])
  711. self.wxId['pcolor'] = color.GetId()
  712. gridSizer.Add(item = color, pos = (row, 1))
  713. row += 1
  714. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Line width"))
  715. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  716. width = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "",
  717. size = (50,-1), style = wx.SP_ARROW_KEYS)
  718. width.SetRange(1, 10)
  719. width.SetValue(self.raster[self.map]['pwidth'])
  720. self.wxId['pwidth'] = width.GetId()
  721. gridSizer.Add(item = width, pos = (row, 1))
  722. row +=1
  723. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Line style"))
  724. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  725. style = wx.Choice(parent = self, id = wx.ID_ANY,
  726. size = (120, -1), choices = self.linestyledict.keys())
  727. style.SetStringSelection(self.raster[self.map]['pstyle'])
  728. self.wxId['pstyle'] = style.GetId()
  729. gridSizer.Add(item = style, pos = (row, 1))
  730. row += 1
  731. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Legend"))
  732. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  733. legend = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (200,-1))
  734. legend.SetValue(self.raster[self.map]['plegend'])
  735. gridSizer.Add(item = legend, pos = (row, 1))
  736. self.wxId['plegend'] = legend.GetId()
  737. boxSizer.Add(item = gridSizer)
  738. boxMainSizer.Add(item = boxSizer, flag = wx.ALL, border = 3)
  739. #
  740. # segment marker settings for profiles only
  741. #
  742. if self.plottype == 'profile':
  743. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  744. label = " %s " % _("Transect segment marker settings"))
  745. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  746. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  747. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Color"))
  748. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  749. ptcolor = csel.ColourSelect(parent = self, id = wx.ID_ANY, colour = self.properties['marker']['color'])
  750. self.wxId['marker']['color'] = ptcolor.GetId()
  751. gridSizer.Add(item = ptcolor, pos = (0, 1))
  752. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Size"))
  753. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  754. ptsize = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "",
  755. size = (50, -1), style = wx.SP_ARROW_KEYS)
  756. ptsize.SetRange(1, 10)
  757. ptsize.SetValue(self.properties['marker']['size'])
  758. self.wxId['marker']['size'] = ptsize.GetId()
  759. gridSizer.Add(item = ptsize, pos = (1, 1))
  760. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Fill"))
  761. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  762. ptfill = wx.Choice(parent = self, id = wx.ID_ANY,
  763. size = (120, -1), choices = self.ptfilldict.keys())
  764. ptfill.SetStringSelection(self.properties['marker']['fill'])
  765. self.wxId['marker']['fill'] = ptfill.GetId()
  766. gridSizer.Add(item = ptfill, pos = (2, 1))
  767. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Legend"))
  768. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (3, 0))
  769. ptlegend = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (200,-1))
  770. ptlegend.SetValue(self.properties['marker']['legend'])
  771. self.wxId['marker']['legend'] = ptlegend.GetId()
  772. gridSizer.Add(item = ptlegend, pos = (3, 1))
  773. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Style"))
  774. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (4, 0))
  775. pttype = wx.Choice(parent = self, size = (200, -1), choices = self.pttypelist)
  776. pttype.SetStringSelection(self.properties['marker']['type'])
  777. self.wxId['marker']['type'] = pttype.GetId()
  778. gridSizer.Add(item = pttype, pos = (4, 1))
  779. boxSizer.Add(item = gridSizer)
  780. boxMainSizer.Add(item = boxSizer, flag = wx.ALL, border = 3)
  781. #
  782. # point options for scatterplots
  783. #
  784. elif self.plottype == 'scatter':
  785. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  786. label = " %s " % _("Scatterplot points"))
  787. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  788. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  789. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Color"))
  790. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  791. ptcolor = csel.ColourSelect(parent = self, id = wx.ID_ANY, colour = self.raster[self.map]['pcolor'])
  792. self.wxId['pcolor'] = ptcolor.GetId()
  793. gridSizer.Add(item = ptcolor, pos = (0, 1))
  794. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Size"))
  795. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  796. ptsize = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "",
  797. size = (50, -1), style = wx.SP_ARROW_KEYS)
  798. ptsize.SetRange(1, 10)
  799. ptsize.SetValue(self.raster[self.map]['psize'])
  800. self.wxId['psize'] = ptsize.GetId()
  801. gridSizer.Add(item = ptsize, pos = (1, 1))
  802. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Fill"))
  803. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  804. ptfill = wx.Choice(parent = self, id = wx.ID_ANY,
  805. size = (120, -1), choices = self.ptfilldict.keys())
  806. ptfill.SetStringSelection(self.raster[self.map]['pfill'])
  807. self.wxId['pfill'] = ptfill.GetId()
  808. gridSizer.Add(item = ptfill, pos = (2, 1))
  809. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Legend"))
  810. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (3, 0))
  811. ptlegend = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (200,-1))
  812. ptlegend.SetValue(self.raster[self.map]['plegend'])
  813. self.wxId['plegend'] = ptlegend.GetId()
  814. gridSizer.Add(item = ptlegend, pos = (3, 1))
  815. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Style"))
  816. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (4, 0))
  817. pttype = wx.Choice(parent = self, size = (200, -1), choices = self.pttypelist)
  818. pttype.SetStringSelection(self.raster[self.map]['ptype'])
  819. self.wxId['ptype'] = pttype.GetId()
  820. gridSizer.Add(item = pttype, pos = (4, 1))
  821. boxSizer.Add(item = gridSizer)
  822. boxMainSizer.Add(item = boxSizer, flag = wx.ALL, border = 3)
  823. sizer.Add(item = boxMainSizer, flag = wx.ALL | wx.EXPAND, border = 3)
  824. #
  825. # axis options for all plots
  826. #
  827. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  828. label = " %s " % _("Axis settings"))
  829. boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  830. middleSizer = wx.BoxSizer(wx.HORIZONTAL)
  831. idx = 0
  832. for axis, atype in [(_("X-Axis"), 'x-axis'),
  833. (_("Y-Axis"), 'y-axis')]:
  834. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  835. label = " %s " % axis)
  836. boxSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  837. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  838. prop = self.properties[atype]['prop']
  839. row = 0
  840. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Scale"))
  841. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  842. type = wx.Choice(parent = self, id = wx.ID_ANY, size = (100, -1), choices = self.axislist)
  843. type.SetStringSelection(prop['type'])
  844. type.SetToolTipString(_("Automatic axis scaling, custom max and min, or scale matches data range (min)" ))
  845. self.wxId[atype]['type'] = type.GetId()
  846. gridSizer.Add(item = type, pos = (row, 1))
  847. row += 1
  848. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Custom min"))
  849. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  850. min = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (70, -1))
  851. min.SetValue(str(prop['min']))
  852. self.wxId[atype]['min'] = min.GetId()
  853. gridSizer.Add(item = min, pos = (row, 1))
  854. row += 1
  855. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Custom max"))
  856. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  857. max = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (70, -1))
  858. max.SetValue(str(prop['max']))
  859. self.wxId[atype]['max'] = max.GetId()
  860. gridSizer.Add(item = max, pos = (row, 1))
  861. row += 1
  862. log = wx.CheckBox(parent = self, id = wx.ID_ANY, label = _("Log scale"))
  863. log.SetValue(prop['log'])
  864. self.wxId[atype]['log'] = log.GetId()
  865. gridSizer.Add(item = log, pos = (row, 0), span = (1, 2))
  866. if idx == 0:
  867. flag = wx.ALL | wx.EXPAND
  868. else:
  869. flag = wx.TOP | wx.BOTTOM | wx.RIGHT | wx.EXPAND
  870. boxSizer.Add(item = gridSizer, flag = wx.ALL, border = 3)
  871. boxMainSizer.Add(item = boxSizer, flag = flag, border = 3)
  872. idx += 1
  873. middleSizer.Add(item = boxMainSizer, flag = wx.ALL | wx.EXPAND, border = 3)
  874. #
  875. # grid & legend options for all plots
  876. #
  877. self.wxId['grid'] = {}
  878. self.wxId['legend'] = {}
  879. self.wxId['font'] = {}
  880. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  881. label = " %s " % _("Grid and Legend settings"))
  882. boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  883. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  884. row = 0
  885. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Grid color"))
  886. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  887. gridcolor = csel.ColourSelect(parent = self, id = wx.ID_ANY, colour = self.properties['grid']['color'])
  888. self.wxId['grid']['color'] = gridcolor.GetId()
  889. gridSizer.Add(item = gridcolor, pos = (row, 1))
  890. row +=1
  891. gridshow = wx.CheckBox(parent = self, id = wx.ID_ANY, label = _("Show grid"))
  892. gridshow.SetValue(self.properties['grid']['enabled'])
  893. self.wxId['grid']['enabled'] = gridshow.GetId()
  894. gridSizer.Add(item = gridshow, pos = (row, 0), span = (1, 2))
  895. row +=1
  896. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Legend font size"))
  897. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  898. legendfontsize = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "",
  899. size = (50, -1), style = wx.SP_ARROW_KEYS)
  900. legendfontsize.SetRange(5,100)
  901. legendfontsize.SetValue(int(self.properties['font']['prop']['legendSize']))
  902. self.wxId['font']['legendSize'] = legendfontsize.GetId()
  903. gridSizer.Add(item = legendfontsize, pos = (row, 1))
  904. row += 1
  905. legendshow = wx.CheckBox(parent = self, id = wx.ID_ANY, label = _("Show legend"))
  906. legendshow.SetValue(self.properties['legend']['enabled'])
  907. self.wxId['legend']['enabled'] = legendshow.GetId()
  908. gridSizer.Add(item = legendshow, pos = (row, 0), span = (1, 2))
  909. boxMainSizer.Add(item = gridSizer, flag = flag, border = 3)
  910. middleSizer.Add(item = boxMainSizer, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
  911. sizer.Add(item = middleSizer, flag = wx.ALL, border = 0)
  912. #
  913. # line & buttons
  914. #
  915. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  916. sizer.Add(item = line, proportion = 0,
  917. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 3)
  918. #
  919. # buttons
  920. #
  921. btnSave = wx.Button(self, wx.ID_SAVE)
  922. btnApply = wx.Button(self, wx.ID_APPLY)
  923. btnOk = wx.Button(self, wx.ID_OK)
  924. btnCancel = wx.Button(self, wx.ID_CANCEL)
  925. btnOk.SetDefault()
  926. # tooltips for buttons
  927. btnApply.SetToolTipString(_("Apply changes for the current session"))
  928. btnOk.SetToolTipString(_("Apply changes for the current session and close dialog"))
  929. btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
  930. btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
  931. # sizers
  932. btnStdSizer = wx.StdDialogButtonSizer()
  933. btnStdSizer.AddButton(btnOk)
  934. btnStdSizer.AddButton(btnApply)
  935. btnStdSizer.AddButton(btnCancel)
  936. btnStdSizer.Realize()
  937. btnSizer = wx.BoxSizer(wx.HORIZONTAL)
  938. btnSizer.Add(item = btnSave, proportion = 0, flag = wx.ALIGN_LEFT | wx.ALL, border = 5)
  939. btnSizer.Add(item = btnStdSizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  940. sizer.Add(item = btnSizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  941. #
  942. # bindings for buttons and map plot settings controls
  943. #
  944. self.mapchoice.Bind(wx.EVT_CHOICE, self.OnSetMap)
  945. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  946. btnOk.Bind(wx.EVT_BUTTON, self.OnOk)
  947. btnOk.SetDefault()
  948. btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
  949. btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  950. self.SetSizer(sizer)
  951. sizer.Fit(self)
  952. def OnSetMap(self, event):
  953. """!Handler for changing map selection"""
  954. idx = event.GetSelection()
  955. self.map = self.rasterList[idx]
  956. # update settings controls for all plots
  957. self.FindWindowById(self.wxId['pcolor']).SetColour(self.raster[self.map]['pcolor'])
  958. self.FindWindowById(self.wxId['plegend']).SetValue(self.raster[self.map]['plegend'])
  959. # update settings controls for histograms and profiles
  960. if self.plottype != 'scatter':
  961. self.FindWindowById(self.wxId['pwidth']).SetValue(self.raster[self.map]['pwidth'])
  962. self.FindWindowById(self.wxId['pstyle']).SetStringSelection(self.raster[self.map]['pstyle'])
  963. # update settings controls for scatterplots
  964. elif self.plottype == 'scatter':
  965. self.FindWindowById(self.wxId['psize']).SetValue(self.raster[self.map]['psize'])
  966. self.FindWindowById(self.wxId['ptype']).SetStringSelection(self.raster[self.map]['ptype'])
  967. self.FindWindowById(self.wxId['pfill']).SetStringSelection(self.raster[self.map]['pfill'])
  968. self.Refresh()
  969. def OnSetOpt(self, event):
  970. """!Handler for changing any other option"""
  971. self.map = self.rasterList[self.mapchoice.GetCurrentSelection()]
  972. self.UpdateSettings()
  973. self.parent.SetGraphStyle()
  974. p = self.parent.CreatePlotList()
  975. self.parent.DrawPlot(p)
  976. def UpdateSettings(self):
  977. """!Apply settings to each map and to entire plot"""
  978. self.raster[self.map]['pcolor'] = self.FindWindowById(self.wxId['pcolor']).GetColour()
  979. self.properties['raster']['pcolor'] = self.raster[self.map]['pcolor']
  980. self.raster[self.map]['plegend'] = self.FindWindowById(self.wxId['plegend']).GetValue()
  981. if self.plottype != 'scatter':
  982. self.raster[self.map]['pwidth'] = int(self.FindWindowById(self.wxId['pwidth']).GetValue())
  983. self.properties['raster']['pwidth'] = self.raster[self.map]['pwidth']
  984. self.raster[self.map]['pstyle'] = self.FindWindowById(self.wxId['pstyle']).GetStringSelection()
  985. self.properties['raster']['pstyle'] = self.raster[self.map]['pstyle']
  986. elif self.plottype == 'scatter':
  987. self.raster[self.map]['psize'] = self.FindWindowById(self.wxId['psize']).GetValue()
  988. self.properties['raster']['psize'] = self.raster[self.map]['psize']
  989. self.raster[self.map]['ptype'] = self.FindWindowById(self.wxId['ptype']).GetStringSelection()
  990. self.properties['raster']['ptype'] = self.raster[self.map]['ptype']
  991. self.raster[self.map]['pfill'] = self.FindWindowById(self.wxId['pfill']).GetStringSelection()
  992. self.properties['raster']['pfill'] = self.raster[self.map]['pfill']
  993. # update settings for entire plot
  994. for axis in ('x-axis', 'y-axis'):
  995. self.properties[axis]['prop']['type'] = self.FindWindowById(self.wxId[axis]['type']).GetStringSelection()
  996. self.properties[axis]['prop']['min'] = float(self.FindWindowById(self.wxId[axis]['min']).GetValue())
  997. self.properties[axis]['prop']['max'] = float(self.FindWindowById(self.wxId[axis]['max']).GetValue())
  998. self.properties[axis]['prop']['log'] = self.FindWindowById(self.wxId[axis]['log']).IsChecked()
  999. if self.plottype == 'profile':
  1000. self.properties['marker']['color'] = self.FindWindowById(self.wxId['marker']['color']).GetColour()
  1001. self.properties['marker']['fill'] = self.FindWindowById(self.wxId['marker']['fill']).GetStringSelection()
  1002. self.properties['marker']['size'] = self.FindWindowById(self.wxId['marker']['size']).GetValue()
  1003. self.properties['marker']['type'] = self.FindWindowById(self.wxId['marker']['type']).GetStringSelection()
  1004. self.properties['marker']['legend'] = self.FindWindowById(self.wxId['marker']['legend']).GetValue()
  1005. self.properties['grid']['color'] = self.FindWindowById(self.wxId['grid']['color']).GetColour()
  1006. self.properties['grid']['enabled'] = self.FindWindowById(self.wxId['grid']['enabled']).IsChecked()
  1007. # this makes more sense in the text properties, including for settings update. But will need to change
  1008. # layout for controls to text dialog too.
  1009. self.properties['font']['prop']['legendSize'] = self.FindWindowById(self.wxId['font']['legendSize']).GetValue()
  1010. self.properties['legend']['enabled'] = self.FindWindowById(self.wxId['legend']['enabled']).IsChecked()
  1011. def OnSave(self, event):
  1012. """!Button 'Save' pressed"""
  1013. self.OnApply(None)
  1014. fileSettings = {}
  1015. UserSettings.ReadSettingsFile(settings = fileSettings)
  1016. fileSettings[self.plottype] = UserSettings.Get(group = self.plottype)
  1017. UserSettings.SaveToFile(fileSettings)
  1018. self.parent.parent.GetLayerManager().GetLogWindow().WriteLog(_('Plot settings saved to file \'%s\'.') % UserSettings.filePath)
  1019. self.Close()
  1020. def OnApply(self, event):
  1021. """!Button 'Apply' pressed. Does not close dialog"""
  1022. self.UpdateSettings()
  1023. self.parent.SetGraphStyle()
  1024. p = self.parent.CreatePlotList()
  1025. self.parent.DrawPlot(p)
  1026. def OnOk(self, event):
  1027. """!Button 'OK' pressed"""
  1028. self.OnApply(None)
  1029. self.EndModal(wx.ID_OK)
  1030. def OnCancel(self, event):
  1031. """!Button 'Cancel' pressed"""
  1032. self.Close()