dialogs.py 53 KB

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