wxplot_dialogs.py 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928
  1. """!
  2. @package wxplot_dialogs.py
  3. Iinteractive plotting using PyPlot (wx.lib.plot.py). Dialogs for
  4. different plotting routines.
  5. Classes:
  6. - ProfileRasterDialog
  7. - HistRasterDialog
  8. - TextDialog
  9. - OptDialog
  10. (C) 2011 by the GRASS Development Team
  11. This program is free software under the GNU General Public License
  12. (>=v2). Read the file COPYING that comes with GRASS for details.
  13. @author Michael Barton, Arizona State University
  14. """
  15. import os
  16. import sys
  17. import wx
  18. import wx.lib.colourselect as csel
  19. import globalvar
  20. import gcmd
  21. from gselect import Select
  22. from preferences import globalSettings as UserSettings
  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 map or imagery group to histogram"),
  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. # for now this is limited to 14 rasters (number of colors in colorList), but it could be increased
  71. rstring = event.GetString()
  72. rList = rstring.split(',')
  73. n = min(len(rList), len(self.colorList))
  74. self.rasterList = []
  75. for idx in range(0,n):
  76. self.rasterList.append(rList[idx])
  77. class HistRasterDialog(wx.Dialog):
  78. def __init__(self, parent, id = wx.ID_ANY,
  79. title = _("Select raster map or imagery group to histogram"),
  80. style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
  81. """!Dialog to select raster maps to histogram.
  82. """
  83. wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
  84. self.parent = parent
  85. self.rasterList = self.parent.rasterList
  86. self.group = self.parent.group
  87. self.bins = self.parent.bins
  88. self.histtype = self.parent.histtype
  89. self.maptype = self.parent.maptype
  90. self.spinbins = ''
  91. self._do_layout()
  92. def _do_layout(self):
  93. sizer = wx.BoxSizer(wx.VERTICAL)
  94. box = wx.GridBagSizer (hgap = 3, vgap = 3)
  95. #
  96. # select single raster or image group to histogram radio buttons
  97. #
  98. self.rasterRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("Histogram single raster"), style = wx.RB_GROUP)
  99. self.groupRadio = wx.RadioButton(self, id = wx.ID_ANY, label = " %s " % _("Histogram imagery group"))
  100. if self.maptype == 'raster':
  101. self.rasterRadio.SetValue(True)
  102. elif self.maptype == 'group':
  103. self.groupRadio.SetValue(True)
  104. box.Add(item = self.rasterRadio, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  105. box.Add(item = self.groupRadio, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 1))
  106. #
  107. # Select a raster to histogram
  108. #
  109. label = wx.StaticText(parent = self, id = wx.ID_ANY,
  110. label = _("Select raster map:"))
  111. box.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  112. self.rselection = Select(self, id = wx.ID_ANY,
  113. size = globalvar.DIALOG_GSELECT_SIZE,
  114. type = 'cell')
  115. if self.groupRadio.GetValue() == True:
  116. self.rselection.Disable()
  117. else:
  118. if len(self.rasterList) > 0: self.rselection.SetValue(self.rasterList[0])
  119. box.Add(item = self.rselection, pos = (1, 1))
  120. #
  121. # Select an image group to histogram
  122. #
  123. label = wx.StaticText(parent = self, id = wx.ID_ANY,
  124. label = _("Select image group:"))
  125. box.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  126. self.gselection = Select(self, id = wx.ID_ANY,
  127. size = globalvar.DIALOG_GSELECT_SIZE,
  128. type = 'group')
  129. if self.rasterRadio.GetValue() == True:
  130. self.gselection.Disable()
  131. else:
  132. if self.group != None: self.gselection.SetValue(self.group)
  133. box.Add(item = self.gselection, pos = (2, 1))
  134. #
  135. # Nsteps for FP maps and histogram type selection
  136. #
  137. label = wx.StaticText(parent = self, id = wx.ID_ANY,
  138. label = _("Number of bins (for FP maps)"))
  139. box.Add(item = label,
  140. flag = wx.ALIGN_CENTER_VERTICAL, pos = (3, 0))
  141. self.spinbins = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "", pos = (30, 50),
  142. size = (100,-1), style = wx.SP_ARROW_KEYS)
  143. self.spinbins.SetRange(1,1000)
  144. self.spinbins.SetValue(self.bins)
  145. box.Add(item = self.spinbins,
  146. flag = wx.ALIGN_CENTER_VERTICAL, pos = (3, 1))
  147. label = wx.StaticText(parent = self, id = wx.ID_ANY,
  148. label = _("Histogram type"))
  149. box.Add(item = label,
  150. flag = wx.ALIGN_CENTER_VERTICAL, pos = (4, 0))
  151. types = ['count', 'percent', 'area']
  152. histtype = wx.ComboBox(parent = self, id = wx.ID_ANY, size = (250, -1),
  153. choices = types, style = wx.CB_DROPDOWN)
  154. histtype.SetStringSelection(self.histtype)
  155. box.Add(item = histtype,
  156. flag = wx.ALIGN_CENTER_VERTICAL, pos = (4, 1))
  157. sizer.Add(item = box, proportion = 0,
  158. flag = wx.ALL, border = 10)
  159. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  160. sizer.Add(item = line, proportion = 0,
  161. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 5)
  162. btnsizer = wx.StdDialogButtonSizer()
  163. btn = wx.Button(self, wx.ID_OK)
  164. btn.SetDefault()
  165. btnsizer.AddButton(btn)
  166. btn = wx.Button(self, wx.ID_CANCEL)
  167. btnsizer.AddButton(btn)
  168. btnsizer.Realize()
  169. sizer.Add(item = btnsizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  170. #
  171. # bindings
  172. #
  173. self.Bind(wx.EVT_RADIOBUTTON, self.OnHistMap, self.rasterRadio)
  174. self.Bind(wx.EVT_RADIOBUTTON, self.OnHistMap, self.groupRadio)
  175. self.rselection.Bind(wx.EVT_TEXT, self.OnRasterSelection)
  176. self.gselection.Bind(wx.EVT_TEXT, self.OnGroupSelection)
  177. self.spinbins.Bind(wx.EVT_TEXT, self.OnSetBins)
  178. self.spinbins.Bind(wx.EVT_SPINCTRL, self.OnSetBins)
  179. histtype.Bind(wx.EVT_TEXT, self.OnSetHisttypes)
  180. self.SetSizer(sizer)
  181. sizer.Fit(self)
  182. def OnHistMap(self, event):
  183. """!Hander for radio buttons to choose between histogramming a
  184. single raster and an imagery group
  185. """
  186. if self.rasterRadio.GetValue() == True:
  187. self.maptype = 'raster'
  188. self.rselection.Enable()
  189. self.gselection.Disable()
  190. self.gselection.SetValue('')
  191. elif self.groupRadio.GetValue() == True:
  192. self.maptype = 'group'
  193. self.gselection.Enable()
  194. self.rselection.Disable()
  195. self.rselection.SetValue('')
  196. else:
  197. pass
  198. def OnRasterSelection(self, event):
  199. """!Handler for selecting a single raster map
  200. """
  201. self.rasterList = []
  202. self.rasterList.append(event.GetString())
  203. def OnGroupSelection(self, event):
  204. """!Handler for selecting imagery group
  205. """
  206. self.rasterList = []
  207. self.group = event.GetString()
  208. ret = grass.read_command('i.group',
  209. group = '%s' % self.group,
  210. quiet = True,
  211. flags = 'g').strip().split('\n')
  212. if ret != None and ret != '':
  213. self.rasterList = ret
  214. def OnSetBins(self, event):
  215. """!Bins for histogramming FP maps (=nsteps in r.stats)
  216. """
  217. self.bins = self.spinbins.GetValue()
  218. def OnSetHisttypes(self, event):
  219. self.histtype = event.GetString()
  220. class TextDialog(wx.Dialog):
  221. def __init__(self, parent, id, title, plottype = '',
  222. style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
  223. """!Dialog to set histogram text options: font, title
  224. and font size, axis labels and font size
  225. """
  226. wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
  227. #
  228. # initialize variables
  229. #
  230. # combo box entry lists
  231. self.ffamilydict = { 'default' : wx.FONTFAMILY_DEFAULT,
  232. 'decorative' : wx.FONTFAMILY_DECORATIVE,
  233. 'roman' : wx.FONTFAMILY_ROMAN,
  234. 'script' : wx.FONTFAMILY_SCRIPT,
  235. 'swiss' : wx.FONTFAMILY_SWISS,
  236. 'modern' : wx.FONTFAMILY_MODERN,
  237. 'teletype' : wx.FONTFAMILY_TELETYPE }
  238. self.fstyledict = { 'normal' : wx.FONTSTYLE_NORMAL,
  239. 'slant' : wx.FONTSTYLE_SLANT,
  240. 'italic' : wx.FONTSTYLE_ITALIC }
  241. self.fwtdict = { 'normal' : wx.FONTWEIGHT_NORMAL,
  242. 'light' : wx.FONTWEIGHT_LIGHT,
  243. 'bold' : wx.FONTWEIGHT_BOLD }
  244. self.parent = parent
  245. self.ptitle = self.parent.ptitle
  246. self.xlabel = self.parent.xlabel
  247. self.ylabel = self.parent.ylabel
  248. self.properties = self.parent.properties # read-only
  249. # font size
  250. self.fontfamily = self.properties['font']['wxfont'].GetFamily()
  251. self.fontstyle = self.properties['font']['wxfont'].GetStyle()
  252. self.fontweight = self.properties['font']['wxfont'].GetWeight()
  253. self._do_layout()
  254. def _do_layout(self):
  255. """!Do layout"""
  256. # dialog layout
  257. sizer = wx.BoxSizer(wx.VERTICAL)
  258. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  259. label = " %s " % _("Text settings"))
  260. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  261. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  262. #
  263. # profile title
  264. #
  265. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Profile title:"))
  266. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  267. self.ptitleentry = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (250,-1))
  268. # self.ptitleentry.SetFont(self.font)
  269. self.ptitleentry.SetValue(self.ptitle)
  270. gridSizer.Add(item = self.ptitleentry, pos = (0, 1))
  271. #
  272. # title font
  273. #
  274. tlabel = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Title font size (pts):"))
  275. gridSizer.Add(item = tlabel, flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  276. self.ptitlesize = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "", pos = (30, 50),
  277. size = (50,-1), style = wx.SP_ARROW_KEYS)
  278. self.ptitlesize.SetRange(5,100)
  279. self.ptitlesize.SetValue(int(self.properties['font']['prop']['titleSize']))
  280. gridSizer.Add(item = self.ptitlesize, pos = (1, 1))
  281. #
  282. # x-axis label
  283. #
  284. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("X-axis label:"))
  285. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  286. self.xlabelentry = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (250,-1))
  287. # self.xlabelentry.SetFont(self.font)
  288. self.xlabelentry.SetValue(self.xlabel)
  289. gridSizer.Add(item = self.xlabelentry, pos = (2, 1))
  290. #
  291. # y-axis label
  292. #
  293. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Y-axis label:"))
  294. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (3, 0))
  295. self.ylabelentry = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (250,-1))
  296. # self.ylabelentry.SetFont(self.font)
  297. self.ylabelentry.SetValue(self.ylabel)
  298. gridSizer.Add(item = self.ylabelentry, pos = (3, 1))
  299. #
  300. # font size
  301. #
  302. llabel = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Label font size (pts):"))
  303. gridSizer.Add(item = llabel, flag = wx.ALIGN_CENTER_VERTICAL, pos = (4, 0))
  304. self.axislabelsize = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "", pos = (30, 50),
  305. size = (50, -1), style = wx.SP_ARROW_KEYS)
  306. self.axislabelsize.SetRange(5, 100)
  307. self.axislabelsize.SetValue(int(self.properties['font']['prop']['axisSize']))
  308. gridSizer.Add(item = self.axislabelsize, pos = (4,1))
  309. boxSizer.Add(item = gridSizer)
  310. sizer.Add(item = boxSizer, flag = wx.ALL | wx.EXPAND, border = 3)
  311. #
  312. # font settings
  313. #
  314. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  315. label = " %s " % _("Font settings"))
  316. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  317. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  318. gridSizer.AddGrowableCol(1)
  319. #
  320. # font family
  321. #
  322. label1 = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Font family:"))
  323. gridSizer.Add(item = label1, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  324. self.ffamilycb = wx.ComboBox(parent = self, id = wx.ID_ANY, size = (250, -1),
  325. choices = self.ffamilydict.keys(), style = wx.CB_DROPDOWN)
  326. self.ffamilycb.SetStringSelection('swiss')
  327. for item in self.ffamilydict.items():
  328. if self.fontfamily == item[1]:
  329. self.ffamilycb.SetStringSelection(item[0])
  330. break
  331. gridSizer.Add(item = self.ffamilycb, pos = (0, 1), flag = wx.ALIGN_RIGHT)
  332. #
  333. # font style
  334. #
  335. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Style:"))
  336. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  337. self.fstylecb = wx.ComboBox(parent = self, id = wx.ID_ANY, size = (250, -1),
  338. choices = self.fstyledict.keys(), style = wx.CB_DROPDOWN)
  339. self.fstylecb.SetStringSelection('normal')
  340. for item in self.fstyledict.items():
  341. if self.fontstyle == item[1]:
  342. self.fstylecb.SetStringSelection(item[0])
  343. break
  344. gridSizer.Add(item = self.fstylecb, pos = (1, 1), flag = wx.ALIGN_RIGHT)
  345. #
  346. # font weight
  347. #
  348. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Weight:"))
  349. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  350. self.fwtcb = wx.ComboBox(parent = self, size = (250, -1),
  351. choices = self.fwtdict.keys(), style = wx.CB_DROPDOWN)
  352. self.fwtcb.SetStringSelection('normal')
  353. for item in self.fwtdict.items():
  354. if self.fontweight == item[1]:
  355. self.fwtcb.SetStringSelection(item[0])
  356. break
  357. gridSizer.Add(item = self.fwtcb, pos = (2, 1), flag = wx.ALIGN_RIGHT)
  358. boxSizer.Add(item = gridSizer, flag = wx.EXPAND)
  359. sizer.Add(item = boxSizer, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
  360. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  361. sizer.Add(item = line, proportion = 0,
  362. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 3)
  363. #
  364. # buttons
  365. #
  366. btnSave = wx.Button(self, wx.ID_SAVE)
  367. btnApply = wx.Button(self, wx.ID_APPLY)
  368. btnOk = wx.Button(self, wx.ID_OK)
  369. btnCancel = wx.Button(self, wx.ID_CANCEL)
  370. btnOk.SetDefault()
  371. # bindings
  372. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  373. btnApply.SetToolTipString(_("Apply changes for the current session"))
  374. btnOk.Bind(wx.EVT_BUTTON, self.OnOk)
  375. btnOk.SetToolTipString(_("Apply changes for the current session and close dialog"))
  376. btnOk.SetDefault()
  377. btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
  378. btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
  379. btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  380. btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
  381. # sizers
  382. btnStdSizer = wx.StdDialogButtonSizer()
  383. btnStdSizer.AddButton(btnOk)
  384. btnStdSizer.AddButton(btnApply)
  385. btnStdSizer.AddButton(btnCancel)
  386. btnStdSizer.Realize()
  387. btnSizer = wx.BoxSizer(wx.HORIZONTAL)
  388. btnSizer.Add(item = btnSave, proportion = 0, flag = wx.ALIGN_LEFT | wx.ALL, border = 5)
  389. btnSizer.Add(item = btnStdSizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  390. sizer.Add(item = btnSizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  391. #
  392. # bindings
  393. #
  394. self.ptitleentry.Bind(wx.EVT_TEXT, self.OnTitle)
  395. self.xlabelentry.Bind(wx.EVT_TEXT, self.OnXLabel)
  396. self.ylabelentry.Bind(wx.EVT_TEXT, self.OnYLabel)
  397. self.SetSizer(sizer)
  398. sizer.Fit(self)
  399. def OnTitle(self, event):
  400. self.ptitle = event.GetString()
  401. def OnXLabel(self, event):
  402. self.xlabel = event.GetString()
  403. def OnYLabel(self, event):
  404. self.ylabel = event.GetString()
  405. def UpdateSettings(self):
  406. self.properties['font']['prop']['titleSize'] = self.ptitlesize.GetValue()
  407. self.properties['font']['prop']['axisSize'] = self.axislabelsize.GetValue()
  408. family = self.ffamilydict[self.ffamilycb.GetStringSelection()]
  409. self.properties['font']['wxfont'].SetFamily(family)
  410. style = self.fstyledict[self.fstylecb.GetStringSelection()]
  411. self.properties['font']['wxfont'].SetStyle(style)
  412. weight = self.fwtdict[self.fwtcb.GetStringSelection()]
  413. self.properties['font']['wxfont'].SetWeight(weight)
  414. def OnSave(self, event):
  415. """!Button 'Save' pressed"""
  416. self.UpdateSettings()
  417. fileSettings = {}
  418. UserSettings.ReadSettingsFile(settings=fileSettings)
  419. fileSettings['plot'] = UserSettings.Get(group = 'plot')
  420. file = UserSettings.SaveToFile(fileSettings)
  421. self.parent.parent.GetLayerManager().goutput.WriteLog(_('Plot text settings saved to file \'%s\'.') % file)
  422. self.EndModal(wx.ID_OK)
  423. def OnApply(self, event):
  424. """!Button 'Apply' pressed"""
  425. self.UpdateSettings()
  426. self.parent.OnPlotText(self)
  427. def OnOk(self, event):
  428. """!Button 'OK' pressed"""
  429. self.UpdateSettings()
  430. self.EndModal(wx.ID_OK)
  431. def OnCancel(self, event):
  432. """!Button 'Cancel' pressed"""
  433. self.EndModal(wx.ID_CANCEL)
  434. class OptDialog(wx.Dialog):
  435. def __init__(self, parent, id, title, plottype = '',
  436. style = wx.DEFAULT_DIALOG_STYLE, **kwargs):
  437. """!Dialog to set various options for data plotted, including: line
  438. width, color, style; marker size, color, fill, and style; grid
  439. and legend options.
  440. """
  441. wx.Dialog.__init__(self, parent, id, title, style = style, **kwargs)
  442. # init variables
  443. self.parent = parent
  444. self.pstyledict = parent.pstyledict
  445. self.ptfilldict = parent.ptfilldict
  446. self.plottype = plottype
  447. self.pttypelist = ['circle',
  448. 'dot',
  449. 'square',
  450. 'triangle',
  451. 'triangle_down',
  452. 'cross',
  453. 'plus']
  454. self.axislist = ['min',
  455. 'auto',
  456. 'custom']
  457. # widgets ids
  458. self.wxId = {}
  459. self.parent = parent
  460. # read-only
  461. self.raster = self.parent.raster
  462. self.rasterList = self.parent.rasterList
  463. self.properties = self.parent.properties
  464. self.map = ''
  465. if len(self.rasterList) == 0:
  466. wx.MessageBox(parent = self,
  467. message = _("No map or image group selected to plot."),
  468. caption = _("Warning"), style = wx.OK | wx.ICON_ERROR)
  469. self._do_layout()
  470. def _do_layout(self):
  471. """!Do layout"""
  472. # dialog layout
  473. sizer = wx.BoxSizer(wx.VERTICAL)
  474. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  475. label = " %s " % _("Plot settings"))
  476. boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  477. self.wxId['pcolor'] = 0
  478. self.wxId['pwidth'] = 0
  479. self.wxId['pstyle'] = 0
  480. self.wxId['plegend'] = 0
  481. self.wxId['marker'] = {}
  482. self.wxId['x-axis'] = {}
  483. self.wxId['y-axis'] = {}
  484. #
  485. # plot line settings
  486. #
  487. if len(self.rasterList) > 0:
  488. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  489. label = _("Map/image plotted"))
  490. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  491. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  492. row = 0
  493. self.mapchoice = wx.Choice(parent = self, id = wx.ID_ANY, size = (300, -1),
  494. choices = self.rasterList)
  495. if not self.map:
  496. self.map = self.rasterList[self.mapchoice.GetCurrentSelection()]
  497. else:
  498. self.mapchoice.SetStringSelection(self.map)
  499. gridSizer.Add(item = self.mapchoice, flag = wx.ALIGN_CENTER_VERTICAL,
  500. pos = (row, 0), span = (1, 2))
  501. row +=1
  502. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Line color"))
  503. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  504. pcolor = csel.ColourSelect(parent = self, id = wx.ID_ANY, colour = self.raster[self.map]['pcolor'])
  505. self.wxId['pcolor'] = pcolor.GetId()
  506. gridSizer.Add(item = pcolor, pos = (row, 1))
  507. row += 1
  508. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Line width"))
  509. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  510. pwidth = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "",
  511. size = (50,-1), style = wx.SP_ARROW_KEYS)
  512. pwidth.SetRange(1, 10)
  513. pwidth.SetValue(self.raster[self.map]['pwidth'])
  514. self.wxId['pwidth'] = pwidth.GetId()
  515. gridSizer.Add(item = pwidth, pos = (row, 1))
  516. row +=1
  517. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Line style"))
  518. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  519. pstyle = wx.Choice(parent = self, id = wx.ID_ANY,
  520. size = (120, -1), choices = self.pstyledict.keys(), style = wx.CB_DROPDOWN)
  521. pstyle.SetStringSelection(self.raster[self.map]['pstyle'])
  522. self.wxId['pstyle'] = pstyle.GetId()
  523. gridSizer.Add(item = pstyle, pos = (row, 1))
  524. row += 1
  525. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Legend"))
  526. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  527. plegend = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (200,-1))
  528. plegend.SetValue(self.raster[self.map]['plegend'])
  529. gridSizer.Add(item = plegend, pos = (row, 1))
  530. self.wxId['plegend'] = plegend.GetId()
  531. boxSizer.Add(item = gridSizer)
  532. boxMainSizer.Add(item = boxSizer, flag = wx.ALL, border = 3)
  533. #
  534. # segment marker settings
  535. #
  536. if self.plottype != 'histogram':
  537. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  538. label = " %s " % _("Transect segment marker settings"))
  539. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  540. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  541. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Color"))
  542. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (0, 0))
  543. ptcolor = csel.ColourSelect(parent = self, id = wx.ID_ANY, colour = self.properties['marker']['color'])
  544. self.wxId['marker']['color'] = ptcolor.GetId()
  545. gridSizer.Add(item = ptcolor, pos = (0, 1))
  546. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Size"))
  547. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (1, 0))
  548. ptsize = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "",
  549. size = (50, -1), style = wx.SP_ARROW_KEYS)
  550. ptsize.SetRange(1, 10)
  551. ptsize.SetValue(self.properties['marker']['size'])
  552. self.wxId['marker']['size'] = ptsize.GetId()
  553. gridSizer.Add(item = ptsize, pos = (1, 1))
  554. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Style"))
  555. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (2, 0))
  556. ptfill = wx.ComboBox(parent = self, id = wx.ID_ANY,
  557. size = (120, -1), choices = self.ptfilldict.keys(), style = wx.CB_DROPDOWN)
  558. ptfill.SetStringSelection(self.properties['marker']['fill'])
  559. self.wxId['marker']['fill'] = ptfill.GetId()
  560. gridSizer.Add(item = ptfill, pos = (2, 1))
  561. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Legend"))
  562. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (3, 0))
  563. ptlegend = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (200,-1))
  564. ptlegend.SetValue(self.properties['marker']['legend'])
  565. self.wxId['marker']['legend'] = ptlegend.GetId()
  566. gridSizer.Add(item = ptlegend, pos = (3, 1))
  567. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Type"))
  568. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (4, 0))
  569. pttype = wx.ComboBox(parent = self,
  570. size = (200, -1), choices = self.pttypelist, style = wx.CB_DROPDOWN)
  571. pttype.SetStringSelection(self.properties['marker']['type'])
  572. self.wxId['marker']['type'] = pttype.GetId()
  573. gridSizer.Add(item = pttype, pos = (4, 1))
  574. boxSizer.Add(item = gridSizer)
  575. boxMainSizer.Add(item = boxSizer, flag = wx.ALL, border = 3)
  576. sizer.Add(item = boxMainSizer, flag = wx.ALL | wx.EXPAND, border = 3)
  577. #
  578. # axis options
  579. #
  580. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  581. label = " %s " % _("Axis settings"))
  582. boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  583. middleSizer = wx.BoxSizer(wx.HORIZONTAL)
  584. idx = 0
  585. for axis, atype in [(_("X-Axis"), 'x-axis'),
  586. (_("Y-Axis"), 'y-axis')]:
  587. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  588. label = " %s " % axis)
  589. boxSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  590. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  591. prop = self.properties[atype]['prop']
  592. row = 0
  593. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Style"))
  594. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  595. type = wx.Choice(parent = self, id = wx.ID_ANY,
  596. size = (100, -1), choices = self.axislist, style = wx.CB_DROPDOWN)
  597. type.SetStringSelection(prop['type'])
  598. self.wxId[atype]['type'] = type.GetId()
  599. gridSizer.Add(item = type, pos = (row, 1))
  600. row += 1
  601. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Custom min"))
  602. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  603. min = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (70, -1))
  604. min.SetValue(str(prop['min']))
  605. self.wxId[atype]['min'] = min.GetId()
  606. gridSizer.Add(item = min, pos = (row, 1))
  607. row += 1
  608. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Custom max"))
  609. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  610. max = wx.TextCtrl(parent = self, id = wx.ID_ANY, value = "", size = (70, -1))
  611. max.SetValue(str(prop['max']))
  612. self.wxId[atype]['max'] = max.GetId()
  613. gridSizer.Add(item = max, pos = (row, 1))
  614. row += 1
  615. log = wx.CheckBox(parent = self, id = wx.ID_ANY, label = _("Log scale"))
  616. log.SetValue(prop['log'])
  617. self.wxId[atype]['log'] = log.GetId()
  618. gridSizer.Add(item = log, pos = (row, 0), span = (1, 2))
  619. if idx == 0:
  620. flag = wx.ALL | wx.EXPAND
  621. else:
  622. flag = wx.TOP | wx.BOTTOM | wx.RIGHT | wx.EXPAND
  623. boxSizer.Add(item = gridSizer, flag = wx.ALL, border = 3)
  624. boxMainSizer.Add(item = boxSizer, flag = flag, border = 3)
  625. idx += 1
  626. middleSizer.Add(item = boxMainSizer, flag = wx.ALL | wx.EXPAND, border = 3)
  627. #
  628. # grid & legend options
  629. #
  630. self.wxId['grid'] = {}
  631. self.wxId['legend'] = {}
  632. self.wxId['font'] = {}
  633. box = wx.StaticBox(parent = self, id = wx.ID_ANY,
  634. label = " %s " % _("Grid and Legend settings"))
  635. boxMainSizer = wx.StaticBoxSizer(box, wx.HORIZONTAL)
  636. gridSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  637. row = 0
  638. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Grid color"))
  639. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  640. gridcolor = csel.ColourSelect(parent = self, id = wx.ID_ANY, colour = self.properties['grid']['color'])
  641. self.wxId['grid']['color'] = gridcolor.GetId()
  642. gridSizer.Add(item = gridcolor, pos = (row, 1))
  643. row +=1
  644. gridshow = wx.CheckBox(parent = self, id = wx.ID_ANY, label = _("Show grid"))
  645. gridshow.SetValue(self.properties['grid']['enabled'])
  646. self.wxId['grid']['enabled'] = gridshow.GetId()
  647. gridSizer.Add(item = gridshow, pos = (row, 0), span = (1, 2))
  648. row +=1
  649. label = wx.StaticText(parent = self, id = wx.ID_ANY, label = _("Legend font size"))
  650. gridSizer.Add(item = label, flag = wx.ALIGN_CENTER_VERTICAL, pos = (row, 0))
  651. legendfontsize = wx.SpinCtrl(parent = self, id = wx.ID_ANY, value = "",
  652. size = (50, -1), style = wx.SP_ARROW_KEYS)
  653. legendfontsize.SetRange(5,100)
  654. legendfontsize.SetValue(int(self.properties['font']['prop']['legendSize']))
  655. self.wxId['font']['legendSize'] = legendfontsize.GetId()
  656. gridSizer.Add(item = legendfontsize, pos = (row, 1))
  657. row += 1
  658. legendshow = wx.CheckBox(parent = self, id = wx.ID_ANY, label = _("Show legend"))
  659. legendshow.SetValue(self.properties['legend']['enabled'])
  660. self.wxId['legend']['enabled'] = legendshow.GetId()
  661. gridSizer.Add(item = legendshow, pos = (row, 0), span = (1, 2))
  662. boxMainSizer.Add(item = gridSizer, flag = flag, border = 3)
  663. middleSizer.Add(item = boxMainSizer, flag = wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border = 3)
  664. sizer.Add(item = middleSizer, flag = wx.ALL, border = 0)
  665. #
  666. # line & buttons
  667. #
  668. line = wx.StaticLine(parent = self, id = wx.ID_ANY, size = (20, -1), style = wx.LI_HORIZONTAL)
  669. sizer.Add(item = line, proportion = 0,
  670. flag = wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.RIGHT, border = 3)
  671. #
  672. # buttons
  673. #
  674. btnSave = wx.Button(self, wx.ID_SAVE)
  675. btnApply = wx.Button(self, wx.ID_APPLY)
  676. btnCancel = wx.Button(self, wx.ID_CANCEL)
  677. btnSave.SetDefault()
  678. # tooltips for buttons
  679. btnApply.SetToolTipString(_("Apply changes for the current session"))
  680. btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
  681. btnSave.SetDefault()
  682. btnCancel.SetToolTipString(_("Close dialog and ignore changes"))
  683. # sizers
  684. btnStdSizer = wx.StdDialogButtonSizer()
  685. btnStdSizer.AddButton(btnCancel)
  686. btnStdSizer.AddButton(btnSave)
  687. btnStdSizer.AddButton(btnApply)
  688. btnStdSizer.Realize()
  689. sizer.Add(item = btnStdSizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = 5)
  690. #
  691. # bindings for buttons and map plot settings controls
  692. #
  693. self.mapchoice.Bind(wx.EVT_CHOICE, self.OnSetMap)
  694. pcolor.Bind(csel.EVT_COLOURSELECT, self.OnSetOpt)
  695. pwidth.Bind(wx.EVT_SPINCTRL, self.OnSetOpt)
  696. pstyle.Bind(wx.EVT_CHOICE, self.OnSetOpt)
  697. plegend.Bind(wx.EVT_TEXT, self.OnSetOpt)
  698. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  699. btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
  700. btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
  701. self.SetSizer(sizer)
  702. sizer.Fit(self)
  703. def OnSetMap(self, event):
  704. """!Handler for changing map selection"""
  705. self.map = event.GetString()
  706. # update plot settings controls for selected map
  707. self.FindWindowById(self.wxId['pcolor']).SetColour(self.raster[self.map]['pcolor'])
  708. self.FindWindowById(self.wxId['pwidth']).SetValue(self.raster[self.map]['pwidth'])
  709. self.FindWindowById(self.wxId['pstyle']).SetStringSelection(self.raster[self.map]['pstyle'])
  710. self.FindWindowById(self.wxId['plegend']).SetValue(self.raster[self.map]['plegend'])
  711. self.Refresh()
  712. def OnSetOpt(self, event):
  713. """!Handler for changing any other option"""
  714. self.map = self.rasterList[self.mapchoice.GetCurrentSelection()]
  715. self.UpdateSettings()
  716. self.parent.SetGraphStyle()
  717. if self.parent.plot:
  718. p = self.parent.CreatPlotList()
  719. self.parent.DrawPlot(p)
  720. def UpdateSettings(self):
  721. """!Apply settings to each map and to entire plot"""
  722. # update plot settings for selected map
  723. self.raster[self.map]['pcolor'] = self.FindWindowById(self.wxId['pcolor']).GetColour()
  724. self.raster[self.map]['pwidth'] = int(self.FindWindowById(self.wxId['pwidth']).GetValue())
  725. self.raster[self.map]['pstyle'] = self.FindWindowById(self.wxId['pstyle']).GetStringSelection()
  726. self.raster[self.map]['plegend'] = self.FindWindowById(self.wxId['plegend']).GetValue()
  727. # update settings for entire plot
  728. for axis in ('x-axis', 'y-axis'):
  729. self.properties[axis]['prop']['type'] = self.FindWindowById(self.wxId[axis]['type']).GetStringSelection()
  730. self.properties[axis]['prop']['min'] = float(self.FindWindowById(self.wxId[axis]['min']).GetValue())
  731. self.properties[axis]['prop']['max'] = float(self.FindWindowById(self.wxId[axis]['max']).GetValue())
  732. self.properties[axis]['prop']['log'] = self.FindWindowById(self.wxId[axis]['log']).IsChecked()
  733. if self.plottype != 'histogram':
  734. self.properties['marker']['color'] = self.FindWindowById(self.wxId['marker']['color']).GetColour()
  735. self.properties['marker']['fill'] = self.FindWindowById(self.wxId['marker']['fill']).GetStringSelection()
  736. self.properties['marker']['size'] = self.FindWindowById(self.wxId['marker']['size']).GetValue()
  737. self.properties['marker']['type'] = self.FindWindowById(self.wxId['marker']['type']).GetValue()
  738. self.properties['marker']['legend'] = self.FindWindowById(self.wxId['marker']['legend']).GetValue()
  739. self.properties['grid']['color'] = self.FindWindowById(self.wxId['grid']['color']).GetColour()
  740. self.properties['grid']['enabled'] = self.FindWindowById(self.wxId['grid']['enabled']).IsChecked()
  741. self.properties['font']['prop']['legendSize'] = self.FindWindowById(self.wxId['font']['legendSize']).GetValue()
  742. self.properties['legend']['enabled'] = self.FindWindowById(self.wxId['legend']['enabled']).IsChecked()
  743. def OnSave(self, event):
  744. """!Button 'Save' pressed"""
  745. self.OnApply(None)
  746. fileSettings = {}
  747. UserSettings.ReadSettingsFile(settings = fileSettings)
  748. fileSettings[self.plottype] = UserSettings.Get(group = self.plottype)
  749. file = UserSettings.SaveToFile(fileSettings)
  750. self.parent.parent.GetLayerManager().goutput.WriteLog(_('Plot settings saved to file \'%s\'.') % file)
  751. self.Close()
  752. def OnApply(self, event):
  753. """!Button 'Apply' pressed. Does not close dialog"""
  754. self.UpdateSettings()
  755. self.parent.SetGraphStyle()
  756. if self.parent.plot:
  757. p = self.parent.CreatePlotList()
  758. self.parent.DrawPlot(p)
  759. def OnCancel(self, event):
  760. """!Button 'Cancel' pressed"""
  761. self.Close()
  762. #### merge with generic options dialog