123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847 |
- """
- @package iclass.dialogs
- @brief wxIClass dialogs
- Classes:
- - dialogs::IClassGroupDialog
- - dialogs::IClassMapDialog
- - dialogs::IClassCategoryManagerDialog
- - dialogs::CategoryListCtrl
- - dialogs::IClassSignatureFileDialog
- - dialogs::IClassExportAreasDialog
- (C) 2006-2011 by the GRASS Development Team
- This program is free software under the GNU General Public
- License (>=v2). Read the file COPYING that comes with GRASS
- for details.
- @author Vaclav Petras <wenzeslaus gmail.com>
- @author Anna Kratochvilova <kratochanna gmail.com>
- """
- import os
- import wx
- import wx.lib.mixins.listctrl as listmix
- import wx.lib.scrolledpanel as scrolled
- from core import globalvar
- from core.settings import UserSettings
- from core.gcmd import GError, RunCommand, GMessage
- from gui_core.dialogs import SimpleDialog, GroupDialog
- from gui_core import gselect
- from gui_core.widgets import SimpleValidator
- from gui_core.wrap import (
- CheckBox,
- Button,
- StaticText,
- StaticBox,
- TextCtrl,
- Menu,
- NewId,
- ListCtrl,
- )
- import grass.script as grass
- class IClassGroupDialog(SimpleDialog):
- """Dialog for imagery group selection"""
- def __init__(
- self,
- parent,
- group=None,
- subgroup=None,
- title=_("Select imagery group"),
- id=wx.ID_ANY,
- ):
- """
- Does post init and layout.
- :param parent: gui parent
- :param title: dialog window title
- :param id: wx id
- """
- SimpleDialog.__init__(self, parent, title)
- self.use_subg = True
- self.groupSelect = gselect.Select(
- parent=self.panel,
- type="group",
- mapsets=[grass.gisenv()["MAPSET"]],
- size=globalvar.DIALOG_GSELECT_SIZE,
- validator=SimpleValidator(callback=self.ValidatorCallback),
- )
- # TODO use when subgroup will be optional
- # self.subg_chbox = wx.CheckBox(parent = self.panel, id = wx.ID_ANY,
- # label = _("Use subgroup"))
- self.subGroupSelect = gselect.SubGroupSelect(parent=self.panel)
- self.groupSelect.SetFocus()
- if group:
- self.groupSelect.SetValue(group)
- self.GroupSelected()
- if subgroup:
- self.subGroupSelect.SetValue(subgroup)
- self.editGroup = Button(
- parent=self.panel, id=wx.ID_ANY, label=_("Create/edit group...")
- )
- self.editGroup.Bind(wx.EVT_BUTTON, self.OnEditGroup)
- self.groupSelect.GetTextCtrl().Bind(
- wx.EVT_TEXT, lambda event: wx.CallAfter(self.GroupSelected)
- )
- self.warning = _("Name of imagery group is missing.")
- self._layout()
- self.SetMinSize(self.GetSize())
- def _layout(self):
- """Do layout"""
- self.dataSizer.Add(
- StaticText(self.panel, id=wx.ID_ANY, label=_("Name of imagery group:")),
- proportion=0,
- flag=wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT,
- border=5,
- )
- self.dataSizer.Add(
- self.groupSelect, proportion=0, flag=wx.EXPAND | wx.ALL, border=5
- )
- # TODO use when subgroup will be optional
- # self.dataSizer.Add(self.subg_chbox, proportion = 0,
- # flag = wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT, border = 5)
- self.dataSizer.Add(
- StaticText(self.panel, id=wx.ID_ANY, label=_("Name of imagery subgroup:")),
- proportion=0,
- flag=wx.EXPAND | wx.EXPAND | wx.BOTTOM | wx.LEFT | wx.RIGHT,
- border=5,
- )
- self.dataSizer.Add(
- self.subGroupSelect, proportion=0, flag=wx.EXPAND | wx.ALL, border=5
- )
- self.dataSizer.Add(self.editGroup, proportion=0, flag=wx.ALL, border=5)
- self.panel.SetSizer(self.sizer)
- self.sizer.Fit(self)
- # TODO use when subgroup will be optional
- # self.subg_panel.Show(False)
- # self.subg_chbox.Bind(wx.EVT_CHECKBOX, self.OnSubgChbox)
- def OnSubgChbox(self, event):
- self.use_subg = self.subg_chbox.GetValue()
- if self.use_subg:
- self.subg_panel.Show()
- # self.SubGroupSelected()
- else:
- self.subg_panel.Hide()
- # self.GroupSelected()
- self.SetMinSize(self.GetBestSize())
- self.Layout()
- def GetData(self):
- """Returns selected group and subgroup"""
- if self.use_subg:
- ret = (self.groupSelect.GetValue(), self.subGroupSelect.GetValue())
- else:
- ret = (self.groupSelect.GetValue(), None)
- return ret
- def OnEditGroup(self, event):
- """Launch edit group dialog"""
- g, s = self.GetData()
- dlg = GroupDialog(parent=self, defaultGroup=g, defaultSubgroup=s)
- dlg.ShowModal()
- gr, s = dlg.GetSelectedGroup()
- if gr in dlg.GetExistGroups():
- self.groupSelect.SetValue(gr)
- self.GroupSelected()
- wx.CallAfter(self.subGroupSelect.SetValue, s)
- dlg.Destroy()
- def GroupSelected(self):
- group = self.GetSelectedGroup()
- self.subGroupSelect.Insert(group)
- def GetSelectedGroup(self):
- """Return currently selected group (without mapset)"""
- return self.groupSelect.GetValue().split("@")[0]
- def GetGroupBandsErr(self, parent):
- """Get list of raster bands which are in the soubgroup of group with both having same name.
- If the group does not exists or it does not contain any bands in subgoup with same name,
- error dialog is shown.
- """
- gr, s = self.GetData()
- group = grass.find_file(name=gr, element="group")
- bands = []
- g = group["name"]
- if g:
- if self.use_subg:
- if s == "":
- GError(_("Please choose a subgroup."), parent=parent)
- return bands
- if s not in self.GetSubgroups(g):
- GError(
- _("Subgroup <%s> not found in group <%s>") % (s, g),
- parent=parent,
- )
- return bands
- bands = self.GetGroupBands(g, s)
- if not bands:
- if self.use_subg:
- GError(
- _("No data found in subgroup <%s> of group <%s>.\n" ".")
- % (s, g),
- parent=parent,
- )
- else:
- GError(_("No data found in group <%s>.\n" ".") % g, parent=parent)
- else:
- GError(_("Group <%s> not found") % gr, parent=parent)
- return bands
- def GetGroupBands(self, group, subgroup):
- """Get list of raster bands which are in the soubgroup of group with both having same name."""
- kwargs = {}
- if subgroup:
- kwargs["subgroup"] = subgroup
- res = RunCommand("i.group", flags="g", group=group, read=True, **kwargs).strip()
- bands = None
- if res.split("\n")[0]:
- bands = res.split("\n")
- return bands
- def GetSubgroups(self, group):
- return RunCommand("i.group", group=group, read=True, flags="sg").splitlines()
- class IClassMapDialog(SimpleDialog):
- """Dialog for adding raster/vector map"""
- def __init__(self, parent, title, element):
- """
- :param parent: gui parent
- :param title: dialog title
- :param element: element type ('raster', 'vector')
- """
- SimpleDialog.__init__(self, parent, title=title)
- self.elementType = element
- self.element = gselect.Select(
- parent=self.panel,
- type=element,
- size=globalvar.DIALOG_GSELECT_SIZE,
- validator=SimpleValidator(callback=self.ValidatorCallback),
- )
- self.element.SetFocus()
- self.warning = _("Name of map is missing.")
- self._layout()
- self.SetMinSize(self.GetSize())
- def _layout(self):
- """Do layout"""
- if self.elementType == "raster":
- label = _("Name of raster map:")
- elif self.elementType == "vector":
- label = _("Name of vector map:")
- self.dataSizer.Add(
- StaticText(self.panel, id=wx.ID_ANY, label=label),
- proportion=0,
- flag=wx.EXPAND | wx.ALL,
- border=5,
- )
- self.dataSizer.Add(
- self.element, proportion=0, flag=wx.EXPAND | wx.ALL, border=5
- )
- self.panel.SetSizer(self.sizer)
- self.sizer.Fit(self)
- def GetMap(self):
- """Returns selected raster/vector map"""
- return self.element.GetValue()
- class IClassCategoryManagerDialog(wx.Dialog):
- """Dialog for managing categories (classes).
- Alows adding, deleting class and changing its name and color.
- """
- def __init__(self, parent, title=_("Class manager"), id=wx.ID_ANY):
- """
- Does post init and layout.
- :param parent: gui parent
- :param title: dialog window title
- :param id: wx id
- """
- wx.Dialog.__init__(self, parent=parent, title=title, id=id)
- self.parent = parent
- panel = wx.Panel(parent=self, id=wx.ID_ANY)
- mainSizer = wx.BoxSizer(wx.VERTICAL)
- box = StaticBox(panel, id=wx.ID_ANY, label=" %s " % _("Classes"))
- sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
- gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
- self.catList = CategoryListCtrl(
- panel, mapwindow=parent, stats_data=parent.stats_data
- )
- addButton = Button(panel, id=wx.ID_ADD)
- deleteButton = Button(panel, id=wx.ID_DELETE)
- gridSizer.Add(self.catList, pos=(0, 0), span=(3, 1), flag=wx.EXPAND)
- gridSizer.Add(addButton, pos=(0, 1), flag=wx.EXPAND)
- gridSizer.Add(deleteButton, pos=(1, 1), flag=wx.EXPAND)
- gridSizer.AddGrowableCol(0)
- gridSizer.AddGrowableRow(2)
- sizer.Add(gridSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
- mainSizer.Add(sizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
- btnSizer = wx.BoxSizer(wx.HORIZONTAL)
- closeButton = Button(panel, id=wx.ID_CLOSE)
- btnSizer.Add(wx.Size(-1, -1), proportion=1, flag=wx.EXPAND)
- btnSizer.Add(closeButton, proportion=0)
- mainSizer.Add(btnSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
- addButton.Bind(wx.EVT_BUTTON, self.OnAddCategory)
- deleteButton.Bind(wx.EVT_BUTTON, self.OnDeleteCategory)
- closeButton.Bind(wx.EVT_BUTTON, self.OnClose)
- self.Bind(wx.EVT_CLOSE, self.OnClose)
- panel.SetSizer(mainSizer)
- mainSizer.Fit(self)
- self.SetSize((400, 250))
- self.Layout()
- def OnAddCategory(self, event):
- if self.parent.stats_data.GetCategories():
- cat = max(self.parent.stats_data.GetCategories()) + 1
- else:
- cat = 1
- # intentionally not translatable
- defaultName = "class" + "_" + str(cat)
- defaultColor = "0:0:0"
- self.catList.AddCategory(cat=cat, name=defaultName, color=defaultColor)
- def OnDeleteCategory(self, event):
- self.catList.DeleteCategory()
- def OnClose(self, event):
- self.catList.DeselectAll()
- self.Hide()
- # if not isinstance(event, wx.CloseEvent):
- # self.Destroy()
- # event.Skip()
- def GetListCtrl(self):
- """Returns list widget"""
- return self.catList
- class CategoryListCtrl(ListCtrl, listmix.ListCtrlAutoWidthMixin, listmix.TextEditMixin):
- """Widget for controlling list of classes (categories).
- CategoryListCtrl updates choice in mapwindow and removes raster map
- when deleting class (category).
- It uses virtual data in the terms of @c wx.ListCtrl.
- .. todo::
- delete vector features after deleting class
- """
- def __init__(self, parent, mapwindow, stats_data, id=wx.ID_ANY):
- """
- :param parent: gui parent
- :param mapwindow: mapwindow instance with iclass toolbar and remove raster method
- :param stats_data: StatisticsData instance (defined in statistics.py)
- :param id: wx id
- """
- ListCtrl.__init__(
- self,
- parent,
- id,
- style=wx.LC_REPORT | wx.LC_VIRTUAL | wx.LC_HRULES | wx.LC_VRULES,
- )
- self.columns = ((_("Class name"), "name"), (_("Color"), "color"))
- self.Populate(columns=self.columns)
- self.mapWindow = mapwindow
- self.stats_data = stats_data
- self.SetItemCount(len(self.stats_data.GetCategories()))
- self.rightClickedItemIdx = wx.NOT_FOUND
- listmix.ListCtrlAutoWidthMixin.__init__(self)
- listmix.TextEditMixin.__init__(self)
- self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnEdit)
- self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnCategorySelected)
- self.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnClassRightUp) # wxMSW
- self.Bind(wx.EVT_RIGHT_UP, self.OnClassRightUp) # wxGTK
- self.stats_data.statisticsAdded.connect(self.Update)
- self.stats_data.statisticsDeleted.connect(self.Update)
- self.stats_data.allStatisticsDeleted.connect(self.Update)
- self.stats_data.statisticsSet.connect(self.Update)
- def Update(self):
- self.SetItemCount(len(self.stats_data.GetCategories()))
- def SetVirtualData(self, row, column, text):
- attr = self.columns[column][1]
- if attr == "name":
- try:
- text.encode("ascii")
- except UnicodeEncodeError:
- GMessage(parent=self, message=_("Please use only ASCII characters."))
- return
- cat = self.stats_data.GetCategories()[row]
- self.stats_data.GetStatistics(cat).SetStatistics(stats={attr: text})
- toolbar = self.mapWindow.toolbars["iClass"]
- toolbar.choice.SetSelection(row)
- self.Select(row)
- if attr == "name":
- self.mapWindow.UpdateRasterName(text, toolbar.GetSelectedCategoryIdx())
- self.mapWindow.UpdateChangeState(changes=True)
- def Populate(self, columns):
- for i, col in enumerate(columns):
- self.InsertColumn(i, col[0]) # wx.LIST_FORMAT_RIGHT
- self.SetColumnWidth(0, 100)
- self.SetColumnWidth(1, 100)
- def AddCategory(self, cat, name, color):
- """Add category record (used when importing areas)"""
- self.stats_data.AddStatistics(cat, name, color)
- self.SetItemCount(len(self.stats_data.GetCategories()))
- self.mapWindow.UpdateChangeState(changes=True)
- def DeleteCategory(self):
- indexList = sorted(self.GetSelectedIndices(), reverse=True)
- del_cats = []
- cats = self.stats_data.GetCategories()
- for i in indexList:
- # remove temporary raster
- cat = cats[i]
- stat = self.stats_data.GetStatistics(cat)
- name = stat.rasterName
- self.mapWindow.RemoveTempRaster(name)
- del_cats.append(cat)
- self.stats_data.DeleteStatistics(cat)
- self.SetItemCount(len(self.stats_data.GetCategories()))
- self.mapWindow.UpdateChangeState(changes=True)
- self.mapWindow.DeleteAreas(cats=del_cats)
- def GetSelectedIndices(self, state=wx.LIST_STATE_SELECTED):
- indices = []
- lastFound = -1
- while True:
- index = self.GetNextItem(lastFound, wx.LIST_NEXT_ALL, state)
- if index == -1:
- break
- else:
- lastFound = index
- indices.append(index)
- return indices
- def OnEdit(self, event):
- currentItem = event.GetIndex()
- currentCol = event.GetColumn()
- if currentCol == 1:
- col = self.OnGetItemText(currentItem, currentCol)
- col = map(int, col.split(":"))
- col_data = wx.ColourData()
- col_data.SetColour(wx.Colour(*col))
- dlg = wx.ColourDialog(self, col_data)
- dlg.GetColourData().SetChooseFull(True)
- if dlg.ShowModal() == wx.ID_OK:
- color = dlg.GetColourData().GetColour().Get()
- color = ":".join(map(str, color))
- self.SetVirtualData(currentItem, currentCol, color)
- dlg.Destroy()
- wx.CallAfter(self.SetFocus)
- event.Skip()
- def OnCategorySelected(self, event):
- """Highlight selected areas"""
- indexList = self.GetSelectedIndices()
- sel_cats = []
- cats = self.stats_data.GetCategories()
- for i in indexList:
- sel_cats.append(cats[i])
- self.mapWindow.HighlightCategory(sel_cats)
- if event:
- event.Skip()
- def OnClassRightUp(self, event):
- """Show context menu on right click"""
- item, flags = self.HitTest((event.GetX(), event.GetY()))
- if item != wx.NOT_FOUND and flags & wx.LIST_HITTEST_ONITEM:
- self.rightClickedItemIdx = item
- if not hasattr(self, "popupZoomtoAreas"):
- self.popupZoomtoAreas = NewId()
- self.Bind(wx.EVT_MENU, self.OnZoomToAreasByCat, id=self.popupZoomtoAreas)
- # generate popup-menu
- menu = Menu()
- menu.Append(
- self.popupZoomtoAreas, _("Zoom to training areas of selected class")
- )
- self.PopupMenu(menu)
- menu.Destroy()
- def OnZoomToAreasByCat(self, event):
- """Zoom to areas of given category"""
- cat = self.stats_data.GetCategories()[self.rightClickedItemIdx]
- self.mapWindow.ZoomToAreasByCat(cat)
- def DeselectAll(self):
- """Deselect all items"""
- indexList = self.GetSelectedIndices()
- for i in indexList:
- self.Select(i, on=0)
- # no highlight
- self.OnCategorySelected(None)
- def OnGetItemText(self, item, col):
- cat = self.stats_data.GetCategories()[item]
- stat = self.stats_data.GetStatistics(cat)
- return getattr(stat, self.columns[col][1])
- def OnGetItemImage(self, item):
- return -1
- def OnGetItemAttr(self, item):
- """Set correct class color for a item"""
- back_c = wx.Colour(*map(int, self.OnGetItemText(item, 1).split(":")))
- text_c = wx.Colour(*ContrastColor(back_c))
- # if it is in scope of the method, gui falls, using self solved it
- self.l = wx.ListItemAttr()
- self.l.SetBackgroundColour(back_c)
- self.l.SetTextColour(text_c)
- return self.l
- def ContrastColor(color):
- """Decides which value shoud have text to be contrast with background color
- (bright bg -> black, dark bg -> white)
- .. todo::
- could be useful by other apps, consider moving it into gui_core
- """
- # gacek,
- # http://stackoverflow.com/questions/1855884/determine-font-color-based-on-background-color
- a = 1 - (0.299 * color[0] + 0.587 * color[1] + 0.114 * color[2]) / 255
- if a < 0.5:
- d = 0
- else:
- d = 255
- # maybe return just bool if text shoud be dark or bright
- return (d, d, d)
- class IClassSignatureFileDialog(wx.Dialog):
- def __init__(
- self,
- parent,
- file=None,
- title=_("Save signature file"),
- id=wx.ID_ANY,
- style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
- **kwargs,
- ):
- """Dialog for saving signature file
- :param parent: window
- :param file: signature file name
- :param title: window title
- """
- wx.Dialog.__init__(self, parent, id, title, style=style, **kwargs)
- self.fileName = file
- env = grass.gisenv()
- # inconsistent group and subgroup name
- # path:
- # grassdata/nc_spm_08/landsat/signatures/sig/sigFile
- self.baseFilePath = os.path.join(
- env["GISDBASE"], env["LOCATION_NAME"], env["MAPSET"], "signatures", "sig"
- )
- self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
- self.btnCancel = Button(parent=self.panel, id=wx.ID_CANCEL)
- self.btnOK = Button(parent=self.panel, id=wx.ID_OK)
- self.btnOK.SetDefault()
- self.btnOK.Enable(False)
- self.__layout()
- self.fileNameCtrl.Bind(wx.EVT_TEXT, self.OnTextChanged)
- self.OnTextChanged(None)
- def OnTextChanged(self, event):
- """Name for signature file given"""
- file = self.fileNameCtrl.GetValue()
- if len(file) > 0:
- self.btnOK.Enable(True)
- else:
- self.btnOK.Enable(False)
- path = os.path.join(self.baseFilePath, file)
- self.filePathText.SetLabel(path)
- bestSize = self.pathPanel.GetBestVirtualSize()
- self.pathPanel.SetVirtualSize(bestSize)
- self.pathPanel.Scroll(*bestSize)
- def __layout(self):
- """Do layout"""
- sizer = wx.BoxSizer(wx.VERTICAL)
- dataSizer = wx.BoxSizer(wx.VERTICAL)
- dataSizer.Add(
- StaticText(
- parent=self.panel,
- id=wx.ID_ANY,
- label=_("Enter name of signature file:"),
- ),
- proportion=0,
- flag=wx.ALL,
- border=3,
- )
- self.fileNameCtrl = TextCtrl(parent=self.panel, id=wx.ID_ANY, size=(400, -1))
- if self.fileName:
- self.fileNameCtrl.SetValue(self.fileName)
- dataSizer.Add(
- self.fileNameCtrl, proportion=0, flag=wx.ALL | wx.EXPAND, border=3
- )
- dataSizer.Add(
- StaticText(
- parent=self.panel, id=wx.ID_ANY, label=_("Signature file path:")
- ),
- proportion=0,
- flag=wx.ALL,
- border=3,
- )
- self.pathPanel = scrolled.ScrolledPanel(self.panel, size=(-1, 40))
- pathSizer = wx.BoxSizer()
- self.filePathText = StaticText(
- parent=self.pathPanel, id=wx.ID_ANY, label=self.baseFilePath
- )
- pathSizer.Add(
- self.filePathText, proportion=1, flag=wx.ALL | wx.EXPAND, border=1
- )
- self.pathPanel.SetupScrolling(scroll_x=True, scroll_y=False)
- self.pathPanel.SetSizer(pathSizer)
- dataSizer.Add(self.pathPanel, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
- # buttons
- btnSizer = wx.StdDialogButtonSizer()
- btnSizer.AddButton(self.btnCancel)
- btnSizer.AddButton(self.btnOK)
- btnSizer.Realize()
- sizer.Add(dataSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
- sizer.Add(btnSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
- self.panel.SetSizer(sizer)
- sizer.Fit(self)
- self.SetMinSize(self.GetSize())
- def GetFileName(self, fullPath=False):
- """Returns signature file name
- :param fullPath: return full path of sig. file
- """
- if fullPath:
- return os.path.join(self.baseFilePath, self.fileNameCtrl.GetValue())
- return self.fileNameCtrl.GetValue()
- class IClassExportAreasDialog(wx.Dialog):
- def __init__(
- self,
- parent,
- vectorName=None,
- title=_("Export training areas"),
- id=wx.ID_ANY,
- style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
- **kwargs,
- ):
- """Dialog for export of training areas to vector layer
- :param parent: window
- :param vectorName: name of vector layer for export
- :param title: window title
- """
- wx.Dialog.__init__(self, parent, id, title, style=style, **kwargs)
- self.vectorName = vectorName
- self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
- self.btnCancel = Button(parent=self.panel, id=wx.ID_CANCEL)
- self.btnOK = Button(parent=self.panel, id=wx.ID_OK)
- self.btnOK.SetDefault()
- self.btnOK.Enable(False)
- self.btnOK.Bind(wx.EVT_BUTTON, self.OnOK)
- self.__layout()
- self.vectorNameCtrl.Bind(wx.EVT_TEXT, self.OnTextChanged)
- self.OnTextChanged(None)
- wx.CallAfter(self.vectorNameCtrl.SetFocus)
- def OnTextChanged(self, event):
- """Name of new vector map given.
- Enable/diable OK button.
- """
- file = self.vectorNameCtrl.GetValue()
- if len(file) > 0:
- self.btnOK.Enable(True)
- else:
- self.btnOK.Enable(False)
- def __layout(self):
- """Do layout"""
- sizer = wx.BoxSizer(wx.VERTICAL)
- dataSizer = wx.BoxSizer(wx.VERTICAL)
- dataSizer.Add(
- StaticText(
- parent=self.panel,
- id=wx.ID_ANY,
- label=_("Enter name of new vector map:"),
- ),
- proportion=0,
- flag=wx.ALL,
- border=3,
- )
- self.vectorNameCtrl = gselect.Select(
- parent=self.panel,
- type="vector",
- mapsets=[grass.gisenv()["MAPSET"]],
- size=globalvar.DIALOG_GSELECT_SIZE,
- )
- if self.vectorName:
- self.vectorNameCtrl.SetValue(self.vectorName)
- dataSizer.Add(
- self.vectorNameCtrl, proportion=0, flag=wx.ALL | wx.EXPAND, border=3
- )
- self.withTableCtrl = CheckBox(
- parent=self.panel, id=wx.ID_ANY, label=_("Export attribute table")
- )
- self.withTableCtrl.SetValue(True)
- self.withTableCtrl.SetToolTip(
- _("Export attribute table containing" " computed statistical data")
- )
- dataSizer.Add(self.withTableCtrl, proportion=0, flag=wx.ALL, border=3)
- # buttons
- btnSizer = wx.StdDialogButtonSizer()
- btnSizer.AddButton(self.btnCancel)
- btnSizer.AddButton(self.btnOK)
- btnSizer.Realize()
- sizer.Add(dataSizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
- sizer.Add(btnSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
- self.panel.SetSizer(sizer)
- sizer.Fit(self)
- self.SetMinSize(self.GetSize())
- def GetVectorName(self):
- """Returns vector name"""
- return self.vectorNameCtrl.GetValue()
- def WithTable(self):
- """Returns true if attribute table should be exported too"""
- return self.withTableCtrl.IsChecked()
- def OnOK(self, event):
- """Checks if map exists and can be overwritten."""
- overwrite = UserSettings.Get(group="cmd", key="overwrite", subkey="enabled")
- vName = self.GetVectorName()
- res = grass.find_file(vName, element="vector")
- if res["fullname"] and overwrite is False:
- qdlg = wx.MessageDialog(
- parent=self,
- message=_(
- "Vector map <%s> already exists."
- " Do you want to overwrite it?" % vName
- ),
- caption=_("Vector <%s> exists" % vName),
- style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.CENTRE,
- )
- if qdlg.ShowModal() == wx.ID_YES:
- event.Skip()
- qdlg.Destroy()
- else:
- event.Skip()
|