[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