[GRASS-dev] Size & (re)sizable Location Wizard dialog please
Anna Petrášová
kratochanna at gmail.com
Sat Mar 19 12:02:11 PDT 2016
On Sat, Mar 12, 2016 at 11:40 AM, Yann <yann.chemin at gmail.com> wrote:
> Hi,
>
> https://grasswiki.osgeo.org/wiki/File:Location_wizard_with_IAU_codes.png
>
> The text goes out of the box, most probably because of some settings in my
> PC.
> Is it possible to let the dialog box adapt to a larger size if needed, or
> being manually resizable.
>
> Could you try the attached diff? I am not really sure about the change.
Anna
> Thank you,
> Yann
>
> --
> -----
> Yann Chemin
> Address: 3 Toul Melin, 56400 Plumergat
> Mobile: +33 (0)7 83 85 52 34
>
> _______________________________________________
> grass-dev mailing list
> grass-dev at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/grass-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/grass-dev/attachments/20160319/9d8faab8/attachment-0001.html>
-------------- next part --------------
Index: datacatalog/catalog.py
===================================================================
--- datacatalog/catalog.py (revision 68055)
+++ datacatalog/catalog.py (working copy)
@@ -42,6 +42,8 @@
self.thread = gThread()
self._loaded = False
self.tree.showNotification.connect(self.showNotification)
+ self.reload_btn = wx.Button(self, label=_("Refresh"))
+ self.reload_btn.Bind(wx.EVT_BUTTON, self.OnReload)
# some layout
self._layout()
@@ -49,7 +51,10 @@
def _layout(self):
"""Do layout"""
sizer = wx.BoxSizer(wx.VERTICAL)
-
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
+ hsizer.AddStretchSpacer()
+ hsizer.Add(self.reload_btn, flag=wx.EXPAND)
+ sizer.Add(hsizer, flag=wx.EXPAND)
sizer.Add(item = self.tree.GetControl(), proportion = 1,
flag = wx.EXPAND)
@@ -68,3 +73,6 @@
def LoadItemsDone(self):
self._loaded = True
self.tree.ExpandCurrentMapset()
+
+ def OnReload(self, event):
+ self.tree.Reload()
Index: datacatalog/tree.py
===================================================================
--- datacatalog/tree.py (revision 68055)
+++ datacatalog/tree.py (working copy)
@@ -91,6 +91,65 @@
gscript.try_remove(tmp_gisrc_file)
+
+def map_exists(name, element, env, mapset=None):
+ """Check is map is present in the mapset given in the environment
+
+ :param name: name of the map
+ :param element: data type ('raster', 'raster_3d', and 'vector')
+ :param env environment created by function getEnvironment
+ """
+ if not mapset:
+ mapset = gscript.run_command('g.mapset', flags='p', env=env).strip()
+ # change type to element used by find file
+ if element == 'raster':
+ element = 'cell'
+ elif element == 'raster_3d':
+ element = 'grid3'
+ # g.findfile returns non-zero when file was not found
+ # se we ignore return code and just focus on stdout
+ process = gscript.start_command('g.findfile', flags='n',
+ element=element, file=name, mapset=mapset,
+ stdout=gscript.PIPE, stderr=gscript.PIPE, env=env)
+ output, errors = process.communicate()
+ info = gscript.parse_key_val(output, sep='=')
+ # file is the key questioned in grass.script.core find_file()
+ # return code should be equivalent to checking the output
+ if info['file']:
+ return True
+ else:
+ return False
+
+
+class NameEntryDialog(TextEntryDialog):
+ def __init__(self, element, mapset, env, **kwargs):
+ TextEntryDialog.__init__(self, **kwargs)
+ self._element = element
+ self._mapset = mapset
+ self._env = env
+ id_OK = self.GetAffirmativeId()
+ self.Bind(wx.EVT_BUTTON, self.OnOK, self.FindWindowById(id_OK))
+
+ def OnOK(self, event):
+ new = self.GetValue()
+ if not new:
+ return
+ if map_exists(new, self._element, self._env, self._mapset):
+ dlg = wx.MessageDialog(self, message=_("Map of type {elem} <{name}> already exists in mapset {mapset}. "
+ "Do you want to overwrite it?").format(elem=self._element,
+ name=new, mapset=self._mapset),
+ caption=_("Overwrite?"), style=wx.YES_NO)
+ if dlg.ShowModal() == wx.ID_YES:
+ dlg.Destroy()
+ self._env['GRASS_OVERWRITE'] = '1'
+ self.EndModal(wx.ID_OK)
+ else:
+ dlg.Destroy()
+ return
+ else:
+ self.EndModal(wx.ID_OK)
+
+
class DataCatalogNode(DictNode):
"""Node representing item in datacatalog."""
def __init__(self, label, data=None):
@@ -146,7 +205,7 @@
location_nodes = []
nlocations = len(locations)
grassdata_node = self._model.AppendNode(parent=self._model.root,
- label=_('GRASS locations ({})').format(self.gisdbase),
+ label=_('GRASS locations in {}').format(self.gisdbase),
data=dict(type='grassdata'))
for location in locations:
results[location] = dict()
@@ -209,6 +268,10 @@
"""Create popup menu for mapsets"""
raise NotImplementedError()
+ def _popupMenuElement(self):
+ """Create popup menu for elements"""
+ raise NotImplementedError()
+
def _initVariables(self):
"""Init variables."""
self.selected_layer = None
@@ -250,10 +313,10 @@
if type == 'location':
self.selected_location = item
-
+
def OnSelChanged(self, event):
self.selected_layer = None
-
+
def OnRightClick(self, node):
"""Display popup menu."""
self.DefineItems(node)
@@ -261,6 +324,8 @@
self._popupMenuLayer(self.selected_mapset.label == self.gmapset)
elif self.selected_mapset and not self.selected_type:
self._popupMenuMapset()
+ elif self.selected_type:
+ self._popupMenuElement()
def OnDoubleClick(self, node):
"""Expand/Collapse node."""
@@ -317,8 +382,8 @@
self._emitSignal(evt.GetItem(), self.startEdit, event=evt))
self.Bind(wx.EVT_TREE_END_LABEL_EDIT, lambda evt:
self._emitSignal(evt.GetItem(), self.endEdit, event=evt))
- ###self.startEdit.connect(self.OnStartEditLabel)
- ###self.endEdit.connect(self.OnEditLabel)
+ self.startEdit.connect(self.OnStartEditLabel)
+ self.endEdit.connect(self.OnEditLabel)
def _initVariablesCatalog(self):
"""Init variables."""
@@ -337,6 +402,11 @@
"""Add locations, mapsets and layers to the tree."""
self._initTreeItems()
+ def Reload(self):
+ """Reload tree"""
+ self._model = TreeModel(DataCatalogNode)
+ self._initTreeItems()
+
def OnCopy(self, event):
"""Copy layer or mapset (just save it temporarily, copying is done by paste)"""
self.copy_layer = self.selected_layer
@@ -352,8 +422,11 @@
"""Rename levent with dialog"""
if self.selected_layer:
self.old_name = self.selected_layer.label
- self.new_name = self._getUserEntry(_('New name'), _('Rename map'), self.old_name)
- self.Rename()
+ gisrc, env = getEnvironment(self.gisdbase, self.selected_location.label, mapset=self.selected_mapset.label)
+ self.new_name = self._getNewMapName(_('New name'), _('Rename map'),
+ self.old_name, env=env, mapset=self.selected_mapset.label, element=self.selected_type.label)
+ if self.new_name:
+ self.Rename()
def OnStartEditLabel(self, node, event):
"""Start label editing"""
@@ -400,18 +473,18 @@
if not self.copy_layer:
GMessage(_("No map selected for copying."), parent=self)
return
- if self.selected_location == self.copy_location and \
- self.selected_mapset.data['name'] == gscript.gisenv()['MAPSET']:
+ if self.selected_location == self.copy_location:
if self.selected_type:
if self.copy_type.label != self.selected_type.label: # copy raster to vector or vice versa
GError(_("Failed to copy map: invalid map type "
"({} vs. {}).".format(self.copy_type.label, self.selected_type.label)), parent=self)
return
- self.new_name = self._getUserEntry(_('New name'), _('Copy map'),
- self.copy_layer.label + '_copy')
+ gisrc, env = getEnvironment(self.gisdbase, self.selected_location.label, mapset=self.selected_mapset.label)
+ self.new_name = self._getNewMapName(_('New name'), _('Copy map'),
+ self.copy_layer.label, env=env, mapset=self.selected_mapset.label, element=self.copy_type.label)
if not self.new_name:
return
- if self.copy_layer.label == self.new_name:
+ if map_exists(self.new_name, element=self.copy_type.label, env=env, mapset=self.selected_mapset.label):
GMessage(_("Failed to copy map: new map has the same name"), parent=self)
return
@@ -435,7 +508,7 @@
overwrite = True
string = self.copy_layer.label + '@' + self.copy_mapset.label + ',' + self.new_name
- gisrc, env = getEnvironment(self.gisdbase, self.selected_location.label, self.selected_mapset.label)
+
pasted = 0
label = _("Copying <{name}>...").format(name=string)
self.showNotification.emit(message=label)
@@ -449,29 +522,32 @@
pasted, cmd = self._runCommand('g.copy', raster_3d=string, overwrite=overwrite, env=env)
node = 'raster_3d'
if pasted == 0:
- if not self.selected_type:
- # add type node if not exists
- self.selected_type = self._model.AppendNode(parent=self.selected_mapset, label=node,
- data=dict(type='element', name=node))
- if not overwrite:
- self._model.AppendNode(parent=self.selected_type, label=self.new_name,
- data=dict(type=node, name=self.new_name))
- self._model.SortChildren(self.selected_type)
- self.RefreshNode(self.selected_type, recursive=True)
+ self.InsertLayer(name=self.new_name, mapset_node=self.selected_mapset, element_name=node)
Debug.msg(1, "COPIED TO: " + self.new_name)
self.showNotification.emit(message= _("{cmd} -- completed").format(cmd=cmd))
gscript.try_remove(gisrc)
else:
- if self.selected_location != self.copy_location:
- GError(_("Failed to copy map: action is allowed only within the same location."),
- parent=self)
- else:
- GError(_("Failed to copy map: action is allowed only within the current mapset."),
- parent=self)
-
+ GError(_("Failed to copy map: action is allowed only within the same location."),
+ parent=self)
+
# expand selected mapset
self.ExpandNode(self.selected_mapset, recursive=True)
+ def InsertLayer(self, name, mapset_node, element_name):
+ """Insert layer into model and rferesh tree"""
+ found_element = self._model.SearchNodes(parent=mapset_node, type='element', name=element_name)
+ found_element = found_element[0] if found_element else None
+ if not found_element:
+ # add type node if not exists
+ found_element = self._model.AppendNode(parent=mapset_node, label=element_name,
+ data=dict(type='element', name=element_name))
+ found = self._model.SearchNodes(parent=found_element, name=name)
+ if len(found) == 0:
+ self._model.AppendNode(parent=found_element, label=name,
+ data=dict(type=element_name, name=name))
+ self._model.SortChildren(found_element)
+ self.RefreshNode(mapset_node, recursive=True)
+
def OnDelete(self, event):
"""Delete layer or mapset"""
if self.selected_layer:
@@ -478,8 +554,10 @@
string = self.selected_layer.label
gisrc, env = getEnvironment(self.gisdbase, self.selected_location.label, self.selected_mapset.label)
removed = 0
- # TODO: rewrite this that it will tell map type in the dialog
- if self._confirmDialog(question=_('Do you really want to delete map <{m}>?').format(m=string),
+ if self._confirmDialog(question=_("Do you really want to delete map <{m}> of type <{etype}> from mapset "
+ "<{mapset}> in location <{loc}>?").format(m=string, mapset=self.selected_mapset.label,
+ etype=self.selected_type.label,
+ loc=self.selected_location.label),
title=_('Delete map')) == wx.ID_YES:
label = _("Deleting {name}...").format(name=string)
self.showNotification.emit(message=label)
@@ -550,9 +628,10 @@
else:
event.Veto()
- def _getUserEntry(self, message, title, value):
+ def _getNewMapName(self, message, title, value, element, mapset, env):
"""Dialog for simple text entry"""
- dlg = TextEntryDialog(self, message, title)
+ dlg = NameEntryDialog(parent=self, message=message, caption=title,
+ element=element, env=env, mapset=mapset)
dlg.SetValue(value)
if dlg.ShowModal() == wx.ID_OK:
name = dlg.GetValue()
@@ -577,20 +656,20 @@
menu.AppendItem(item)
self.Bind(wx.EVT_MENU, self.OnCopy, item)
+ item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))
+ menu.AppendItem(item)
+ self.Bind(wx.EVT_MENU, self.OnPaste, item)
+
item = wx.MenuItem(menu, wx.NewId(), _("&Delete"))
menu.AppendItem(item)
self.Bind(wx.EVT_MENU, self.OnDelete, item)
- if not current_mapset:
- item.Enable(False)
item = wx.MenuItem(menu, wx.NewId(), _("&Rename"))
menu.AppendItem(item)
self.Bind(wx.EVT_MENU, self.OnRename, item)
- if not current_mapset:
- item.Enable(False)
if not isinstance(self._giface, StandaloneGrassInterface):
- item = wx.MenuItem(menu, wx.NewId(), _("&Display"))
+ item = wx.MenuItem(menu, wx.NewId(), _("&Display layer"))
menu.AppendItem(item)
self.Bind(wx.EVT_MENU, self.OnDisplayLayer, item)
@@ -607,3 +686,14 @@
self.PopupMenu(menu)
menu.Destroy()
+
+ def _popupMenuElement(self):
+ """Create popup menu for elements"""
+ menu = wx.Menu()
+
+ item = wx.MenuItem(menu, wx.NewId(), _("&Paste"))
+ menu.AppendItem(item)
+ self.Bind(wx.EVT_MENU, self.OnPaste, item)
+
+ self.PopupMenu(menu)
+ menu.Destroy()
Index: dbmgr/base.py
===================================================================
--- dbmgr/base.py (revision 68055)
+++ dbmgr/base.py (working copy)
@@ -252,6 +252,7 @@
record = record.split(fs)
if len(columns) != len(record):
+ print columns, record
GError(parent = self,
message = _("Inconsistent number of columns "
"in the table <%(table)s>.") % \
Index: dbmgr/dialogs.py
===================================================================
--- dbmgr/dialogs.py (revision 68055)
+++ dbmgr/dialogs.py (working copy)
@@ -303,7 +303,7 @@
"""
frame = self.parent.parent
frame.dialogs['attributes'] = None
- if hasattr(self, "digit"):
+ if self.parent.digit:
self.parent.digit.GetDisplay().SetSelected([])
if frame.IsAutoRendered():
self.parent.UpdateMap(render = False)
Index: gis_set.py
===================================================================
--- gis_set.py (revision 68055)
+++ gis_set.py (working copy)
@@ -249,12 +249,15 @@
self.delete_mapset_button.Enable(False)
# set database
- if not self.gisdbase:
+ if self.GetRCValue("LOCATION_NAME") == "<UNKNOWN>":
# sets an initial path for gisdbase if nothing in GISRC
- if os.path.isdir(os.getenv("HOME")):
- self.gisdbase = os.getenv("HOME")
+ from os.path import expanduser
+ if os.path.isdir(os.path.join(os.path.expanduser('~'), 'grassdata')):
+ self.gisdbase = os.path.join(os.path.expanduser('~'), 'grassdata')
else:
self.gisdbase = os.getcwd()
+ RunCommand("g.gisenv",
+ set = "GISDBASE=%s" % self.gisdbase)
try:
self.tgisdbase.SetValue(self.gisdbase)
except UnicodeDecodeError:
@@ -444,7 +447,7 @@
grassrc = {}
gisrc = os.getenv("GISRC")
-
+ print gisrc
if gisrc and os.path.isfile(gisrc):
try:
rc = open(gisrc, "r")
@@ -470,6 +473,7 @@
There is no cleaning procedure. You should call _hideMessage when
you know that there is everything correct now.
"""
+ print 'show warning'
self.lmessage.SetLabel(text)
self.lmessage.Wrap(self.GetClientSize()[0])
self.sizer.Layout()
@@ -493,6 +497,7 @@
# we do no hide widget
# because we do not want the dialog to change the size
self.lmessage.SetLabel("")
+ print 'hide'
self.sizer.Layout()
def GetRCValue(self, value):
@@ -1093,17 +1098,18 @@
self.SetTopWindow(StartUp)
StartUp.Show()
- if StartUp.GetRCValue("LOCATION_NAME") == "<UNKNOWN>":
- # TODO: This is not ideal, either it should be checked elsewhere
- # where other checks are performed or it should use some public
- # API. There is no reason for not exposing it.
- # TODO: another question is what should be warning, hint or message
- StartUp._showWarning(_('GRASS needs a directory (GRASS database) '
- 'in which to store its data. '
- 'Create one now if you have not already done so. '
- 'A popular choice is "grassdata", located in '
- 'your home directory. '
- 'Press Browse button to select the directory.'))
+# if StartUp.GetRCValue("LOCATION_NAME") == "<UNKNOWN>":
+# # TODO: This is not ideal, either it should be checked elsewhere
+# # where other checks are performed or it should use some public
+# # API. There is no reason for not exposing it.
+# # TODO: another question is what should be warning, hint or message
+#
+# StartUp._showWarning(_('GRASS needs a directory (GRASS database) '
+# 'in which to store its data. '
+# 'Create one now if you have not already done so. '
+# 'A popular choice is "grassdata", located in '
+# 'your home directory. '
+# 'Press Browse button to select the directory.'))
return 1
Index: location_wizard/wizard.py
===================================================================
--- location_wizard/wizard.py (revision 68055)
+++ location_wizard/wizard.py (working copy)
@@ -2161,9 +2161,7 @@
self.ellipsepage.DoLayout()
self.custompage.DoLayout()
self.sumpage.DoLayout()
- self.wizard.FitToPage(self.datumpage)
- size = self.wizard.GetPageSize()
- self.wizard.SetPageSize((size[0], size[1] + 75))
+ self.wizard.GetPageAreaSizer().Add(self.startpage)
# new location created?
self.location = None
More information about the grass-dev
mailing list