Ejemplo n.º 1
0
class DataCatalog(wx.Panel):
    """Data catalog panel"""
    def __init__(
            self,
            parent,
            giface=None,
            id=wx.ID_ANY,
            title=_("Data catalog"),
            name="catalog",
            **kwargs,
    ):
        """Panel constructor"""
        self.showNotification = Signal("DataCatalog.showNotification")
        self.parent = parent
        self.baseTitle = title
        self.giface = giface
        self._startLoadingTime = 0
        wx.Panel.__init__(self, parent=parent, id=id, **kwargs)
        self.SetName("DataCatalog")

        Debug.msg(1, "DataCatalog.__init__()")

        # toolbar
        self.toolbar = DataCatalogToolbar(parent=self)

        # tree with layers
        self.tree = DataCatalogTree(self, giface=giface)
        self.tree.showNotification.connect(self.showNotification)

        # infobar for data catalog
        delay = 2000
        self.infoBar = InfoBar(self)
        self.giface.currentMapsetChanged.connect(self.dismissInfobar)

        # infobar manager for data catalog
        self.infoManager = DataCatalogInfoManager(infobar=self.infoBar,
                                                  giface=self.giface)
        self.tree.showImportDataInfo.connect(self.showImportDataInfo)
        self.tree.loadingDone.connect(self._loadingDone)

        # some layout
        self._layout()

        # show infobar for first-time user if applicable
        if is_first_time_user():
            # show data structure infobar for first-time user
            wx.CallLater(delay, self.showDataStructureInfo)

        # show infobar if last used mapset is not usable
        if is_fallback_session():
            # get reason why last used mapset is not usable
            last_mapset_path = gisenv()["LAST_MAPSET_PATH"]
            self.reason_id = get_reason_id_mapset_not_usable(last_mapset_path)
            if self.reason_id in ("non-existent", "invalid",
                                  "different-owner"):
                # show non-standard situation info
                wx.CallLater(delay, self.showFallbackSessionInfo)
            elif self.reason_id == "locked":
                # show info allowing to switch to locked mapset
                wx.CallLater(delay, self.showLockedMapsetInfo)

    def _layout(self):
        """Do layout"""
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.toolbar, proportion=0, flag=wx.EXPAND)
        sizer.Add(self.infoBar, proportion=0, flag=wx.EXPAND)
        sizer.Add(self.tree.GetControl(), proportion=1, flag=wx.EXPAND)

        self.SetAutoLayout(True)
        self.SetSizer(sizer)
        self.Fit()

        self.Layout()

    def showDataStructureInfo(self):
        self.infoManager.ShowDataStructureInfo(self.OnCreateLocation)

    def showLockedMapsetInfo(self):
        self.infoManager.ShowLockedMapsetInfo(self.OnSwitchToLastUsedMapset)

    def showFallbackSessionInfo(self):
        self.infoManager.ShowFallbackSessionInfo(self.reason_id)

    def showImportDataInfo(self):
        self.infoManager.ShowImportDataInfo(self.OnImportOgrLayers,
                                            self.OnImportGdalLayers)

    def LoadItems(self):
        """Reload tree - full or lazy - based on user settings"""
        self._startLoadingTime = clock()
        self.tree.ReloadTreeItems(full=False)

    def _loadingDone(self):
        """If loading took more time, suggest lazy loading"""
        if clock(
        ) - self._startLoadingTime > 5 and not self.tree._useLazyLoading():
            asked = UserSettings.Get(group="datacatalog",
                                     key="lazyLoading",
                                     subkey="asked")
            if not asked:
                wx.CallAfter(
                    self.infoManager.ShowLazyLoadingOn,
                    setLazyLoadingOnHandler=self._saveLazyLoadingOnSettings,
                    doNotAskHandler=self._saveDontAskLazyLoadingSettings,
                )

    def _saveLazyLoadingOnSettings(self, event):
        """Turn on lazy loading in settings"""
        UserSettings.Set(group="datacatalog",
                         key="lazyLoading",
                         subkey="enabled",
                         value=True)
        UserSettings.Set(group="datacatalog",
                         key="lazyLoading",
                         subkey="asked",
                         value=True)
        self._saveLazyLoadingSettings()
        event.Skip()

    def _saveDontAskLazyLoadingSettings(self, event):
        """Save in settings that decision on lazy loading was done to not ask again"""
        UserSettings.Set(group="datacatalog",
                         key="lazyLoading",
                         subkey="asked",
                         value=True)
        self._saveLazyLoadingSettings()
        event.Skip()

    def _saveLazyLoadingSettings(self):
        dcSettings = {}
        UserSettings.ReadSettingsFile(settings=dcSettings)
        if "datacatalog" not in dcSettings:
            dcSettings["datacatalog"] = UserSettings.Get(group="datacatalog")
        dcSettings["datacatalog"]["lazyLoading"] = UserSettings.Get(
            group="datacatalog", key="lazyLoading")
        UserSettings.SaveToFile(dcSettings)

    def dismissInfobar(self):
        if self.infoBar.IsShown():
            self.infoBar.Dismiss()

    def OnReloadTree(self, event):
        """Reload whole tree"""
        self.tree.ReloadTreeItems(full=True)

    def OnReloadCurrentMapset(self, event):
        """Reload current mapset tree only"""
        self.tree.ReloadCurrentMapset()

    def OnAddGrassDB(self, event):
        """Add grass database"""
        dlg = wx.DirDialog(self, _("Choose GRASS data directory:"),
                           os.getcwd(), wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            grassdatabase = dlg.GetPath()
            grassdb_node = self.tree.InsertGrassDb(name=grassdatabase)

            # Offer to create a new location
            if grassdb_node and not os.listdir(grassdatabase):
                message = _("Do you want to create a location?")
                dlg2 = wx.MessageDialog(
                    self,
                    message=message,
                    caption=_("Create location?"),
                    style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION,
                )
                if dlg2.ShowModal() == wx.ID_YES:
                    self.tree.CreateLocation(grassdb_node)
                dlg2.Destroy()
        dlg.Destroy()

    def OnCreateMapset(self, event):
        """Create new mapset in current location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateMapset(db_node, loc_node)

    def OnCreateLocation(self, event):
        """Create new location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateLocation(db_node)

    def OnDownloadLocation(self, event):
        """Download location to current grass database"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.DownloadLocation(db_node)

    def OnSwitchToLastUsedMapset(self, event):
        """Switch to last used mapset"""
        last_mapset_path = gisenv()["LAST_MAPSET_PATH"]
        grassdb, location, mapset = split_mapset_path(last_mapset_path)
        self.tree.SwitchMapset(grassdb, location, mapset)

    def OnImportGdalLayers(self, event):
        """Convert multiple GDAL layers to GRASS raster map layers"""
        from modules.import_export import GdalImportDialog

        dlg = GdalImportDialog(parent=self, giface=self.giface)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnImportOgrLayers(self, event):
        """Convert multiple OGR layers to GRASS vector map layers"""
        from modules.import_export import OgrImportDialog

        dlg = OgrImportDialog(parent=self, giface=self.giface)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnLinkGdalLayers(self, event):
        """Link multiple GDAL layers to GRASS raster map layers"""
        from modules.import_export import GdalImportDialog

        dlg = GdalImportDialog(parent=self, giface=self.giface, link=True)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnLinkOgrLayers(self, event):
        """Links multiple OGR layers to GRASS vector map layers"""
        from modules.import_export import OgrImportDialog

        dlg = OgrImportDialog(parent=self, giface=self.giface, link=True)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnRasterOutputFormat(self, event):
        """Set raster output format handler"""
        from modules.import_export import GdalOutputDialog

        dlg = GdalOutputDialog(parent=self, ogr=False)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnVectorOutputFormat(self, event):
        """Set vector output format handler"""
        from modules.import_export import GdalOutputDialog

        dlg = GdalOutputDialog(parent=self, ogr=True)
        dlg.CentreOnScreen()
        dlg.Show()

    def GuiParseCommand(self, cmd):
        """Generic handler"""
        GUI(parent=self, giface=self.giface).ParseCommand(cmd=[cmd])

    def OnMoreOptions(self, event):
        self.giface.Help(entry="topic_import")

    def SetRestriction(self, restrict):
        """Allow editing other mapsets or restrict editing to current mapset"""
        self.tree.SetRestriction(restrict)

    def Filter(self, text, element=None):
        self.tree.Filter(text=text, element=element)

    def OnImportMenu(self, event):
        """Create popup menu for other import options"""
        # create submenu
        subMenu = Menu()

        subitem = wx.MenuItem(subMenu, wx.ID_ANY,
                              _("Link external raster data  [r.external]"))
        subMenu.AppendItem(subitem)
        self.Bind(wx.EVT_MENU, self.OnLinkGdalLayers, subitem)

        subitem = wx.MenuItem(subMenu, wx.ID_ANY,
                              _("Link external vector data  [v.external]"))
        subMenu.AppendItem(subitem)
        self.Bind(wx.EVT_MENU, self.OnLinkOgrLayers, subitem)

        subMenu.AppendSeparator()

        subitem = wx.MenuItem(subMenu, wx.ID_ANY,
                              _("Set raster output format  [r.external.out]"))
        subMenu.AppendItem(subitem)
        self.Bind(wx.EVT_MENU, self.OnRasterOutputFormat, subitem)

        subitem = wx.MenuItem(subMenu, wx.ID_ANY,
                              _("Set vector output format  [v.external.out]"))
        subMenu.AppendItem(subitem)
        self.Bind(wx.EVT_MENU, self.OnVectorOutputFormat, subitem)

        # create menu
        menu = Menu()

        item = wx.MenuItem(menu, wx.ID_ANY,
                           _("Unpack GRASS raster map  [r.unpack]"))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, lambda evt: self.GuiParseCommand("r.unpack"),
                  item)

        item = wx.MenuItem(menu, wx.ID_ANY,
                           _("Unpack GRASS vector map  [v.unpack]"))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, lambda evt: self.GuiParseCommand("v.unpack"),
                  item)

        menu.AppendSeparator()

        item = wx.MenuItem(menu, wx.ID_ANY,
                           _("Create raster map from x,y,z data  [r.in.xyz]"))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, lambda evt: self.GuiParseCommand("r.in.xyz"),
                  item)

        item = wx.MenuItem(
            menu, wx.ID_ANY,
            _("Create vector map from x,y,z data  [v.in.ascii]"))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, lambda evt: self.GuiParseCommand("v.in.ascii"),
                  item)

        menu.AppendSeparator()
        menu.AppendMenu(wx.ID_ANY, _("Link external data"), subMenu)

        menu.AppendSeparator()
        item = wx.MenuItem(menu, wx.ID_ANY, _("More options..."))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, self.OnMoreOptions, item)

        self.PopupMenu(menu)
        menu.Destroy()
Ejemplo n.º 2
0
class DataCatalog(wx.Panel):
    """Data catalog panel"""
    def __init__(self,
                 parent,
                 giface=None,
                 id=wx.ID_ANY,
                 title=_("Data catalog"),
                 name='catalog',
                 **kwargs):
        """Panel constructor  """
        self.showNotification = Signal('DataCatalog.showNotification')
        self.parent = parent
        self.baseTitle = title
        wx.Panel.__init__(self, parent=parent, id=id, **kwargs)
        self.SetName("DataCatalog")

        Debug.msg(1, "DataCatalog.__init__()")

        # toolbar
        self.toolbar = DataCatalogToolbar(parent=self)

        # tree with layers
        self.tree = DataCatalogTree(self, giface=giface)
        self.tree.showNotification.connect(self.showNotification)

        # some layout
        self._layout()

    def _layout(self):
        """Do layout"""
        sizer = wx.BoxSizer(wx.VERTICAL)

        sizer.Add(self.toolbar, proportion=0, flag=wx.EXPAND)

        sizer.Add(self.tree.GetControl(), proportion=1, flag=wx.EXPAND)

        self.SetAutoLayout(True)
        self.SetSizer(sizer)

        self.Layout()

    def LoadItems(self):
        self.tree.ReloadTreeItems()

    def OnReloadTree(self, event):
        """Reload whole tree"""
        self.LoadItems()

    def OnReloadCurrentMapset(self, event):
        """Reload current mapset tree only"""
        self.tree.ReloadCurrentMapset()

    def OnAddGrassDB(self, event):
        """Add grass database"""
        dlg = wx.DirDialog(self, _("Choose GRASS data directory:"),
                           os.getcwd(), wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            grassdatabase = dlg.GetPath()
            self.tree.InsertGrassDb(name=grassdatabase)
        dlg.Destroy()

    def OnCreateMapset(self, event):
        """Create new mapset in current location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateMapset(db_node, loc_node)

    def OnCreateLocation(self, event):
        """Create new location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateLocation(db_node)

    def OnDownloadLocation(self, event):
        """Download location to current grass database"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.DownloadLocation(db_node)

    def SetRestriction(self, restrict):
        """Allow editing other mapsets or restrict editing to current mapset"""
        self.tree.SetRestriction(restrict)

    def Filter(self, text):
        self.tree.Filter(text=text)
Ejemplo n.º 3
0
class DataCatalog(wx.Panel):
    """Data catalog panel"""
    def __init__(self,
                 parent,
                 giface=None,
                 id=wx.ID_ANY,
                 title=_("Data catalog"),
                 name='catalog',
                 **kwargs):
        """Panel constructor  """
        self.showNotification = Signal('DataCatalog.showNotification')
        self.parent = parent
        self.baseTitle = title
        self.giface = giface
        wx.Panel.__init__(self, parent=parent, id=id, **kwargs)
        self.SetName("DataCatalog")

        Debug.msg(1, "DataCatalog.__init__()")

        # toolbar
        self.toolbar = DataCatalogToolbar(parent=self)

        # tree with layers
        self.tree = DataCatalogTree(self, giface=giface)
        self.tree.showNotification.connect(self.showNotification)

        # infobar for data catalog
        self.infoBar = InfoBar(self)

        # infobar manager for data catalog
        self.infoManager = DataCatalogInfoManager(infobar=self.infoBar,
                                                  giface=self.giface)
        self.tree.showImportDataInfo.connect(self.showImportDataInfo)

        # some layout
        self._layout()

        # show data structure infobar for first-time user with proper layout
        if is_current_mapset_in_demolocation():
            wx.CallLater(2000, self.showDataStructureInfo)

    def _layout(self):
        """Do layout"""
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.toolbar, proportion=0, flag=wx.EXPAND)
        sizer.Add(self.infoBar, proportion=0, flag=wx.EXPAND)
        sizer.Add(self.tree.GetControl(), proportion=1, flag=wx.EXPAND)

        self.SetAutoLayout(True)
        self.SetSizer(sizer)
        self.Fit()

        self.Layout()

    def showDataStructureInfo(self):
        self.infoManager.ShowDataStructureInfo(self.OnCreateLocation)

    def showImportDataInfo(self):
        self.infoManager.ShowImportDataInfo(self.OnImportOgrLayers,
                                            self.OnImportGdalLayers)

    def LoadItems(self):
        self.tree.ReloadTreeItems()

    def OnReloadTree(self, event):
        """Reload whole tree"""
        self.LoadItems()

    def OnReloadCurrentMapset(self, event):
        """Reload current mapset tree only"""
        self.tree.ReloadCurrentMapset()

    def OnAddGrassDB(self, event):
        """Add grass database"""
        dlg = wx.DirDialog(self, _("Choose GRASS data directory:"),
                           os.getcwd(), wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            grassdatabase = dlg.GetPath()
            self.tree.InsertGrassDb(name=grassdatabase)
        dlg.Destroy()

    def OnCreateMapset(self, event):
        """Create new mapset in current location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateMapset(db_node, loc_node)

    def OnImportOgrLayers(self, event, cmd=None):
        """Convert multiple OGR layers to GRASS vector map layers"""
        from modules.import_export import OgrImportDialog
        dlg = OgrImportDialog(parent=self, giface=self.giface)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnImportGdalLayers(self, event, cmd=None):
        """Convert multiple GDAL layers to GRASS raster map layers"""
        from modules.import_export import GdalImportDialog
        dlg = GdalImportDialog(parent=self, giface=self.giface)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnCreateLocation(self, event):
        """Create new location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateLocation(db_node)

    def OnDownloadLocation(self, event):
        """Download location to current grass database"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.DownloadLocation(db_node)

    def SetRestriction(self, restrict):
        """Allow editing other mapsets or restrict editing to current mapset"""
        self.tree.SetRestriction(restrict)

    def Filter(self, text):
        self.tree.Filter(text=text)
Ejemplo n.º 4
0
class DataCatalogFrame(wx.Frame):
    """Frame for testing purposes only."""
    def __init__(self, parent, giface=None):
        wx.Frame.__init__(self,
                          parent=parent,
                          title=_('GRASS GIS Data Catalog'))
        self.SetName("DataCatalog")
        self.SetIcon(
            wx.Icon(os.path.join(ICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))

        self._giface = giface
        self.panel = wx.Panel(self)

        self.toolbar = DataCatalogToolbar(parent=self)
        # workaround for http://trac.wxwidgets.org/ticket/13888
        if sys.platform != 'darwin':
            self.SetToolBar(self.toolbar)

        # tree
        self.tree = DataCatalogTree(parent=self.panel, giface=self._giface)
        self.tree.ReloadTreeItems()

        # buttons
        self.btnClose = Button(parent=self.panel, id=wx.ID_CLOSE)
        self.btnClose.SetToolTip(_("Close GRASS GIS Data Catalog"))
        self.btnClose.SetDefault()

        # events
        self.btnClose.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        self._layout()

    def _layout(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.tree, proportion=1, flag=wx.EXPAND)

        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.AddStretchSpacer()
        btnSizer.Add(self.btnClose)

        sizer.Add(btnSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)

        self.panel.SetSizer(sizer)
        sizer.Fit(self.panel)

        self.SetMinSize((400, 500))

    def OnCloseWindow(self, event):
        """Cancel button pressed"""
        if not isinstance(event, wx.CloseEvent):
            self.Destroy()

        event.Skip()

    def OnReloadTree(self, event):
        """Reload whole tree"""
        self.tree.ReloadTreeItems()

    def OnReloadCurrentMapset(self, event):
        """Reload current mapset tree only"""
        self.tree.ReloadCurrentMapset()

    def OnAddGrassDB(self, event):
        """Add grass database"""
        dlg = wx.DirDialog(self, _("Choose GRASS data directory:"),
                           os.getcwd(), wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            grassdatabase = dlg.GetPath()
            self.tree.InsertGrassDb(name=grassdatabase)
        dlg.Destroy()

    def OnCreateMapset(self, event):
        """Create new mapset in current location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateMapset(db_node, loc_node)

    def OnCreateLocation(self, event):
        """Create new location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateLocation(db_node)

    def OnDownloadLocation(self, event):
        """Download location online"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.DownloadLocation(db_node)

    def SetRestriction(self, restrict):
        """Allow editing other mapsets or restrict editing to current mapset"""
        self.tree.SetRestriction(restrict)

    def Filter(self, text):
        self.tree.Filter(text=text)
Ejemplo n.º 5
0
class DataCatalog(wx.Panel):
    """Data catalog panel"""
    def __init__(self,
                 parent,
                 giface=None,
                 id=wx.ID_ANY,
                 title=_("Data catalog"),
                 name='catalog',
                 **kwargs):
        """Panel constructor  """
        self.showNotification = Signal('DataCatalog.showNotification')
        self.parent = parent
        self.baseTitle = title
        self.giface = giface
        wx.Panel.__init__(self, parent=parent, id=id, **kwargs)
        self.SetName("DataCatalog")

        Debug.msg(1, "DataCatalog.__init__()")

        # toolbar
        self.toolbar = DataCatalogToolbar(parent=self)

        # tree with layers
        self.tree = DataCatalogTree(self, giface=giface)
        self.tree.showNotification.connect(self.showNotification)

        # infobar for data catalog
        self.infoBar = InfoBar(self)

        # infobar manager for data catalog
        self.infoManager = DataCatalogInfoManager(infobar=self.infoBar,
                                                  giface=self.giface)
        self.tree.showImportDataInfo.connect(self.showImportDataInfo)

        # some layout
        self._layout()

        # show data structure infobar for first-time user with proper layout
        if is_current_mapset_in_demolocation():
            wx.CallLater(2000, self.showDataStructureInfo)

    def _layout(self):
        """Do layout"""
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.toolbar, proportion=0, flag=wx.EXPAND)
        sizer.Add(self.infoBar, proportion=0, flag=wx.EXPAND)
        sizer.Add(self.tree.GetControl(), proportion=1, flag=wx.EXPAND)

        self.SetAutoLayout(True)
        self.SetSizer(sizer)
        self.Fit()

        self.Layout()

    def showDataStructureInfo(self):
        self.infoManager.ShowDataStructureInfo(self.OnCreateLocation)

    def showImportDataInfo(self):
        self.infoManager.ShowImportDataInfo(self.OnImportOgrLayers,
                                            self.OnImportGdalLayers)

    def LoadItems(self):
        self.tree.ReloadTreeItems()

    def OnReloadTree(self, event):
        """Reload whole tree"""
        self.LoadItems()

    def OnReloadCurrentMapset(self, event):
        """Reload current mapset tree only"""
        self.tree.ReloadCurrentMapset()

    def OnAddGrassDB(self, event):
        """Add grass database"""
        dlg = wx.DirDialog(self, _("Choose GRASS data directory:"),
                           os.getcwd(), wx.DD_DEFAULT_STYLE)
        if dlg.ShowModal() == wx.ID_OK:
            grassdatabase = dlg.GetPath()
            grassdb_node = self.tree.InsertGrassDb(name=grassdatabase)

            # Offer to create a new location
            if grassdb_node and not os.listdir(grassdatabase):
                message = _("Do you want to create a location?")
                dlg2 = wx.MessageDialog(self,
                                        message=message,
                                        caption=_("Create location?"),
                                        style=wx.YES_NO | wx.YES_DEFAULT
                                        | wx.ICON_QUESTION)
                if dlg2.ShowModal() == wx.ID_YES:
                    self.tree.CreateLocation(grassdb_node)
                dlg2.Destroy()
        dlg.Destroy()

    def OnCreateMapset(self, event):
        """Create new mapset in current location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateMapset(db_node, loc_node)

    def OnCreateLocation(self, event):
        """Create new location"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.CreateLocation(db_node)

    def OnDownloadLocation(self, event):
        """Download location to current grass database"""
        db_node, loc_node, mapset_node = self.tree.GetCurrentDbLocationMapsetNode(
        )
        self.tree.DownloadLocation(db_node)

    def OnImportGdalLayers(self, event):
        """Convert multiple GDAL layers to GRASS raster map layers"""
        from modules.import_export import GdalImportDialog
        dlg = GdalImportDialog(parent=self, giface=self.giface)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnImportOgrLayers(self, event):
        """Convert multiple OGR layers to GRASS vector map layers"""
        from modules.import_export import OgrImportDialog
        dlg = OgrImportDialog(parent=self, giface=self.giface)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnLinkGdalLayers(self, event):
        """Link multiple GDAL layers to GRASS raster map layers"""
        from modules.import_export import GdalImportDialog
        dlg = GdalImportDialog(parent=self, giface=self.giface, link=True)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnLinkOgrLayers(self, event):
        """Links multiple OGR layers to GRASS vector map layers"""
        from modules.import_export import OgrImportDialog
        dlg = OgrImportDialog(parent=self, giface=self.giface, link=True)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnRasterOutputFormat(self, event):
        """Set raster output format handler"""
        from modules.import_export import GdalOutputDialog
        dlg = GdalOutputDialog(parent=self, ogr=False)
        dlg.CentreOnScreen()
        dlg.Show()

    def OnVectorOutputFormat(self, event):
        """Set vector output format handler"""
        from modules.import_export import GdalOutputDialog
        dlg = GdalOutputDialog(parent=self, ogr=True)
        dlg.CentreOnScreen()
        dlg.Show()

    def GuiParseCommand(self, cmd):
        """Generic handler"""
        GUI(parent=self, giface=self.giface).ParseCommand(cmd=[cmd])

    def OnMoreOptions(self, event):
        self.giface.Help(entry="topic_import")

    def SetRestriction(self, restrict):
        """Allow editing other mapsets or restrict editing to current mapset"""
        self.tree.SetRestriction(restrict)

    def Filter(self, text, element=None):
        self.tree.Filter(text=text, element=element)

    def OnImportMenu(self, event):
        """Create popup menu for other import options"""
        # create submenu
        subMenu = Menu()

        subitem = wx.MenuItem(subMenu, wx.ID_ANY,
                              _("Link external raster data  [r.external]"))
        subMenu.AppendItem(subitem)
        self.Bind(wx.EVT_MENU, self.OnLinkGdalLayers, subitem)

        subitem = wx.MenuItem(subMenu, wx.ID_ANY,
                              _("Link external vector data  [v.external]"))
        subMenu.AppendItem(subitem)
        self.Bind(wx.EVT_MENU, self.OnLinkOgrLayers, subitem)

        subMenu.AppendSeparator()

        subitem = wx.MenuItem(subMenu, wx.ID_ANY,
                              _("Set raster output format  [r.external.out]"))
        subMenu.AppendItem(subitem)
        self.Bind(wx.EVT_MENU, self.OnRasterOutputFormat, subitem)

        subitem = wx.MenuItem(subMenu, wx.ID_ANY,
                              _("Set vector output format  [v.external.out]"))
        subMenu.AppendItem(subitem)
        self.Bind(wx.EVT_MENU, self.OnVectorOutputFormat, subitem)

        # create menu
        menu = Menu()

        item = wx.MenuItem(menu, wx.ID_ANY,
                           _("Unpack GRASS raster map  [r.unpack]"))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, lambda evt: self.GuiParseCommand('r.unpack'),
                  item)

        item = wx.MenuItem(menu, wx.ID_ANY,
                           _("Unpack GRASS vector map  [v.unpack]"))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, lambda evt: self.GuiParseCommand('v.unpack'),
                  item)

        menu.AppendSeparator()

        item = wx.MenuItem(menu, wx.ID_ANY,
                           _("Create raster map from x,y,z data  [r.in.xyz]"))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, lambda evt: self.GuiParseCommand('r.in.xyz'),
                  item)

        item = wx.MenuItem(
            menu, wx.ID_ANY,
            _("Create vector map from x,y,z data  [v.in.ascii]"))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, lambda evt: self.GuiParseCommand('v.in.ascii'),
                  item)

        menu.AppendSeparator()
        menu.AppendMenu(wx.ID_ANY, _("Link external data"), subMenu)

        menu.AppendSeparator()
        item = wx.MenuItem(menu, wx.ID_ANY, _("More options..."))
        menu.AppendItem(item)
        self.Bind(wx.EVT_MENU, self.OnMoreOptions, item)

        self.PopupMenu(menu)
        menu.Destroy()