wxplot_dialogs.py 52 KB

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