dialogs.py 53 KB

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