Esempio n. 1
0
    def __init__(
            self,
            parent,
            giface,
            title=_("Digitization settings"),
            style=wx.DEFAULT_DIALOG_STYLE,
    ):
        """Standard settings dialog for digitization purposes"""
        wx.Dialog.__init__(self,
                           parent=parent,
                           id=wx.ID_ANY,
                           title=title,
                           style=style)

        self._giface = giface
        self.parent = parent  # MapFrame
        self.digit = self.parent.MapWindow.digit

        # notebook
        notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
        self._createGeneralPage(notebook)
        self._createSymbologyPage(notebook)
        self.digit.SetCategory()
        self._createAttributesPage(notebook)
        self._createQueryPage(notebook)

        # buttons
        btnApply = Button(self, wx.ID_APPLY)
        btnCancel = Button(self, wx.ID_CLOSE)
        btnSave = Button(self, wx.ID_SAVE)
        btnSave.SetDefault()

        # bindigs
        btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
        btnApply.SetToolTip(_("Apply changes for this session"))
        btnApply.SetDefault()
        btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
        btnSave.SetToolTip(
            _("Close dialog and save changes to user settings file"))
        btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
        btnCancel.SetToolTip(_("Close dialog and ignore changes"))

        # sizers
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(btnCancel, proportion=0, flag=wx.ALL, border=5)
        btnSizer.Add(btnApply, proportion=0, flag=wx.ALL, border=5)
        btnSizer.Add(btnSave, proportion=0, flag=wx.ALL, border=5)

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(notebook,
                      proportion=1,
                      flag=wx.EXPAND | wx.ALL,
                      border=5)
        mainSizer.Add(btnSizer, proportion=0, flag=wx.ALIGN_RIGHT, border=5)

        self.Bind(wx.EVT_CLOSE, self.OnCancel)

        self.SetSizer(mainSizer)
        mainSizer.Fit(self)
Esempio n. 2
0
class ModelItemDialog(wx.Dialog):
    """Abstract item properties dialog"""
    def __init__(
        self,
        parent,
        shape,
        title,
        id=wx.ID_ANY,
        style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
        **kwargs,
    ):
        self.parent = parent
        self.shape = shape

        wx.Dialog.__init__(self,
                           parent,
                           id,
                           title=title,
                           style=style,
                           **kwargs)

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        self.condBox = StaticBox(parent=self.panel,
                                 id=wx.ID_ANY,
                                 label=" %s " % _("Condition"))
        self.condText = TextCtrl(parent=self.panel,
                                 id=wx.ID_ANY,
                                 value=shape.GetLabel())

        self.itemList = ItemCheckListCtrl(
            parent=self.panel,
            columns=[_("Label"), _("Command")],
            shape=shape,
            frame=parent,
        )

        self.itemList.Populate(self.parent.GetModel().GetItems())

        self.btnCancel = Button(parent=self.panel, id=wx.ID_CANCEL)
        self.btnOk = Button(parent=self.panel, id=wx.ID_OK)
        self.btnOk.SetDefault()

    def _layout(self):
        """Do layout (virtual method)"""
        pass

    def GetCondition(self):
        """Get loop condition"""
        return self.condText.GetValue()
Esempio n. 3
0
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent)
        self.SetTitle(_("Create new raster map"))
        self._name = None
        self._type = None

        # create widgets
        self._mapSelect = Select(parent=self, type='raster')
        self._backgroundSelect = Select(parent=self, type='raster')
        self._typeChoice = wx.Choice(self, choices=['CELL', 'FCELL', 'DCELL'])
        self._typeChoice.SetSelection(0)
        self._mapSelect.SetFocus()

        btnCancel = Button(parent=self, id=wx.ID_CANCEL)
        btnOK = Button(parent=self, id=wx.ID_OK)
        btnOK.SetDefault()
        btnOK.Bind(wx.EVT_BUTTON, self.OnOK)

        # do layout
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        sizer = wx.GridBagSizer(hgap=10, vgap=10)
        sizer.Add(StaticText(self, label=_("Name for new raster map:")),
                  pos=(0, 0),
                  span=(1, 2),
                  flag=wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self._mapSelect, pos=(1, 0), span=(1, 2))
        sizer.Add(StaticText(
            self, label=_("Optionally select background raster map:")),
                  pos=(2, 0),
                  span=(1, 2),
                  flag=wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self._backgroundSelect, pos=(3, 0), span=(1, 2))
        sizer.Add(StaticText(self, label=_("New raster map type:")),
                  pos=(4, 0),
                  flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
        sizer.Add(self._typeChoice, pos=(4, 1), flag=wx.EXPAND)

        mainSizer.Add(sizer, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)

        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(btnCancel)
        btnSizer.AddButton(btnOK)
        btnSizer.Realize()

        mainSizer.Add(btnSizer, flag=wx.EXPAND | wx.ALL, border=10)

        self._backgroundSelect.Bind(wx.EVT_TEXT, self.OnBackgroundMap)

        self.SetSizer(mainSizer)
        mainSizer.Fit(self)
Esempio 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.catalogpanel = DataCatalog(self.panel, giface=giface)

        # 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, lambda evt: self.Close())

        self._layout()
        self.catalogpanel.LoadItems()

    def _layout(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.catalogpanel, 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((450, 500))
Esempio n. 5
0
class ReprojectionDialog(wx.Dialog):
    """ """
    def __init__(self,
                 parent,
                 giface,
                 data,
                 id=wx.ID_ANY,
                 title=_("Reprojection"),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
        self.parent = parent  # GMFrame
        self._giface = giface  # used to add layers

        wx.Dialog.__init__(self,
                           parent,
                           id,
                           title,
                           style=style,
                           name="MultiImportDialog")

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        # list of layers
        columns = [_('Layer id'), _('Name for output GRASS map')]

        self.layerBox = StaticBox(parent=self.panel, id=wx.ID_ANY)
        self.layerSizer = wx.StaticBoxSizer(self.layerBox, wx.HORIZONTAL)

        self.list = GListCtrl(parent=self.panel)

        for i in range(len(columns)):
            self.list.InsertColumn(i, columns[i])

        width = (65, 180)

        for i in range(len(width)):
            self.list.SetColumnWidth(col=i, width=width[i])

        self.list.LoadData(data)
        self.list.SelectAll(True)

        self.labelText = StaticText(
            parent=self.panel,
            id=wx.ID_ANY,
            label=
            _("Projection of following layers do not match with projection of current location. "
              ))

        label = _("Layers to be reprojected")
        self.layerBox.SetLabel(" %s - %s " %
                               (label, _("right click to (un)select all")))

        #
        # buttons
        #
        # cancel
        self.btn_close = Button(parent=self.panel, id=wx.ID_CANCEL)

        # run
        self.btn_run = Button(parent=self.panel,
                              id=wx.ID_OK,
                              label=_("&Import && reproject"))
        self.btn_run.SetToolTip(_("Reproject selected layers"))
        self.btn_run.SetDefault()

        self.doLayout()

    def doLayout(self):
        """Do layout"""
        dialogSizer = wx.BoxSizer(wx.VERTICAL)

        dialogSizer.Add(self.labelText, flag=wx.ALL | wx.EXPAND, border=5)

        self.layerSizer.Add(self.list,
                            proportion=1,
                            flag=wx.ALL | wx.EXPAND,
                            border=5)

        dialogSizer.Add(self.layerSizer,
                        proportion=1,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
                        border=5)

        #
        # buttons
        #
        btnsizer = wx.BoxSizer(orient=wx.HORIZONTAL)

        btnsizer.Add(self.btn_close,
                     proportion=0,
                     flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER,
                     border=10)

        btnsizer.Add(self.btn_run,
                     proportion=0,
                     flag=wx.RIGHT | wx.ALIGN_CENTER,
                     border=10)

        dialogSizer.Add(btnsizer,
                        proportion=0,
                        flag=wx.BOTTOM | wx.ALIGN_RIGHT,
                        border=10)

        self.panel.SetSizer(dialogSizer)
        dialogSizer.Fit(self.panel)

        self.Layout()

    def GetData(self, checked):

        return self.list.GetData(checked)
Esempio n. 6
0
class CatalogReprojectionDialog(wx.Dialog):
    def __init__(self,
                 parent,
                 giface,
                 inputGisdbase,
                 inputLocation,
                 inputMapset,
                 inputLayer,
                 inputEnv,
                 outputGisdbase,
                 outputLocation,
                 outputMapset,
                 outputLayer,
                 etype,
                 outputEnv,
                 callback,
                 id=wx.ID_ANY,
                 title=_("Reprojection"),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):

        self.parent = parent
        self._giface = giface

        wx.Dialog.__init__(self,
                           parent,
                           id,
                           title,
                           style=style,
                           name="ReprojectionDialog")

        self.panel = wx.Panel(parent=self)
        self.iGisdbase = inputGisdbase
        self.iLocation = inputLocation
        self.iMapset = inputMapset
        self.iLayer = inputLayer
        self.iEnv = inputEnv
        self.oGisdbase = outputGisdbase
        self.oLocation = outputLocation
        self.oMapset = outputMapset
        self.oLayer = outputLayer
        self.etype = etype
        self.oEnv = outputEnv
        self.callback = callback

        self._widgets()
        self._doLayout()

        if self.etype == 'raster':
            self._estimateResampling()
            self._estimateResolution()

    def _widgets(self):
        if self.etype == 'raster':
            self.resolution = TextCtrl(self.panel, validator=FloatValidator())
            self.resampling = wx.Choice(self.panel,
                                        size=(200, -1),
                                        choices=[
                                            'nearest', 'bilinear', 'bicubic',
                                            'lanczos', 'bilinear_f',
                                            'bicubic_f', 'lanczos_f'
                                        ])
        else:
            self.vsplit = TextCtrl(self.panel, validator=IntegerValidator())
            self.vsplit.SetValue('10000')

        #
        # buttons
        #
        self.btn_close = Button(parent=self.panel, id=wx.ID_CLOSE)
        self.SetEscapeId(self.btn_close.GetId())

        # run
        self.btn_run = Button(parent=self.panel,
                              id=wx.ID_OK,
                              label=_("Reproject"))
        if self.etype == 'raster':
            self.btn_run.SetToolTip(_("Reproject raster"))
        elif self.etype == 'vector':
            self.btn_run.SetToolTip(_("Reproject vector"))
        self.btn_run.SetDefault()
        self.btn_run.Bind(wx.EVT_BUTTON, self.OnReproject)

    def _doLayout(self):
        """Do layout"""
        dialogSizer = wx.BoxSizer(wx.VERTICAL)
        optionsSizer = wx.GridBagSizer(5, 5)

        label = _("Map layer <{ml}> needs to be reprojected.\n"
                  "Please review and modify reprojection parameters:").format(
                      ml=self.iLayer)
        dialogSizer.Add(StaticText(self.panel, label=label),
                        flag=wx.ALL | wx.EXPAND,
                        border=10)
        if self.etype == 'raster':
            optionsSizer.Add(StaticText(self.panel,
                                        label=_("Estimated resolution:")),
                             pos=(0, 0),
                             flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
            optionsSizer.Add(self.resolution, pos=(0, 1), flag=wx.EXPAND)
            optionsSizer.Add(StaticText(self.panel,
                                        label=_("Resampling method:")),
                             pos=(1, 0),
                             flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
            optionsSizer.Add(self.resampling, pos=(1, 1), flag=wx.EXPAND)
        else:
            optionsSizer.Add(StaticText(self.panel,
                                        label=_("Maximum segment length:")),
                             pos=(1, 0),
                             flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)
            optionsSizer.Add(self.vsplit, pos=(1, 1), flag=wx.EXPAND)
        optionsSizer.AddGrowableCol(1)
        dialogSizer.Add(optionsSizer,
                        proportion=1,
                        flag=wx.ALL | wx.EXPAND,
                        border=10)
        helptext = StaticText(
            self.panel,
            label="For more reprojection options,"
            " please see {module}".format(
                module='r.proj' if self.etype == 'raster' else 'v.proj'))
        dialogSizer.Add(helptext,
                        proportion=0,
                        flag=wx.ALL | wx.EXPAND,
                        border=10)
        #
        # buttons
        #
        btnStdSizer = wx.StdDialogButtonSizer()
        btnStdSizer.AddButton(self.btn_run)
        btnStdSizer.AddButton(self.btn_close)
        btnStdSizer.Realize()
        dialogSizer.Add(btnStdSizer,
                        proportion=0,
                        flag=wx.ALL | wx.EXPAND,
                        border=5)

        self.panel.SetSizer(dialogSizer)
        dialogSizer.Fit(self.panel)

        self.Layout()
        self.SetSize(self.GetBestSize())

    def _estimateResolution(self):
        output = RunCommand('r.proj',
                            flags='g',
                            quiet=False,
                            read=True,
                            input=self.iLayer,
                            dbase=self.iGisdbase,
                            location=self.iLocation,
                            mapset=self.iMapset,
                            env=self.oEnv).strip()
        params = parse_key_val(output, vsep=' ')
        output = RunCommand('g.region',
                            flags='ug',
                            quiet=False,
                            read=True,
                            env=self.oEnv,
                            parse=lambda x: parse_key_val(x, val_type=float),
                            **params)
        cell_ns = (output['n'] - output['s']) / output['rows']
        cell_ew = (output['e'] - output['w']) / output['cols']
        estimate = (cell_ew + cell_ns) / 2.
        self.resolution.SetValue(str(estimate))
        self.params = params

    def _estimateResampling(self):
        output = RunCommand('r.info',
                            flags='g',
                            quiet=False,
                            read=True,
                            map=self.iLayer,
                            env=self.iEnv,
                            parse=parse_key_val)
        if output['datatype'] == 'CELL':
            self.resampling.SetStringSelection('nearest')
        else:
            self.resampling.SetStringSelection('bilinear')

    def OnReproject(self, event):
        cmd = []
        if self.etype == 'raster':
            cmd.append('r.proj')
            cmd.append('dbase=' + self.iGisdbase)
            cmd.append('location=' + self.iLocation)
            cmd.append('mapset=' + self.iMapset)
            cmd.append('input=' + self.iLayer)
            cmd.append('output=' + self.oLayer)
            cmd.append('method=' + self.resampling.GetStringSelection())

            self.oEnv['GRASS_REGION'] = region_env(
                n=self.params['n'],
                s=self.params['s'],
                e=self.params['e'],
                w=self.params['w'],
                flags='a',
                res=float(self.resolution.GetValue()),
                env=self.oEnv)
        else:
            cmd.append('v.proj')
            cmd.append('dbase=' + self.iGisdbase)
            cmd.append('location=' + self.iLocation)
            cmd.append('mapset=' + self.iMapset)
            cmd.append('input=' + self.iLayer)
            cmd.append('output=' + self.oLayer)
            cmd.append('smax=' + self.vsplit.GetValue())

        self._giface.RunCmd(cmd,
                            env=self.oEnv,
                            compReg=False,
                            addLayer=False,
                            onDone=self._onDone,
                            userData=None,
                            notification=Notification.MAKE_VISIBLE)

        event.Skip()

    def _onDone(self, event):
        self.callback()
Esempio n. 7
0
class ExportCategoryRaster(wx.Dialog):

    def __init__(self, parent, title, rasterName=None, id=wx.ID_ANY,
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
                 **kwargs):
        """Dialog for export of category raster.

        :param parent: window
        :param str rasterName name of vector layer for export
        :param title: window title
        """
        wx.Dialog.__init__(self, parent, id, title, style=style, **kwargs)

        self.rasterName = rasterName
        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 = Select(parent=self.panel, type='raster',
                                     mapsets=[grass.gisenv()['MAPSET']],
                                     size=globalvar.DIALOG_GSELECT_SIZE)
        if self.rasterName:
            self.vectorNameCtrl.SetValue(self.rasterName)
        dataSizer.Add(self.vectorNameCtrl,
                      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 | wx.ALIGN_CENTER, border=5)

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

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

        self.SetMinSize(self.GetSize())

    def GetRasterName(self):
        """Returns vector name"""
        return self.vectorNameCtrl.GetValue()

    def OnOK(self, event):
        """Checks if map exists and can be overwritten."""
        overwrite = UserSettings.Get(
            group='cmd', key='overwrite', subkey='enabled')
        rast_name = self.GetRasterName()
        res = grass.find_file(rast_name, element='cell')
        if res['fullname'] and overwrite is False:
            qdlg = wx.MessageDialog(
                parent=self, message=_(
                    "Raster map <%s> already exists."
                    " Do you want to overwrite it?" %
                    rast_name), caption=_(
                    "Raster <%s> exists" %
                    rast_name), 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()
Esempio n. 8
0
class ModelSearchDialog(wx.Dialog):

    def __init__(self, parent, title=_("Add GRASS command to the model"),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs):
        """Graphical modeler module search window

        :param parent: parent window
        :param id: window id
        :param title: window title
        :param kwargs: wx.Dialogs' arguments
        """
        self.parent = parent

        wx.Dialog.__init__(
            self,
            parent=parent,
            id=wx.ID_ANY,
            title=title,
            **kwargs)
        self.SetName("ModelerDialog")
        self.SetIcon(
            wx.Icon(
                os.path.join(
                    globalvar.ICONDIR,
                    'grass.ico'),
                wx.BITMAP_TYPE_ICO))

        self._command = None
        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        self.cmdBox = StaticBox(parent=self.panel, id=wx.ID_ANY,
                                label=" %s " % _("Command"))
        self.labelBox = StaticBox(parent=self.panel, id=wx.ID_ANY,
                                  label=" %s " % _("Label and comment"))

        # menu data for search widget and prompt
        menuModel = LayerManagerMenuData()

        self.cmd_prompt = GPromptSTC(
            parent=self, menuModel=menuModel.GetModel())
        self.cmd_prompt.promptRunCmd.connect(self.OnCommand)
        self.cmd_prompt.commandSelected.connect(
            lambda command: self.label.SetValue(command))
        self.search = SearchModuleWidget(parent=self.panel,
                                         model=menuModel.GetModel(),
                                         showTip=True)
        self.search.moduleSelected.connect(
            lambda name: self.cmd_prompt.SetTextAndFocus(name + ' '))
        wx.CallAfter(self.cmd_prompt.SetFocus)

        self.label = TextCtrl(parent=self.panel, id=wx.ID_ANY)
        self.comment = TextCtrl(
            parent=self.panel,
            id=wx.ID_ANY,
            style=wx.TE_MULTILINE)

        self.btnCancel = Button(self.panel, wx.ID_CANCEL)
        self.btnOk = Button(self.panel, wx.ID_OK)
        self.btnOk.SetDefault()

        self.Bind(wx.EVT_BUTTON, self.OnOk, self.btnOk)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, self.btnCancel)

        self._layout()

        self.SetSize((500, -1))

    def _layout(self):
        cmdSizer = wx.StaticBoxSizer(self.cmdBox, wx.VERTICAL)
        cmdSizer.Add(self.cmd_prompt, proportion=1,
                     flag=wx.EXPAND)
        labelSizer = wx.StaticBoxSizer(self.labelBox, wx.VERTICAL)
        gridSizer = wx.GridBagSizer(hgap=5, vgap=5)
        gridSizer.Add(StaticText(parent=self.panel, id=wx.ID_ANY,
                                 label=_("Label:")),
                      flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
        gridSizer.Add(self.label, pos=(0, 1), flag=wx.EXPAND)
        gridSizer.Add(StaticText(parent=self.panel, id=wx.ID_ANY,
                                 label=_("Comment:")),
                      flag=wx.ALIGN_CENTER_VERTICAL, pos=(1, 0))
        gridSizer.Add(self.comment, pos=(1, 1), flag=wx.EXPAND)
        gridSizer.AddGrowableRow(1)
        gridSizer.AddGrowableCol(1)
        labelSizer.Add(gridSizer, proportion=1, flag=wx.EXPAND)

        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(self.btnCancel)
        btnSizer.AddButton(self.btnOk)
        btnSizer.Realize()

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(self.search, proportion=0,
                      flag=wx.EXPAND | wx.ALL, border=3)
        mainSizer.Add(cmdSizer, proportion=1,
                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=3)
        mainSizer.Add(labelSizer, proportion=1,
                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP, border=3)
        mainSizer.Add(btnSizer, proportion=0,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)

        self.panel.SetSizer(mainSizer)
        mainSizer.Fit(self)

        self.Layout()

    def GetPanel(self):
        """Get dialog panel"""
        return self.panel

    def _getCmd(self):
        line = self.cmd_prompt.GetCurLine()[0].strip()
        if len(line) == 0:
            cmd = list()
        else:
            try:
                cmd = utils.split(str(line))
            except UnicodeError:
                cmd = utils.split(EncodeString((line)))
        return cmd

    def GetCmd(self):
        """Get command"""
        return self._command

    def GetLabel(self):
        """Get label and comment"""
        return self.label.GetValue(), self.comment.GetValue()

    def ValidateCmd(self, cmd):
        if len(cmd) < 1:
            GError(parent=self,
                   message=_("Command not defined.\n\n"
                             "Unable to add new action to the model."))
            return False

        if cmd[0] not in globalvar.grassCmd:
            GError(
                parent=self, message=_(
                    "'%s' is not a GRASS module.\n\n"
                    "Unable to add new action to the model.") %
                cmd[0])
            return False
        return True

    def OnCommand(self, cmd):
        """Command in prompt confirmed"""
        if self.ValidateCmd(cmd):
            self._command = cmd
            self.EndModal(wx.ID_OK)

    def OnOk(self, event):
        """Button 'OK' pressed"""
        cmd = self._getCmd()
        if self.ValidateCmd(cmd):
            self._command = cmd
            self.EndModal(wx.ID_OK)

    def OnCancel(self, event):
        """Cancel pressed, close window"""
        self.Hide()

    def Reset(self):
        """Reset dialog"""
        self.search.Reset()
        self.label.SetValue('')
        self.comment.SetValue('')
        self.cmd_prompt.OnCmdErase(None)
        self.cmd_prompt.SetFocus()
Esempio n. 9
0
class AddWSDialog(WSDialogBase):
    """Dialog for adding web service layer."""
    def __init__(
        self,
        parent,
        giface,
        id=wx.ID_ANY,
        style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
        **kwargs,
    ):

        WSDialogBase.__init__(
            self,
            parent,
            id=wx.ID_ANY,
            style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
            **kwargs,
        )

        self.SetTitle(_("Add web service layer"))

        self.parent = parent
        self.giface = giface
        self.btn_connect.SetDefault()

    def _createWidgets(self):

        WSDialogBase._createWidgets(self)

        self.btn_add = Button(parent=self, id=wx.ID_ANY, label=_("&Add layer"))
        self.btn_add.SetToolTip(
            _("Add selected web service layers as map layer into layer tree"))
        self.btn_add.Enable(False)

        self.run_btns.append(self.btn_add)

    def _doLayout(self):

        WSDialogBase._doLayout(self)

        self.btnsizer.Add(self.btn_add,
                          proportion=0,
                          flag=wx.ALL | wx.ALIGN_CENTER,
                          border=10)

        # bindings
        self.btn_add.Bind(wx.EVT_BUTTON, self.OnAddLayer)

    def UpdateDialogAfterConnection(self):
        """Connect to the server"""
        WSDialogBase.UpdateDialogAfterConnection(self)

        if self._getConnectedWS():
            self.btn_add.SetDefault()
        else:
            self.btn_connect.SetDefault()

    def OnAddLayer(self, event):
        """Add web service layer."""
        # add layer
        if self.active_ws_panel is None:
            return

        lcmd = self.active_ws_panel.CreateCmd()
        if not lcmd:
            return None

        # TODO: It is not clear how to do GetOptData in giface
        # knowing what GetOptData is doing might help
        # (maybe Get... is not the right name)
        # please fix giface if you know
        # tree -> giface
        # GetLayerTree -> GetLayerList
        # AddLayer -> AddLayer (but tree ones returns some layer,
        # giface ones nothing)
        # GetLayerInfo -> Layer object can by used instead
        # GetOptData -> unknown
        ltree = self.giface.GetLayerTree()

        active_ws = self.active_ws_panel.GetWebService()
        if "WMS" not in active_ws:
            cap_file = self.active_ws_panel.GetCapFile()
            cmd_cap_file = grass.tempfile()
            shutil.copyfile(cap_file, cmd_cap_file)
            lcmd.append("capfile=" + cmd_cap_file)

        layer = ltree.AddLayer(
            ltype="wms",
            lname=self.active_ws_panel.GetOutputLayerName(),
            lchecked=True,
            lcmd=lcmd,
        )

        ws_cap_files = self._getCapFiles()
        # create properties dialog
        cmd_list = ltree.GetLayerInfo(layer, "cmd")
        cmd = cmdlist_to_tuple(cmd_list)

        prop_win = WSPropertiesDialog(
            parent=self.parent,
            giface=self.giface,
            id=wx.ID_ANY,
            layer=layer,
            ws_cap_files=ws_cap_files,
            cmd=cmd,
        )

        prop_win.Hide()
        ltree.GetOptData(dcmd=None, layer=layer, params=None, propwin=prop_win)
Esempio n. 10
0
    def __init__(self,
                 parent,
                 title,
                 nselected,
                 style=wx.DEFAULT_DIALOG_STYLE):
        """Dialog used for Z bulk-labeling tool
        """
        wx.Dialog.__init__(self,
                           parent=parent,
                           id=wx.ID_ANY,
                           title=title,
                           style=style)

        self.parent = parent  # map window class instance

        # panel  = wx.Panel(parent=self, id=wx.ID_ANY)

        border = wx.BoxSizer(wx.VERTICAL)

        txt = StaticText(parent=self,
                         label=_("%d lines selected for z bulk-labeling") %
                         nselected)
        border.Add(txt, proportion=0, flag=wx.ALL | wx.EXPAND, border=5)

        box = StaticBox(parent=self,
                        id=wx.ID_ANY,
                        label=" %s " % _("Set value"))
        sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
        flexSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=5)
        flexSizer.AddGrowableCol(0)

        # starting value
        txt = StaticText(parent=self, label=_("Starting value"))
        self.value = SpinCtrl(parent=self,
                              id=wx.ID_ANY,
                              size=(150, -1),
                              initial=0,
                              min=-1e6,
                              max=1e6)
        flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
        flexSizer.Add(self.value,
                      proportion=0,
                      flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)

        # step
        txt = StaticText(parent=self, label=_("Step"))
        self.step = SpinCtrl(parent=self,
                             id=wx.ID_ANY,
                             size=(150, -1),
                             initial=0,
                             min=0,
                             max=1e6)
        flexSizer.Add(txt, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
        flexSizer.Add(self.step,
                      proportion=0,
                      flag=wx.ALIGN_CENTER | wx.FIXED_MINSIZE)

        sizer.Add(flexSizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=1)
        border.Add(sizer, proportion=1, flag=wx.ALL | wx.EXPAND, border=0)

        # buttons
        btnCancel = Button(self, wx.ID_CANCEL)
        btnOk = Button(self, wx.ID_OK)
        btnOk.SetDefault()

        # sizers
        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(btnCancel)
        btnSizer.AddButton(btnOk)
        btnSizer.Realize()

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(border, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
        mainSizer.Add(btnSizer,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
                      border=5)

        self.SetSizer(mainSizer)
        mainSizer.Fit(self)
Esempio n. 11
0
class EditItem(wx.Dialog):

    def __init__(
            self, parent, data, pointNo, itemCap="Point No.", id=wx.ID_ANY,
            title=_("Edit point"),
            style=wx.DEFAULT_DIALOG_STYLE):
        """Dialog for editing item cells in list"""

        wx.Dialog.__init__(self, parent, id, title=_(title), style=style)

        self.parent = parent
        panel = Panel(parent=self)
        sizer = wx.BoxSizer(wx.VERTICAL)

        box = StaticBox(parent=panel, id=wx.ID_ANY,
                        label=" %s %s " % (_(itemCap), str(pointNo + 1)))
        boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)

        # source coordinates
        gridSizer = wx.GridBagSizer(vgap=5, hgap=5)

        self.fields = []
        self.data = deepcopy(data)

        col = 0
        row = 0
        iField = 0
        for cell in self.data:

            # Select
            if type(cell[2]).__name__ == "list":
                self.fields.append(ComboBox(parent=panel, id=wx.ID_ANY,
                                            choices=cell[2],
                                            style=wx.CB_READONLY,
                                            size=(110, -1)))
            # Text field
            else:
                if cell[2] == float:
                    validator = FloatValidator()
                elif cell[2] == int:
                    validator = IntegerValidator()
                else:
                    validator = None

                if validator:
                    self.fields.append(
                        TextCtrl(
                            parent=panel, id=wx.ID_ANY, validator=validator,
                            size=(150, -1)))
                else:
                    self.fields.append(TextCtrl(parent=panel, id=wx.ID_ANY,
                                                size=(150, -1)))
                    value = cell[1]
                    if not isinstance(cell[1], basestring):
                        value = str(cell[1])
                    self.fields[iField].SetValue(value)

            label = StaticText(
                parent=panel,
                id=wx.ID_ANY,
                label=_(
                    parent.GetColumn(
                        cell[0]).GetText()) +
                ":")  # name of column)

            gridSizer.Add(label,
                          flag=wx.ALIGN_CENTER_VERTICAL,
                          pos=(row, col))

            col += 1

            gridSizer.Add(self.fields[iField],
                          pos=(row, col))

            if col % 3 == 0:
                col = 0
                row += 1
            else:
                col += 1

            iField += 1

        boxSizer.Add(gridSizer, proportion=1,
                     flag=wx.EXPAND | wx.ALL, border=5)

        sizer.Add(boxSizer, proportion=1,
                  flag=wx.EXPAND | wx.ALL, border=5)

        #
        # buttons
        #
        self.btnCancel = Button(panel, wx.ID_CANCEL)
        self.btnOk = Button(panel, wx.ID_OK)
        self.btnOk.SetDefault()

        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(self.btnCancel)
        btnSizer.AddButton(self.btnOk)
        btnSizer.Realize()

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

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

    def GetValues(self):
        """Return list of values (as strings).
        """

        iField = 0
        for cell in self.data:
            value = self.fields[iField].GetValue()

            if type(cell[2]).__name__ == "list":
                cell[1] = value
            else:
                try:
                    cell[1] = cell[2](value)
                except ValueError:
                    return []
            iField += 1

        return self.data

    def GetSelectionIndexes(self):
        """Return indexes of selected values (works just for choice
        columns).
        """
        iField = 0
        itemIndexes = []
        for cell in self.parent.colsData:
            if type(cell[2]).__name__ == "list":
                itemIndexes.append(self.fields[iField].GetSelection())
            else:
                itemIndexes.append(-1)  # not a choise column
            if cell[2]:
                iField += 1

        return itemIndexes
Esempio n. 12
0
class VectorCleaningFrame(wx.Frame):

    def __init__(
            self, parent, id=wx.ID_ANY,
        title=_('Set up vector cleaning tools'),
            style=wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER, **kwargs):
        """
        Dialog for interactively defining vector cleaning tools
        """
        wx.Frame.__init__(self, parent, id, title, style=style, **kwargs)

        self.parent = parent  # GMFrame
        if self.parent:
            self.log = self.parent.GetLogWindow()
        else:
            self.log = None

        # grass command
        self.cmd = 'v.clean'

        # statusbar
        self.CreateStatusBar()

        # icon
        self.SetIcon(
            wx.Icon(
                os.path.join(
                    globalvar.ICONDIR,
                    'grass.ico'),
                wx.BITMAP_TYPE_ICO))

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        # input map to clean
        self.inmap = ''

        # cleaned output map
        self.outmap = ''

        self.ftype = ''

        # cleaning tools
        self.toolslines = {}

        self.tool_desc_list = [
            _('break lines/boundaries'),
            _('remove duplicates'),
            _('remove dangles'),
            _('change boundary dangles to lines'),
            _('remove bridges'),
            _('change bridges to lines'),
            _('snap lines/boundaries'),
            _('remove duplicate area centroids'),
            _('break polygons'),
            _('prune lines/boundaries'),
            _('remove small areas'),
            _('remove lines/boundaries of zero length'),
            _('remove small angles at nodes')
        ]

        self.tool_list = [
            'break',
            'rmdupl',
            'rmdangle',
            'chdangle',
            'rmbridge',
            'chbridge',
            'snap',
            'rmdac',
            'bpol',
            'prune',
            'rmarea',
            'rmline',
            'rmsa'
        ]

        self.ftype = [
            'point',
            'line',
            'boundary',
            'centroid',
            'area',
            'face']

        self.n_ftypes = len(self.ftype)

        self.tools_string = ''
        self.thresh_string = ''
        self.ftype_string = ''

        self.SetStatusText(_("Set up vector cleaning tools"))
        self.elem = 'vector'
        self.ctlabel = _('Choose cleaning tools and set thresholds')

        # top controls
        self.inmaplabel = StaticText(parent=self.panel, id=wx.ID_ANY,
                                     label=_('Select input vector map:'))
        self.selectionInput = Select(parent=self.panel, id=wx.ID_ANY,
                                     size=globalvar.DIALOG_GSELECT_SIZE,
                                     type='vector')
        self.ftype_check = {}
        ftypeBox = StaticBox(parent=self.panel, id=wx.ID_ANY,
                             label=_(' Feature type: '))
        self.ftypeSizer = wx.StaticBoxSizer(ftypeBox, wx.HORIZONTAL)

        self.outmaplabel = StaticText(parent=self.panel, id=wx.ID_ANY,
                                      label=_('Select output vector map:'))
        self.selectionOutput = Select(parent=self.panel, id=wx.ID_ANY,
                                      size=globalvar.DIALOG_GSELECT_SIZE,
                                      mapsets=[grass.gisenv()['MAPSET'], ],
                                      fullyQualified=False,
                                      type='vector')

        self.overwrite = wx.CheckBox(
            parent=self.panel, id=wx.ID_ANY,
            label=_('Allow output files to overwrite existing files'))
        self.overwrite.SetValue(
            UserSettings.Get(
                group='cmd',
                key='overwrite',
                subkey='enabled'))

        # cleaning tools
        self.ct_label = StaticText(parent=self.panel, id=wx.ID_ANY,
                                   label=self.ctlabel)

        self.ct_panel = self._toolsPanel()

        # buttons to manage cleaning tools
        self.btn_add = Button(parent=self.panel, id=wx.ID_ADD)
        self.btn_remove = Button(parent=self.panel, id=wx.ID_REMOVE)
        self.btn_moveup = Button(parent=self.panel, id=wx.ID_UP)
        self.btn_movedown = Button(parent=self.panel, id=wx.ID_DOWN)

        # add one tool as default
        self.AddTool()
        self.selected = -1

        # Buttons
        self.btn_close = Button(parent=self.panel, id=wx.ID_CLOSE)
        self.btn_run = Button(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_("&Run"))
        self.btn_run.SetDefault()
        self.btn_clipboard = Button(parent=self.panel, id=wx.ID_COPY)
        self.btn_clipboard.SetToolTip(
            _("Copy the current command string to the clipboard (Ctrl+C)"))
        self.btn_help = Button(parent=self.panel, id=wx.ID_HELP)

        # bindings
        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
        self.btn_run.Bind(wx.EVT_BUTTON, self.OnCleaningRun)
        self.btn_clipboard.Bind(wx.EVT_BUTTON, self.OnCopy)
        self.btn_help.Bind(wx.EVT_BUTTON, self.OnHelp)

        self.btn_add.Bind(wx.EVT_BUTTON, self.OnAddTool)
        self.btn_remove.Bind(wx.EVT_BUTTON, self.OnClearTool)
        self.btn_moveup.Bind(wx.EVT_BUTTON, self.OnMoveToolUp)
        self.btn_movedown.Bind(wx.EVT_BUTTON, self.OnMoveToolDown)

        # layout
        self._layout()

        self.SetMinSize(self.GetBestSize())

        self.CentreOnScreen()

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

        #
        # input output
        #
        inSizer = wx.GridBagSizer(hgap=5, vgap=5)

        inSizer.Add(
            self.inmaplabel,
            pos=(
                0,
                0),
            flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND,
            border=1)
        inSizer.Add(
            self.selectionInput,
            pos=(
                1,
                0),
            flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND,
            border=1)

        self.ftype_check = [
            wx.CheckBox(parent=self.panel, id=wx.ID_ANY, label=_('point')),
            wx.CheckBox(parent=self.panel, id=wx.ID_ANY, label=_('line')),
            wx.CheckBox(parent=self.panel, id=wx.ID_ANY, label=_('boundary')),
            wx.CheckBox(parent=self.panel, id=wx.ID_ANY, label=_('centroid')),
            wx.CheckBox(parent=self.panel, id=wx.ID_ANY, label=_('area')),
            wx.CheckBox(parent=self.panel, id=wx.ID_ANY, label=_('face'))
        ]

        typeoptSizer = wx.BoxSizer(wx.HORIZONTAL)
        for num in range(0, self.n_ftypes):
            type_box = self.ftype_check[num]
            if self.ftype[num] in ('point', 'line', 'area'):
                type_box.SetValue(True)
            typeoptSizer.Add(type_box, flag=wx.ALIGN_LEFT, border=1)

        self.ftypeSizer.Add(typeoptSizer,
                            flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=2)

        outSizer = wx.GridBagSizer(hgap=5, vgap=5)

        outSizer.Add(
            self.outmaplabel,
            pos=(
                0,
                0),
            flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND,
            border=1)
        outSizer.Add(
            self.selectionOutput,
            pos=(
                1,
                0),
            flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL | wx.EXPAND,
            border=1)
        replaceSizer = wx.BoxSizer(wx.HORIZONTAL)
        replaceSizer.Add(self.overwrite, proportion=1,
                         flag=wx.ALL | wx.EXPAND, border=1)

        outSizer.Add(replaceSizer, pos=(2, 0),
                     flag=wx.ALL | wx.EXPAND, border=1)

        #
        # tools selection
        #
        bodySizer = wx.GridBagSizer(hgap=5, vgap=5)

        bodySizer.Add(self.ct_label, pos=(0, 0), span=(1, 2),
                      flag=wx.ALL, border=5)

        bodySizer.Add(self.ct_panel, pos=(1, 0), span=(1, 2))

        manageBoxSizer = wx.GridBagSizer(hgap=10, vgap=1)
        # start with row 1 for nicer layout
        manageBoxSizer.Add(
            self.btn_add, pos=(1, 0),
            border=2, flag=wx.ALL | wx.EXPAND)
        manageBoxSizer.Add(
            self.btn_remove, pos=(2, 0),
            border=2, flag=wx.ALL | wx.EXPAND)
        manageBoxSizer.Add(
            self.btn_moveup, pos=(3, 0),
            border=2, flag=wx.ALL | wx.EXPAND)
        manageBoxSizer.Add(
            self.btn_movedown, pos=(4, 0),
            border=2, flag=wx.ALL | wx.EXPAND)

        bodySizer.Add(manageBoxSizer, pos=(1, 2),
                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5)

        bodySizer.AddGrowableCol(2)

        #
        # standard buttons
        #
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(self.btn_close,
                     flag=wx.LEFT | wx.RIGHT, border=5)
        btnSizer.Add(self.btn_run,
                     flag=wx.LEFT | wx.RIGHT, border=5)
        btnSizer.Add(self.btn_clipboard,
                     flag=wx.LEFT | wx.RIGHT, border=5)
        btnSizer.Add(self.btn_help,
                     flag=wx.LEFT | wx.RIGHT, border=5)

        #
        # put it all together
        #
        sizer.Add(inSizer, proportion=0,
                  flag=wx.ALL | wx.EXPAND, border=5)

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

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

        sizer.Add(wx.StaticLine(parent=self, id=wx.ID_ANY,
                                style=wx.LI_HORIZONTAL), proportion=0,
                  flag=wx.EXPAND | wx.ALL, border=5)

        sizer.Add(bodySizer, proportion=1,
                  flag=wx.ALL | wx.EXPAND, border=5)

        sizer.Add(wx.StaticLine(parent=self, id=wx.ID_ANY,
                                style=wx.LI_HORIZONTAL), proportion=0,
                  flag=wx.EXPAND | wx.ALL, border=5)

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

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

        self.Layout()

    def _toolsPanel(self):
        ct_panel = scrolled.ScrolledPanel(parent=self.panel, id=wx.ID_ANY,
                                          size=(500, 240),
                                          style=wx.SUNKEN_BORDER)

        self.ct_sizer = wx.GridBagSizer(vgap=2, hgap=4)

        ct_panel.SetSizer(self.ct_sizer)
        ct_panel.SetAutoLayout(True)

        return ct_panel

    def OnAddTool(self, event):
        """Add tool button pressed"""
        self.AddTool()

    def AddTool(self):
        snum = len(self.toolslines.keys())
        num = snum + 1
        # tool
        tool_cbox = wx.ComboBox(parent=self.ct_panel, id=1000 + num,
                                size=(300, -1), choices=self.tool_desc_list,
                                style=wx.CB_DROPDOWN |
                                wx.CB_READONLY | wx.TE_PROCESS_ENTER)
        self.Bind(wx.EVT_COMBOBOX, self.OnSetTool, tool_cbox)
        # threshold
        txt_ctrl = TextCtrl(
            parent=self.ct_panel, id=2000 + num, value='0.00', size=(100, -1),
            style=wx.TE_NOHIDESEL)
        self.Bind(wx.EVT_TEXT, self.OnThreshValue, txt_ctrl)

        # select with tool number
        select = wx.CheckBox(
            parent=self.ct_panel,
            id=num,
            label=str(num) + '.')
        select.SetValue(False)
        self.Bind(wx.EVT_CHECKBOX, self.OnSelect, select)

        # start with row 1 and col 1 for nicer layout
        self.ct_sizer.Add(select, pos=(num, 1),
                          flag=wx.ALIGN_CENTER | wx.RIGHT)
        self.ct_sizer.Add(tool_cbox, pos=(num, 2),
                          flag=wx.ALIGN_CENTER | wx.RIGHT, border=5)
        self.ct_sizer.Add(txt_ctrl, pos=(num, 3),
                          flag=wx.ALIGN_CENTER | wx.RIGHT, border=5)

        self.toolslines[num] = {'tool_desc': '',
                                'tool': '',
                                'thresh': '0.00'}

        self.ct_panel.Layout()
        self.ct_panel.SetupScrolling()

    def OnClearTool(self, event):
        """Remove tool button pressed"""
        id = self.selected

        if id > 0:
            self.FindWindowById(id + 1000).SetValue('')
            self.toolslines[id]['tool_desc'] = ''
            self.toolslines[id]['tool'] = ''
            self.SetStatusText(
                _("%s. cleaning tool removed, will be ignored") %
                id)
        else:
            self.SetStatusText(_("Please select a cleaning tool to remove"))

    def OnMoveToolUp(self, event):
        """Move up tool button pressed"""
        id = self.selected

        if id > 1:
            id_up = id - 1
            this_toolline = self.toolslines[id]
            up_toolline = self.toolslines[id_up]

            self.FindWindowById(id_up).SetValue(True)
            self.FindWindowById(
                id_up +
                1000).SetValue(
                this_toolline['tool_desc'])
            self.FindWindowById(id_up + 2000).SetValue(this_toolline['thresh'])
            self.toolslines[id_up] = this_toolline

            self.FindWindowById(id).SetValue(False)
            self.FindWindowById(id + 1000).SetValue(up_toolline['tool_desc'])
            self.FindWindowById(id + 2000).SetValue(up_toolline['thresh'])
            self.toolslines[id] = up_toolline
            self.selected = id_up
            self.SetStatusText(_("%s. cleaning tool moved up") % id)
        elif id == 1:
            self.SetStatusText(_("1. cleaning tool can not be moved up "))
        elif id == -1:
            self.SetStatusText(_("Please select a cleaning tool to move up"))

    def OnMoveToolDown(self, event):
        """Move down tool button pressed"""
        id = self.selected
        snum = len(self.toolslines.keys())

        if id > 0 and id < snum:
            id_down = id + 1
            this_toolline = self.toolslines[id]
            down_toolline = self.toolslines[id_down]

            self.FindWindowById(id_down).SetValue(True)
            self.FindWindowById(
                id_down +
                1000).SetValue(
                this_toolline['tool_desc'])
            self.FindWindowById(
                id_down +
                2000).SetValue(
                this_toolline['thresh'])
            self.toolslines[id_down] = this_toolline

            self.FindWindowById(id).SetValue(False)
            self.FindWindowById(id + 1000).SetValue(down_toolline['tool_desc'])
            self.FindWindowById(id + 2000).SetValue(down_toolline['thresh'])
            self.toolslines[id] = down_toolline
            self.selected = id_down
            self.SetStatusText(_("%s. cleaning tool moved down") % id)
        elif id == snum:
            self.SetStatusText(_("Last cleaning tool can not be moved down "))
        elif id == -1:
            self.SetStatusText(_("Please select a cleaning tool to move down"))

    def OnSetTool(self, event):
        """Tool was defined"""
        id = event.GetId()
        tool_no = id - 1000
        num = self.FindWindowById(id).GetCurrentSelection()

        self.toolslines[tool_no]['tool_desc'] = self.tool_desc_list[num]
        self.toolslines[tool_no]['tool'] = self.tool_list[num]

        self.SetStatusText(
            str(tool_no) +
            '. ' +
            _("cleaning tool: '%s'") %
            (self.tool_list[num]))

    def OnThreshValue(self, event):
        """Threshold value was entered"""
        id = event.GetId()
        num = id - 2000
        self.toolslines[num]['thresh'] = self.FindWindowById(id).GetValue()

        self.SetStatusText(
            _("Threshold for %(num)s. tool '%(tool)s': %(thresh)s") % {
                'num': num,
                'tool': self.toolslines[num]['tool'],
                'thresh': self.toolslines[num]['thresh']})

    def OnSelect(self, event):
        """Tool was selected"""
        id = event.GetId()

        if self.selected > -1 and self.selected != id:
            win = self.FindWindowById(self.selected)
            win.SetValue(False)

        if self.selected != id:
            self.selected = id
        else:
            self.selected = -1

    def OnDone(self, event):
        """Command done"""
        self.SetStatusText('')

    def OnCleaningRun(self, event):
        """Builds options and runs v.clean
        """
        self.GetCmdStrings()

        err = list()
        for p, name in ((self.inmap, _('Name of input vector map')),
                        (self.outmap, _('Name for output vector map')),
                        (self.tools_string, _('Tools')),
                        (self.thresh_string, _('Threshold'))):
            if not p:
                err.append(_("'%s' not defined") % name)
        if err:
            GError(_("Some parameters not defined. Operation "
                     "canceled.\n\n%s") % '\n'.join(err),
                   parent=self)
            return

        self.SetStatusText(_("Executing selected cleaning operations..."))
        snum = len(self.toolslines.keys())

        if self.log:
            cmd = [self.cmd,
                   'input=%s' % self.inmap,
                   'output=%s' % self.outmap,
                   'tool=%s' % self.tools_string,
                   'thres=%s' % self.thresh_string]
            if self.ftype_string:
                cmd.append('type=%s' % self.ftype_string)
            if self.overwrite.IsChecked():
                cmd.append('--overwrite')

            self.log.RunCmd(cmd, onDone=self.OnDone)
            self.parent.Raise()
        else:
            if self.overwrite.IsChecked():
                overwrite = True
            else:
                overwrite = False

            RunCommand(self.cmd,
                       input=self.inmap,
                       output=self.outmap,
                       type=self.ftype_string,
                       tool=self.tools_string,
                       thresh=self.thresh_string,
                       overwrite=overwrite)

    def OnClose(self, event):
        self.Destroy()

    def OnHelp(self, event):
        """Show GRASS manual page"""
        RunCommand('g.manual',
                   quiet=True,
                   parent=self,
                   entry=self.cmd)

    def OnCopy(self, event):
        """Copy the command"""
        cmddata = wx.TextDataObject()
        # get tool and thresh strings
        self.GetCmdStrings()
        cmdstring = '%s' % (self.cmd)
        # list -> string
        cmdstring += ' input=%s output=%s type=%s tool=%s thres=%s' % (
            self.inmap, self.outmap, self.ftype_string, self.tools_string, self.thresh_string)
        if self.overwrite.IsChecked():
            cmdstring += ' --overwrite'

        cmddata.SetText(cmdstring)
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(cmddata)
            wx.TheClipboard.Close()
            self.SetStatusText(
                _("Vector cleaning command copied to clipboard"))

    def GetCmdStrings(self):
        self.tools_string = ''
        self.thresh_string = ''
        self.ftype_string = ''
        # feature types
        first = 1
        for num in range(0, self.n_ftypes - 1):
            if self.ftype_check[num].IsChecked():
                if first:
                    self.ftype_string = '%s' % self.ftype[num]
                    first = 0
                else:
                    self.ftype_string += ',%s' % self.ftype[num]

        # cleaning tools
        first = 1
        snum = len(self.toolslines.keys())
        for num in range(1, snum + 1):
            if self.toolslines[num]['tool']:
                if first:
                    self.tools_string = '%s' % self.toolslines[num]['tool']
                    self.thresh_string = '%s' % self.toolslines[num]['thresh']
                    first = 0
                else:
                    self.tools_string += ',%s' % self.toolslines[num]['tool']
                    self.thresh_string += ',%s' % self.toolslines[
                        num]['thresh']

        self.inmap = self.selectionInput.GetValue()
        self.outmap = self.selectionOutput.GetValue()
Esempio n. 13
0
class GdalOutputDialog(wx.Dialog):
    def __init__(self,
                 parent,
                 id=wx.ID_ANY,
                 ogr=False,
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
                 *kwargs):
        """Dialog for setting output format for rasters/vectors

        .. todo::
            Split into GdalOutputDialog and OgrOutputDialog

        :param parent: parent window
        :param id: window id
        :param ogr: True for OGR (vector) otherwise GDAL (raster)
        :param style: window style
        :param *kwargs: other wx.Dialog's arguments
        """
        self.parent = parent  # GMFrame
        self.ogr = ogr
        wx.Dialog.__init__(self, parent, id=id, style=style, *kwargs)
        if self.ogr:
            self.SetTitle(_("Define output format for vector data"))
        else:
            self.SetTitle(_("Define output format for raster data"))

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        # buttons
        self.btnCancel = Button(parent=self.panel, id=wx.ID_CANCEL)
        self.btnCancel.SetToolTip(_("Close dialog"))
        self.btnOk = Button(parent=self.panel, id=wx.ID_OK)
        self.btnOk.SetToolTip(_("Set external format and close dialog"))
        self.btnOk.SetDefault()

        self.dsnInput = GdalSelect(parent=self,
                                   panel=self.panel,
                                   ogr=ogr,
                                   exclude=['file', 'protocol'],
                                   dest=True)
        self.dsnInput.AttachSettings()

        self.Bind(wx.EVT_BUTTON, self.OnCancel, self.btnCancel)
        self.Bind(wx.EVT_BUTTON, self.OnOK, self.btnOk)

        self._layout()

    def _layout(self):
        dialogSizer = wx.BoxSizer(wx.VERTICAL)

        dialogSizer.Add(self.dsnInput, proportion=1, flag=wx.EXPAND)

        btnSizer = wx.BoxSizer(orient=wx.HORIZONTAL)
        btnSizer.Add(self.btnCancel,
                     proportion=0,
                     flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER,
                     border=10)
        btnSizer.Add(self.btnOk,
                     proportion=0,
                     flag=wx.RIGHT | wx.ALIGN_CENTER,
                     border=10)

        dialogSizer.Add(btnSizer,
                        proportion=0,
                        flag=wx.BOTTOM | wx.TOP | wx.ALIGN_RIGHT,
                        border=10)

        self.panel.SetAutoLayout(True)
        self.panel.SetSizer(dialogSizer)
        dialogSizer.Fit(self.panel)

        size = wx.Size(globalvar.DIALOG_GSELECT_SIZE[0] + 320,
                       self.GetBestSize()[1] + 35)
        self.SetMinSize(size)
        self.SetSize((size.width, size.height))
        self.Layout()

    def OnCancel(self, event):
        self.Destroy()

    def OnOK(self, event):
        if self.dsnInput.GetType() == 'native':
            RunCommand('v.external.out', parent=self, flags='r')
        else:
            dsn = self.dsnInput.GetDsn()
            frmt = self.dsnInput.GetFormat()
            options = self.dsnInput.GetOptions()
            if not dsn:
                GMessage(_("No data source selected."), parent=self)
                return

            RunCommand('v.external.out',
                       parent=self,
                       output=dsn,
                       format=frmt,
                       options=options)
        self.Close()
Esempio n. 14
0
class ImportDialog(wx.Dialog):
    """Dialog for bulk import of various data (base class)"""
    def __init__(self,
                 parent,
                 giface,
                 itype,
                 id=wx.ID_ANY,
                 title=_("Multiple import"),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
        self.parent = parent  # GMFrame
        self._giface = giface  # used to add layers
        self.importType = itype
        self.options = dict()  # list of options
        self.options_par = dict()

        self.commandId = -1  # id of running command

        wx.Dialog.__init__(self,
                           parent,
                           id,
                           title,
                           style=style,
                           name="MultiImportDialog")

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        self.layerBox = StaticBox(parent=self.panel, id=wx.ID_ANY)
        if self.importType == 'gdal':
            label = _("List of raster layers")
        elif self.importType == 'ogr':
            label = _("List of vector layers")
        else:
            label = _("List of %s layers") % self.importType.upper()
        self.layerBox.SetLabel(" %s - %s " %
                               (label, _("right click to (un)select all")))

        # list of layers
        columns = [
            _('Layer id'),
            _('Layer name'),
            _('Name for output GRASS map (editable)')
        ]
        if itype == 'ogr':
            columns.insert(2, _('Feature type'))
            columns.insert(3, _('Projection match'))
        elif itype == 'gdal':
            columns.insert(2, _('Projection match'))

        self.list = LayersList(parent=self.panel, columns=columns)
        self.list.LoadData()

        self.override = wx.CheckBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_(
                "Override projection check (use current location's projection)"
            ))

        self.overwrite = wx.CheckBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_("Allow output files to overwrite existing files"))
        self.overwrite.SetValue(
            UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))
        self.overwrite.Bind(wx.EVT_CHECKBOX, self.OnCheckOverwrite)
        if UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'):
            self.list.validate = False

        self.add = wx.CheckBox(parent=self.panel, id=wx.ID_ANY)
        self.closeOnFinish = wx.CheckBox(parent=self.panel,
                                         id=wx.ID_ANY,
                                         label=_("Close dialog on finish"))
        self.closeOnFinish.SetValue(
            UserSettings.Get(group='cmd', key='closeDlg', subkey='enabled'))

        #
        # buttons
        #
        # cancel
        self.btn_close = CloseButton(parent=self.panel)
        self.btn_close.SetToolTip(_("Close dialog"))
        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
        # run
        self.btn_run = Button(parent=self.panel,
                              id=wx.ID_OK,
                              label=_("&Import"))
        self.btn_run.SetToolTip(_("Import selected layers"))
        self.btn_run.SetDefault()
        self.btn_run.Bind(wx.EVT_BUTTON, self.OnRun)

        self.Bind(wx.EVT_CLOSE, lambda evt: self.Destroy())

        self.notebook = GNotebook(parent=self, style=globalvar.FNPageDStyle)

        self.notebook.AddPage(page=self.panel,
                              text=_('Source settings'),
                              name='source')

        self.createSettingsPage()

    def createSettingsPage(self):

        self._blackList = {
            'enabled': True,
            'items': {
                self._getCommand(): {
                    'params': self._getBlackListedParameters(),
                    'flags': self._getBlackListedFlags()
                }
            }
        }

        grass_task = gtask.parse_interface(self._getCommand(),
                                           blackList=self._blackList)

        self.advancedPagePanel = CmdPanel(parent=self,
                                          giface=None,
                                          task=grass_task,
                                          frame=None)

        self.notebook.AddPage(page=self.advancedPagePanel,
                              text=_('Import settings'),
                              name='settings')

    def doLayout(self):
        """Do layout"""
        dialogSizer = wx.BoxSizer(wx.VERTICAL)

        # dsn input
        dialogSizer.Add(self.dsnInput, proportion=0, flag=wx.EXPAND)

        #
        # list of DXF layers
        #
        layerSizer = wx.StaticBoxSizer(self.layerBox, wx.HORIZONTAL)

        layerSizer.Add(self.list,
                       proportion=1,
                       flag=wx.ALL | wx.EXPAND,
                       border=5)

        dialogSizer.Add(layerSizer,
                        proportion=1,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
                        border=5)

        dialogSizer.Add(self.override,
                        proportion=0,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                        border=5)

        dialogSizer.Add(self.overwrite,
                        proportion=0,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                        border=5)

        dialogSizer.Add(self.add,
                        proportion=0,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                        border=5)

        dialogSizer.Add(self.closeOnFinish,
                        proportion=0,
                        flag=wx.LEFT | wx.RIGHT | wx.BOTTOM,
                        border=5)
        #
        # buttons
        #
        btnsizer = wx.BoxSizer(orient=wx.HORIZONTAL)

        btnsizer.Add(self.btn_close,
                     proportion=0,
                     flag=wx.LEFT | wx.RIGHT | wx.ALIGN_CENTER,
                     border=10)

        btnsizer.Add(self.btn_run,
                     proportion=0,
                     flag=wx.RIGHT | wx.ALIGN_CENTER,
                     border=10)

        dialogSizer.Add(btnsizer,
                        proportion=0,
                        flag=wx.BOTTOM | wx.ALIGN_RIGHT,
                        border=10)

        # dialogSizer.SetSizeHints(self.panel)
        self.panel.SetAutoLayout(True)
        self.panel.SetSizer(dialogSizer)
        dialogSizer.Fit(self.panel)

        # auto-layout seems not work here - FIXME
        size = wx.Size(globalvar.DIALOG_GSELECT_SIZE[0] + 322, 550)
        self.SetMinSize(size)
        self.SetSize((size.width, size.height + 100))
        # width = self.GetSize()[0]
        # self.list.SetColumnWidth(col = 1, width = width / 2 - 50)
        self.Layout()

    def _getCommand(self):
        """Get command"""
        raise NotImplementedError()

    def _getBlackListedParameters(self):
        """Get parameters which will not be showed in Settings page"""
        raise NotImplementedError()

    def _getBlackListedFlags(self):
        """Get flags which will not be showed in Settings page"""
        raise NotImplementedError()

    def _nameValidationFailed(self, layers_list):
        """Output map name validation callback

        :param layers_list: LayersList class instance
        """
        if isinstance(layers_list.output_map, list):
            maps = ['<{}>'.format(m) for m in layers_list.output_map]
            message = _("Output map names %(names)s exist. ") % {
                'names': ', '.join(maps)
            }
        else:
            message = _("Output map name <%(name)s> exist. ") % {
                'name': layers_list.output_map
            }
        GError(parent=self, message=message, caption=_("Invalid name"))

    def _validateOutputMapName(self):
        """Enable/disable output map name validation according the
        overwrite state"""
        if not self.overwrite.IsChecked():
            if not self.list.GetValidator().\
               Validate(win=self.list, validate_all=True):
                return False
        return True

    def OnClose(self, event=None):
        """Close dialog"""
        self.Close()

    def OnRun(self, event):
        """Import/Link data (each layes as separate vector map)"""
        pass

    def OnCheckOverwrite(self, event):
        """Check/uncheck overwrite checkbox widget"""
        if self.overwrite.IsChecked():
            self.list.validate = False
        else:
            self.list.validate = True

    def AddLayers(self, returncode, cmd=None, userData=None):
        """Add imported/linked layers into layer tree"""
        if not self.add.IsChecked() or returncode != 0:
            return

        # TODO: if importing map creates more map the following does not work
        # * do nothing if map does not exist or
        # * try to determine names using regexp or
        # * persuade import tools to report map names
        self.commandId += 1
        layer, output = self.list.GetLayers()[self.commandId][:2]

        if '@' not in output:
            name = output + '@' + grass.gisenv()['MAPSET']
        else:
            name = output

        # add imported layers into layer tree
        # an alternative would be emit signal (mapCreated) and (optionally)
        # connect to this signal
        llist = self._giface.GetLayerList()
        if self.importType == 'gdal':
            if userData:
                nBands = int(userData.get('nbands', 1))
            else:
                nBands = 1

            if UserSettings.Get(group='rasterLayer',
                                key='opaque',
                                subkey='enabled'):
                nFlag = True
            else:
                nFlag = False

            for i in range(1, nBands + 1):
                nameOrig = name
                if nBands > 1:
                    mapName, mapsetName = name.split('@')
                    mapName += '.%d' % i
                    name = mapName + '@' + mapsetName

                cmd = ['d.rast', 'map=%s' % name]
                if nFlag:
                    cmd.append('-n')

                llist.AddLayer(ltype='raster',
                               name=name,
                               checked=True,
                               cmd=cmd)
                name = nameOrig
        else:
            llist.AddLayer(ltype='vector',
                           name=name,
                           checked=True,
                           cmd=['d.vect', 'map=%s' % name] +
                           GetDisplayVectSettings())

        self._giface.GetMapWindow().ZoomToMap()

    def OnAbort(self, event):
        """Abort running import

        .. todo::
            not yet implemented
        """
        pass

    def OnCmdDone(self, event):
        """Do what has to be done after importing"""
        pass

    def _getLayersToReprojetion(self, projMatch_idx, grassName_idx):
        """If there are layers with different projection from loation projection,
           show dialog to user to explicitly select layers which will be reprojected..."""
        differentProjLayers = []
        data = self.list.GetData(checked=True)

        for itm in data:

            layerId = itm[-1]

            # select only layers with different projetion
            if self.layersData[layerId][projMatch_idx] == 0:
                dt = [itm[0], itm[grassName_idx]]
                differentProjLayers.append(tuple(dt))

        layers = self.list.GetLayers()

        if not self.link and \
           differentProjLayers and \
           not self.override.IsChecked(): # '-o' not in self.getSettingsPageCmd():

            dlg = ReprojectionDialog(parent=self,
                                     giface=self._giface,
                                     data=differentProjLayers)

            ret = dlg.ShowModal()

            if ret == wx.ID_OK:

                # do not import unchecked layers
                for itm in reversed(list(dlg.GetData(checked=False))):
                    idx = itm[-1]
                    layers.pop(idx)
            else:
                return None

        return layers

    def getSettingsPageCmd(self):

        return self.advancedPagePanel.createCmd(ignoreErrors=True,
                                                ignoreRequired=True)
Esempio n. 15
0
class PropertiesDialog(wx.Dialog):
    """Model properties dialog
    """

    def __init__(self, parent, id=wx.ID_ANY,
                 title=_('Model properties'),
                 size=(350, 400),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
        wx.Dialog.__init__(self, parent, id, title, size=size,
                           style=style)

        self.metaBox = StaticBox(parent=self, id=wx.ID_ANY,
                                 label=" %s " % _("Metadata"))
        self.cmdBox = StaticBox(parent=self, id=wx.ID_ANY,
                                label=" %s " % _("Commands"))

        self.name = TextCtrl(parent=self, id=wx.ID_ANY,
                             size=(300, 25))
        self.desc = TextCtrl(parent=self, id=wx.ID_ANY,
                             style=wx.TE_MULTILINE,
                             size=(300, 50))
        self.author = TextCtrl(parent=self, id=wx.ID_ANY,
                               size=(300, 25))

        # commands
        self.overwrite = wx.CheckBox(parent=self, id=wx.ID_ANY, label=_(
            "Allow output files to overwrite existing files"))
        self.overwrite.SetValue(
            UserSettings.Get(
                group='cmd',
                key='overwrite',
                subkey='enabled'))

        # buttons
        self.btnOk = Button(self, wx.ID_OK)
        self.btnCancel = Button(self, wx.ID_CANCEL)
        self.btnOk.SetDefault()

        self.btnOk.SetToolTip(_("Apply properties"))
        self.btnOk.SetDefault()
        self.btnCancel.SetToolTip(_("Close dialog and ignore changes"))

        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

        self._layout()

    def _layout(self):
        metaSizer = wx.StaticBoxSizer(self.metaBox, wx.VERTICAL)
        gridSizer = wx.GridBagSizer(hgap=3, vgap=3)
        gridSizer.Add(StaticText(parent=self, id=wx.ID_ANY,
                                 label=_("Name:")),
                      flag=wx.ALIGN_LEFT |
                      wx.ALIGN_CENTER_VERTICAL,
                      pos=(0, 0))
        gridSizer.Add(self.name,
                      flag=wx.ALIGN_LEFT |
                      wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
                      pos=(0, 1))
        gridSizer.Add(StaticText(parent=self, id=wx.ID_ANY,
                                 label=_("Description:")),
                      flag=wx.ALIGN_LEFT |
                      wx.ALIGN_CENTER_VERTICAL,
                      pos=(1, 0))
        gridSizer.Add(self.desc,
                      flag=wx.ALIGN_LEFT |
                      wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
                      pos=(1, 1))
        gridSizer.Add(StaticText(parent=self, id=wx.ID_ANY,
                                 label=_("Author(s):")),
                      flag=wx.ALIGN_LEFT |
                      wx.ALIGN_CENTER_VERTICAL,
                      pos=(2, 0))
        gridSizer.Add(self.author,
                      flag=wx.ALIGN_LEFT |
                      wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
                      pos=(2, 1))
        gridSizer.AddGrowableCol(1)
        gridSizer.AddGrowableRow(1)
        metaSizer.Add(gridSizer, proportion=1, flag=wx.EXPAND)

        cmdSizer = wx.StaticBoxSizer(self.cmdBox, wx.VERTICAL)
        cmdSizer.Add(self.overwrite,
                     flag=wx.EXPAND | wx.ALL, border=3)

        btnStdSizer = wx.StdDialogButtonSizer()
        btnStdSizer.AddButton(self.btnCancel)
        btnStdSizer.AddButton(self.btnOk)
        btnStdSizer.Realize()

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(metaSizer, proportion=1,
                      flag=wx.EXPAND | wx.ALL, border=5)
        mainSizer.Add(
            cmdSizer,
            proportion=0,
            flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
            border=5)
        mainSizer.Add(btnStdSizer, proportion=0,
                      flag=wx.EXPAND | wx.ALL, border=5)

        self.SetSizer(mainSizer)
        mainSizer.Fit(self)

    def OnCloseWindow(self, event):
        self.Hide()

    def GetValues(self):
        """Get values"""
        return {'name': self.name.GetValue(),
                'description': self.desc.GetValue(),
                'author': self.author.GetValue(),
                'overwrite': self.overwrite.IsChecked()}

    def Init(self, prop):
        """Initialize dialog"""
        self.name.SetValue(prop['name'])
        self.desc.SetValue(prop['description'])
        self.author.SetValue(prop['author'])
        if 'overwrite' in prop:
            self.overwrite.SetValue(prop['overwrite'])
Esempio n. 16
0
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()
Esempio n. 17
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)
Esempio n. 18
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.InitTreeItems()
        self.tree.ExpandCurrentMapset()
        self.tree.changeMapset.connect(
            lambda mapset: self.ChangeLocationMapset(location=None,
                                                     mapset=mapset))
        self.tree.changeLocation.connect(
            lambda mapset, location: self.ChangeLocationMapset(
                location=location, mapset=mapset))

        # 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.ALIGN_RIGHT | 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()
        self.tree.ExpandCurrentMapset()

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

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

    def ChangeLocationMapset(self, mapset, location=None):
        """Change mapset or location"""
        if location:
            if RunCommand('g.mapset',
                          parent=self,
                          location=location,
                          mapset=mapset) == 0:
                GMessage(parent=self,
                         message=_("Current location is <%(loc)s>.\n"
                                   "Current mapset is <%(mapset)s>.") % {
                                       'loc': location,
                                       'mapset': mapset
                                   })
        else:
            if RunCommand('g.mapset', parent=self, mapset=mapset) == 0:
                GMessage(parent=self,
                         message=_("Current mapset is <%s>.") % mapset)

    def Filter(self, text):
        self.tree.Filter(text=text)
Esempio n. 19
0
class IClassSignatureFileDialog(wx.Dialog):
    def __init__(self,
                 parent,
                 group,
                 subgroup,
                 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 group: group name
        :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/group/test_group/subgroup/test_group/sig/sigFile
        self.baseFilePath = os.path.join(env['GISDBASE'], env['LOCATION_NAME'],
                                         env['MAPSET'], 'group', group,
                                         'subgroup', subgroup, '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 | wx.ALIGN_CENTER,
                  border=5)

        sizer.Add(btnSizer,
                  proportion=0,
                  flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
                  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()
Esempio n. 20
0
class SwipeMapDialog(wx.Dialog):
    """Dialog used to select maps.

    There are two modes - simple (only two raster maps),
    or two layer lists.
    """

    def __init__(
        self,
        parent,
        title=_("Select raster maps"),
        first=None,
        second=None,
        firstLayerList=None,
        secondLayerList=None,
    ):

        wx.Dialog.__init__(
            self,
            parent=parent,
            title=title,
            style=wx.RESIZE_BORDER | wx.DEFAULT_DIALOG_STYLE,
        )

        if firstLayerList is None:
            self._firstLayerList = LayerList()
        else:
            self._firstLayerList = copy.deepcopy(firstLayerList)
        if secondLayerList is None:
            self._secondLayerList = LayerList()
        else:
            self._secondLayerList = copy.deepcopy(secondLayerList)

        self._firstPanel = self._createSimplePanel()
        self._secondPanel = self._createAdvancedPanel()

        self.btnSwitch = Button(self)
        self.btnCancel = Button(self, id=wx.ID_CANCEL)
        self.btnApply = Button(self, id=wx.ID_APPLY)
        self.btnOK = Button(self, id=wx.ID_OK)
        self.btnOK.SetDefault()

        self.btnSwitch.Bind(wx.EVT_BUTTON, self.OnSwitchMode)
        self.btnApply.Bind(wx.EVT_BUTTON, lambda evt: self._apply())
        self.btnOK.Bind(wx.EVT_BUTTON, lambda evt: self._ok())
        self.btnCancel.Bind(wx.EVT_BUTTON, lambda evt: self.Close())
        self.Bind(wx.EVT_CLOSE, lambda evt: self.Hide())

        self.applyChanges = Signal("SwipeMapDialog.applyChanges")

        if first:
            self._firstRaster.SetValue(first)
        if second:
            self._secondRaster.SetValue(second)

        self._layout()

    def UnInit(self):
        self._firstLmgr.UnInit()
        self._secondLmgr.UnInit()

    def _layout(self):
        """Do layout"""
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        self._switchSizer = wx.BoxSizer()
        self._switchSizer.Add(
            self._firstPanel, proportion=1, flag=wx.EXPAND | wx.ALL, border=5
        )
        self._switchSizer.Add(
            self._secondPanel, proportion=1, flag=wx.EXPAND | wx.ALL, border=5
        )
        mainSizer.Add(self._switchSizer, proportion=1, flag=wx.EXPAND | wx.ALL)

        self.btnSizer = wx.StdDialogButtonSizer()
        self.btnSizer.AddButton(self.btnCancel)
        self.btnSizer.AddButton(self.btnOK)
        self.btnSizer.AddButton(self.btnApply)
        self.btnSizer.Realize()

        mainSizer.Add(
            self.btnSwitch, proportion=0, flag=wx.ALL | wx.ALIGN_LEFT, border=5
        )
        mainSizer.Add(self.btnSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
        self.mainSizer = mainSizer
        self._switchMode(simple=True)
        self.SetSizer(mainSizer)
        mainSizer.Fit(self)

    def _createSimplePanel(self):
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.VERTICAL)

        self._firstRaster = gselect.Select(
            parent=panel,
            type="raster",
            size=globalvar.DIALOG_GSELECT_SIZE,
            validator=SimpleValidator(callback=self.ValidatorCallback),
        )

        self._secondRaster = gselect.Select(
            parent=panel,
            type="raster",
            size=globalvar.DIALOG_GSELECT_SIZE,
            validator=SimpleValidator(callback=self.ValidatorCallback),
        )
        sizer.Add(
            StaticText(panel, label=_("Name of top/left raster map:")),
            proportion=0,
            flag=wx.EXPAND | wx.ALL,
            border=5,
        )
        sizer.Add(self._firstRaster, proportion=0, flag=wx.EXPAND | wx.ALL, border=1)
        sizer.Add(
            StaticText(panel, label=_("Name of bottom/right raster map:")),
            proportion=0,
            flag=wx.EXPAND | wx.ALL,
            border=1,
        )
        sizer.Add(self._secondRaster, proportion=0, flag=wx.EXPAND | wx.ALL, border=1)

        self._firstRaster.SetFocus()

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

        return panel

    def _createAdvancedPanel(self):
        panel = wx.Panel(self)
        sizer = wx.BoxSizer(wx.HORIZONTAL)

        self._firstLmgr = SimpleLayerManager(
            parent=panel,
            layerList=self._firstLayerList,
            lmgrStyle=SIMPLE_LMGR_RASTER
            | SIMPLE_LMGR_RGB
            | SIMPLE_LMGR_VECTOR
            | SIMPLE_LMGR_TB_LEFT,
        )
        self._secondLmgr = SimpleLayerManager(
            parent=panel,
            layerList=self._secondLayerList,
            lmgrStyle=SIMPLE_LMGR_RASTER
            | SIMPLE_LMGR_RGB
            | SIMPLE_LMGR_VECTOR
            | SIMPLE_LMGR_TB_RIGHT,
        )
        sizer.Add(self._firstLmgr, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
        sizer.Add(self._secondLmgr, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
        panel.SetSizer(sizer)
        sizer.Fit(panel)

        return panel

    def _switchMode(self, simple):
        if simple:
            self._switchSizer.Show(self._firstPanel, show=True, recursive=True)
            self._switchSizer.Show(self._secondPanel, show=False, recursive=True)
            self.btnSwitch.SetLabel(_("Switch to advanced mode"))
            self.btnCancel.SetLabel(_("Cancel"))
        else:
            self._switchSizer.Show(self._firstPanel, show=False, recursive=True)
            self._switchSizer.Show(self._secondPanel, show=True, recursive=True)
            self.btnSwitch.SetLabel(_("Switch to simple mode"))
            self.btnCancel.SetLabel(_("Close"))

        self.Freeze()  # doesn't do anything (at least on Ubuntu)
        self.btnSizer.Show(self.btnApply, simple)
        self.btnSizer.Show(self.btnOK, simple)
        self.btnSizer.Layout()
        self._switchSizer.Layout()
        self.Fit()
        self.Thaw()

        self.applyChanges.emit()

    def OnSwitchMode(self, event):
        if self._switchSizer.IsShown(self._secondPanel):
            self._switchMode(simple=True)
        else:
            self._switchMode(simple=False)

    def ValidatorCallback(self, win):
        if self._switchSizer.IsShown(self._secondPanel):
            return

        if win == self._firstRaster.GetTextCtrl():
            GMessage(parent=self, message=_("Name of the first map is missing."))
        else:
            GMessage(parent=self, message=_("Name of the second map is missing."))

    def _ok(self):
        self._apply()
        self.Close()

    def _apply(self):
        # TODO check if not empty
        self.applyChanges.emit()

    def GetValues(self):
        """Get raster maps"""
        if self.IsSimpleMode():
            return (self._firstRaster.GetValue(), self._secondRaster.GetValue())
        else:
            return (self._firstLayerList, self._secondLayerList)

    def IsSimpleMode(self):
        if self._switchSizer.IsShown(self._firstPanel):
            return True
        return False

    def GetFirstSimpleLmgr(self):
        return self._firstLmgr

    def GetSecondSimpleLmgr(self):
        return self._secondLmgr
Esempio n. 21
0
    def __init__(self,
                 parent,
                 title,
                 vectorName,
                 query=None,
                 cats=None,
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
                 **kwargs):
        """Dialog used to display/modify categories of vector objects

        :param parent:
        :param title: dialog title
        :param query: {coordinates, qdist} - used by v.edit/v.what
        :param cats: directory of lines (layer/categories) - used by vdigit
        :param style: dialog style
        """
        self.parent = parent  # map window class instance
        self.digit = parent.digit

        # map name
        self.vectorName = vectorName

        # line : {layer: [categories]}
        self.cats = {}

        # do not display dialog if no line is found (-> self.cats)
        if cats is None:
            if self._getCategories(query[0], query[1]) == 0 or not self.line:
                Debug.msg(3, "VDigitCategoryDialog(): nothing found!")
        else:
            self.cats = cats
            for line in cats.keys():
                for layer in cats[line].keys():
                    self.cats[line][layer] = list(cats[line][layer])

            layers = []
            for layer in self.digit.GetLayers():
                layers.append(str(layer))

        # make copy of cats (used for 'reload')
        self.cats_orig = copy.deepcopy(self.cats)

        wx.Dialog.__init__(self,
                           parent=self.parent,
                           id=wx.ID_ANY,
                           title=title,
                           style=style,
                           **kwargs)

        # list of categories
        box = StaticBox(parent=self,
                        id=wx.ID_ANY,
                        label=" %s " %
                        _("List of categories - right-click to delete"))
        listSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
        self.list = CategoryListCtrl(parent=self,
                                     id=wx.ID_ANY,
                                     style=wx.LC_REPORT | wx.BORDER_NONE
                                     | wx.LC_SORT_ASCENDING | wx.LC_HRULES
                                     | wx.LC_VRULES)
        # sorter
        self.fid = list(self.cats.keys())[0]
        self.itemDataMap = self.list.Populate(self.cats[self.fid])
        listmix.ColumnSorterMixin.__init__(self, 2)
        self.fidMulti = wx.Choice(parent=self, id=wx.ID_ANY, size=(150, -1))
        self.fidMulti.Bind(wx.EVT_CHOICE, self.OnFeature)
        self.fidText = StaticText(parent=self, id=wx.ID_ANY)
        if len(self.cats.keys()) == 1:
            self.fidMulti.Show(False)
            self.fidText.SetLabel(str(self.fid))
        else:
            self.fidText.Show(False)
            choices = []
            for fid in self.cats.keys():
                choices.append(str(fid))
            self.fidMulti.SetItems(choices)
            self.fidMulti.SetSelection(0)

        listSizer.Add(self.list, proportion=1, flag=wx.EXPAND)

        # add new category
        box = StaticBox(parent=self,
                        id=wx.ID_ANY,
                        label=" %s " % _("Add new category"))
        addSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
        flexSizer = wx.FlexGridSizer(cols=5, hgap=5, vgap=5)
        flexSizer.AddGrowableCol(3)

        layerNewTxt = StaticText(parent=self,
                                 id=wx.ID_ANY,
                                 label="%s:" % _("Layer"))
        self.layerNew = wx.Choice(parent=self,
                                  id=wx.ID_ANY,
                                  size=(75, -1),
                                  choices=layers)
        if len(layers) > 0:
            self.layerNew.SetSelection(0)

        catNewTxt = StaticText(parent=self,
                               id=wx.ID_ANY,
                               label="%s:" % _("Category"))

        try:
            newCat = max(self.cats[self.fid][1]) + 1
        except KeyError:
            newCat = 1
        self.catNew = SpinCtrl(parent=self,
                               id=wx.ID_ANY,
                               size=(75, -1),
                               initial=newCat,
                               min=0,
                               max=1e9)
        btnAddCat = Button(self, wx.ID_ADD)
        flexSizer.Add(layerNewTxt,
                      proportion=0,
                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
        flexSizer.Add(self.layerNew,
                      proportion=0,
                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
        flexSizer.Add(catNewTxt,
                      proportion=0,
                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT | wx.LEFT,
                      border=10)
        flexSizer.Add(self.catNew,
                      proportion=0,
                      flag=wx.FIXED_MINSIZE | wx.ALIGN_CENTER_VERTICAL)
        flexSizer.Add(btnAddCat,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALIGN_RIGHT | wx.FIXED_MINSIZE)
        addSizer.Add(flexSizer,
                     proportion=1,
                     flag=wx.ALL | wx.EXPAND,
                     border=5)

        # buttons
        btnApply = Button(self, wx.ID_APPLY)
        btnApply.SetToolTip(_("Apply changes"))
        btnCancel = Button(self, wx.ID_CANCEL)
        btnCancel.SetToolTip(_("Ignore changes and close dialog"))
        btnOk = Button(self, wx.ID_OK)
        btnOk.SetToolTip(_("Apply changes and close dialog"))
        btnOk.SetDefault()

        # sizers
        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(btnCancel)
        # btnSizer.AddButton(btnReload)
        # btnSizer.SetNegativeButton(btnReload)
        btnSizer.AddButton(btnApply)
        btnSizer.AddButton(btnOk)
        btnSizer.Realize()

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(listSizer,
                      proportion=1,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
                      border=5)
        mainSizer.Add(addSizer,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT
                      | wx.BOTTOM,
                      border=5)
        fidSizer = wx.BoxSizer(wx.HORIZONTAL)
        fidSizer.Add(StaticText(parent=self,
                                id=wx.ID_ANY,
                                label=_("Feature id:")),
                     proportion=0,
                     border=5,
                     flag=wx.ALIGN_CENTER_VERTICAL)
        fidSizer.Add(self.fidMulti,
                     proportion=0,
                     flag=wx.EXPAND | wx.ALL,
                     border=5)
        fidSizer.Add(self.fidText,
                     proportion=0,
                     flag=wx.EXPAND | wx.ALL,
                     border=5)
        mainSizer.Add(fidSizer,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALL,
                      border=5)
        mainSizer.Add(btnSizer,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
                      border=5)

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

        # set min size for dialog
        self.SetMinSize(self.GetBestSize())

        # bindings
        btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
        btnOk.Bind(wx.EVT_BUTTON, self.OnOK)
        btnAddCat.Bind(wx.EVT_BUTTON, self.OnAddCat)
        btnCancel.Bind(wx.EVT_BUTTON, self.OnCancel)
        self.Bind(wx.EVT_CLOSE, lambda evt: self.Hide())

        # list
        self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightUp)  # wxMSW
        self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)  # wxGTK
        self.Bind(wx.EVT_LIST_BEGIN_LABEL_EDIT, self.OnBeginEdit, self.list)
        self.Bind(wx.EVT_LIST_END_LABEL_EDIT, self.OnEndEdit, self.list)
        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)
Esempio n. 22
0
class MapCalcFrame(wx.Frame):
    """Mapcalc Frame class. Calculator-style window to create and run
    r(3).mapcalc statements.
    """
    def __init__(self,
                 parent,
                 giface,
                 cmd,
                 id=wx.ID_ANY,
                 style=wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER,
                 **kwargs):
        self.parent = parent
        self._giface = giface

        if self.parent:
            self.log = self.parent.GetLogWindow()
        else:
            self.log = None

        # grass command
        self.cmd = cmd

        if self.cmd == 'r.mapcalc':
            self.rast3d = False
            title = _('GRASS GIS Raster Map Calculator')
        if self.cmd == 'r3.mapcalc':
            self.rast3d = True
            title = _('GRASS GIS 3D Raster Map Calculator')

        wx.Frame.__init__(self, parent, id=id, title=title, **kwargs)
        self.SetIcon(
            wx.Icon(os.path.join(globalvar.ICONDIR, 'grass.ico'),
                    wx.BITMAP_TYPE_ICO))

        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)
        self.CreateStatusBar()

        #
        # variables
        #
        self.heading = _('mapcalc statement')
        self.funct_dict = {
            'abs(x)': 'abs()',
            'acos(x)': 'acos()',
            'asin(x)': 'asin()',
            'atan(x)': 'atan()',
            'atan(x,y)': 'atan( , )',
            'cos(x)': 'cos()',
            'double(x)': 'double()',
            'eval([x,y,...,]z)': 'eval()',
            'exp(x)': 'exp()',
            'exp(x,y)': 'exp( , )',
            'float(x)': 'float()',
            'graph(x,x1,y1[x2,y2..])': 'graph( , , )',
            'if(x)': 'if()',
            'if(x,a)': 'if( , )',
            'if(x,a,b)': 'if( , , )',
            'if(x,a,b,c)': 'if( , , , )',
            'int(x)': 'int()',
            'isnull(x)': 'isnull()',
            'log(x)': 'log(',
            'log(x,b)': 'log( , )',
            'max(x,y[,z...])': 'max( , )',
            'median(x,y[,z...])': 'median( , )',
            'min(x,y[,z...])': 'min( , )',
            'mode(x,y[,z...])': 'mode( , )',
            'nmax(x,y[,z...])': 'nmax( , )',
            'nmedian(x,y[,z...])': 'nmedian( , )',
            'nmin(x,y[,z...])': 'nmin( , )',
            'nmode(x,y[,z...])': 'nmode( , )',
            'not(x)': 'not()',
            'pow(x,y)': 'pow( , )',
            'rand(a,b)': 'rand( , )',
            'round(x)': 'round()',
            'round(x,y)': 'round( , )',
            'round(x,y,z)': 'round( , , )',
            'sin(x)': 'sin()',
            'sqrt(x)': 'sqrt()',
            'tan(x)': 'tan()',
            'xor(x,y)': 'xor( , )',
            'row()': 'row()',
            'col()': 'col()',
            'nrows()': 'nrows()',
            'ncols()': 'ncols()',
            'x()': 'x()',
            'y()': 'y()',
            'ewres()': 'ewres()',
            'nsres()': 'nsres()',
            'area()': 'area()',
            'null()': 'null()'
        }

        if self.rast3d:
            self.funct_dict['z()'] = 'z()'
            self.funct_dict['tbres()'] = 'tbres()'
            element = 'raster_3d'
        else:
            element = 'cell'

        # characters which can be in raster map name but the map name must be
        # then quoted
        self.charactersToQuote = '+-&!<>%~?^|'
        # stores last typed map name in Select widget to distinguish typing
        # from selection
        self.lastMapName = ''

        self.operatorBox = StaticBox(parent=self.panel,
                                     id=wx.ID_ANY,
                                     label=" %s " % _('Operators'))
        self.outputBox = StaticBox(parent=self.panel,
                                   id=wx.ID_ANY,
                                   label=" %s " % _('Output'))
        self.operandBox = StaticBox(parent=self.panel,
                                    id=wx.ID_ANY,
                                    label=" %s " % _('Operands'))
        self.expressBox = StaticBox(parent=self.panel,
                                    id=wx.ID_ANY,
                                    label=" %s " % _('Expression'))

        #
        # Buttons
        #
        self.btn_clear = ClearButton(parent=self.panel)
        self.btn_help = Button(parent=self.panel, id=wx.ID_HELP)
        self.btn_run = Button(parent=self.panel, id=wx.ID_ANY, label=_("&Run"))
        self.btn_run.SetDefault()
        self.btn_close = CloseButton(parent=self.panel)
        self.btn_save = Button(parent=self.panel, id=wx.ID_SAVE)
        self.btn_save.SetToolTip(_('Save expression to file'))
        self.btn_load = Button(parent=self.panel,
                               id=wx.ID_ANY,
                               label=_("&Load"))
        self.btn_load.SetToolTip(_('Load expression from file'))
        self.btn_copy = Button(parent=self.panel,
                               id=wx.ID_ANY,
                               label=_("Copy"))
        self.btn_copy.SetToolTip(
            _("Copy the current command string to the clipboard"))

        self.btn = dict()
        self.btn['pow'] = Button(parent=self.panel, id=wx.ID_ANY, label="^")
        self.btn['pow'].SetToolTip(_('exponent'))
        self.btn['div'] = Button(parent=self.panel, id=wx.ID_ANY, label="/")
        self.btn['div'].SetToolTip(_('divide'))
        self.btn['add'] = Button(parent=self.panel, id=wx.ID_ANY, label="+")
        self.btn['add'].SetToolTip(_('add'))
        self.btn['minus'] = Button(parent=self.panel, id=wx.ID_ANY, label="-")
        self.btn['minus'].SetToolTip(_('subtract'))
        self.btn['mod'] = Button(parent=self.panel, id=wx.ID_ANY, label="%")
        self.btn['mod'].SetToolTip(_('modulus'))
        self.btn['mult'] = Button(parent=self.panel, id=wx.ID_ANY, label="*")
        self.btn['mult'].SetToolTip(_('multiply'))

        self.btn['parenl'] = Button(parent=self.panel, id=wx.ID_ANY, label="(")
        self.btn['parenr'] = Button(parent=self.panel, id=wx.ID_ANY, label=")")
        self.btn['lshift'] = Button(parent=self.panel,
                                    id=wx.ID_ANY,
                                    label="<<")
        self.btn['lshift'].SetToolTip(_('left shift'))
        self.btn['rshift'] = Button(parent=self.panel,
                                    id=wx.ID_ANY,
                                    label=">>")
        self.btn['rshift'].SetToolTip(_('right shift'))
        self.btn['rshiftu'] = Button(parent=self.panel,
                                     id=wx.ID_ANY,
                                     label=">>>")
        self.btn['rshiftu'].SetToolTip(_('right shift (unsigned)'))
        self.btn['gt'] = Button(parent=self.panel, id=wx.ID_ANY, label=">")
        self.btn['gt'].SetToolTip(_('greater than'))
        self.btn['gteq'] = Button(parent=self.panel, id=wx.ID_ANY, label=">=")
        self.btn['gteq'].SetToolTip(_('greater than or equal to'))
        self.btn['lt'] = Button(parent=self.panel, id=wx.ID_ANY, label="<")
        self.btn['lt'].SetToolTip(_('less than'))
        self.btn['lteq'] = Button(parent=self.panel, id=wx.ID_ANY, label="<=")
        self.btn['lteq'].SetToolTip(_('less than or equal to'))
        self.btn['eq'] = Button(parent=self.panel, id=wx.ID_ANY, label="==")
        self.btn['eq'].SetToolTip(_('equal to'))
        self.btn['noteq'] = Button(parent=self.panel, id=wx.ID_ANY, label="!=")
        self.btn['noteq'].SetToolTip(_('not equal to'))

        self.btn['compl'] = Button(parent=self.panel, id=wx.ID_ANY, label="~")
        self.btn['compl'].SetToolTip(_('one\'s complement'))
        self.btn['not'] = Button(parent=self.panel, id=wx.ID_ANY, label="!")
        self.btn['not'].SetToolTip(_('NOT'))
        self.btn['andbit'] = Button(parent=self.panel,
                                    id=wx.ID_ANY,
                                    label='&&')
        self.btn['andbit'].SetToolTip(_('bitwise AND'))
        self.btn['orbit'] = Button(parent=self.panel, id=wx.ID_ANY, label="|")
        self.btn['orbit'].SetToolTip(_('bitwise OR'))
        self.btn['and'] = Button(parent=self.panel, id=wx.ID_ANY, label="&&&&")
        self.btn['and'].SetToolTip(_('logical AND'))
        self.btn['andnull'] = Button(parent=self.panel,
                                     id=wx.ID_ANY,
                                     label="&&&&&&")
        self.btn['andnull'].SetToolTip(_('logical AND (ignores NULLs)'))
        self.btn['or'] = Button(parent=self.panel, id=wx.ID_ANY, label="||")
        self.btn['or'].SetToolTip(_('logical OR'))
        self.btn['ornull'] = Button(parent=self.panel,
                                    id=wx.ID_ANY,
                                    label="|||")
        self.btn['ornull'].SetToolTip(_('logical OR (ignores NULLs)'))
        self.btn['cond'] = Button(parent=self.panel,
                                  id=wx.ID_ANY,
                                  label="a ? b : c")
        self.btn['cond'].SetToolTip(_('conditional'))

        #
        # Text area
        #
        self.text_mcalc = TextCtrl(parent=self.panel,
                                   id=wx.ID_ANY,
                                   size=(-1, 100),
                                   style=wx.TE_MULTILINE)
        wx.CallAfter(self.text_mcalc.SetFocus)

        #
        # Map and function insertion text and ComboBoxes
        self.newmaplabel = StaticText(parent=self.panel, id=wx.ID_ANY)
        if self.rast3d:
            self.newmaplabel.SetLabel(
                _('Name for new 3D raster map to create'))
        else:
            self.newmaplabel.SetLabel(_('Name for new raster map to create'))
        # As we can write only to current mapset, names should not be fully qualified
        # to not confuse end user about writing in other mapset
        self.newmaptxt = Select(parent=self.panel,
                                id=wx.ID_ANY,
                                size=(250, -1),
                                type=element,
                                multiple=False,
                                fullyQualified=False)
        self.mapsellabel = StaticText(parent=self.panel, id=wx.ID_ANY)
        if self.rast3d:
            self.mapsellabel.SetLabel(_('Insert existing 3D raster map'))
        else:
            self.mapsellabel.SetLabel(_('Insert existing raster map'))
        self.mapselect = Select(parent=self.panel,
                                id=wx.ID_ANY,
                                size=(250, -1),
                                type=element,
                                multiple=False)
        self.functlabel = StaticText(parent=self.panel,
                                     id=wx.ID_ANY,
                                     label=_('Insert mapcalc function'))
        self.function = wx.ComboBox(parent=self.panel,
                                    id=wx.ID_ANY,
                                    size=(250, -1),
                                    choices=sorted(self.funct_dict.keys()),
                                    style=wx.CB_DROPDOWN | wx.CB_READONLY
                                    | wx.TE_PROCESS_ENTER)

        self.overwrite = wx.CheckBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=_("Allow output files to overwrite existing files"))
        self.overwrite.SetValue(
            UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))

        self.randomSeed = wx.CheckBox(
            parent=self.panel, label=_("Generate random seed for rand()"))
        self.randomSeedStaticText = StaticText(parent=self.panel,
                                               label=_("Seed:"))
        self.randomSeedText = TextCtrl(parent=self.panel,
                                       size=(100, -1),
                                       validator=IntegerValidator())
        self.randomSeedText.SetToolTip(_("Integer seed for rand() function"))
        self.randomSeed.SetValue(True)
        self.randomSeedStaticText.Disable()
        self.randomSeedText.Disable()

        self.addbox = wx.CheckBox(
            parent=self.panel,
            label=_('Add created raster map into layer tree'),
            style=wx.NO_BORDER)
        self.addbox.SetValue(
            UserSettings.Get(group='cmd', key='addNewLayer', subkey='enabled'))
        if not self.parent or self.parent.GetName() != 'LayerManager':
            self.addbox.Hide()

        #
        # Bindings
        #
        for btn in self.btn.keys():
            self.btn[btn].Bind(wx.EVT_BUTTON, self.AddMark)

        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
        self.btn_clear.Bind(wx.EVT_BUTTON, self.OnClear)
        self.btn_run.Bind(wx.EVT_BUTTON, self.OnMCalcRun)
        self.btn_help.Bind(wx.EVT_BUTTON, self.OnHelp)
        self.btn_save.Bind(wx.EVT_BUTTON, self.OnSaveExpression)
        self.btn_load.Bind(wx.EVT_BUTTON, self.OnLoadExpression)
        self.btn_copy.Bind(wx.EVT_BUTTON, self.OnCopyCommand)

        self.mapselect.Bind(wx.EVT_TEXT, self.OnSelect)
        self.function.Bind(wx.EVT_COMBOBOX, self._return_funct)
        self.function.Bind(wx.EVT_TEXT_ENTER, self.OnSelect)
        self.newmaptxt.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
        self.text_mcalc.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
        self.overwrite.Bind(wx.EVT_CHECKBOX, self.OnUpdateStatusBar)
        self.randomSeed.Bind(wx.EVT_CHECKBOX, self.OnUpdateStatusBar)
        self.randomSeed.Bind(wx.EVT_CHECKBOX, self.OnSeedFlag)
        self.randomSeedText.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)

        # bind closing to ESC
        self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_CANCEL)
        accelTableList = [(wx.ACCEL_NORMAL, wx.WXK_ESCAPE, wx.ID_CANCEL)]
        accelTable = wx.AcceleratorTable(accelTableList)
        self.SetAcceleratorTable(accelTable)

        self._layout()

        self.SetMinSize(self.panel.GetBestSize())
        # workaround for http://trac.wxwidgets.org/ticket/13628
        self.SetSize(self.panel.GetBestSize())

    def _return_funct(self, event):
        i = event.GetString()
        self._addSomething(self.funct_dict[i])

        # reset
        win = self.FindWindowById(event.GetId())
        win.SetValue('')

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

        controlSizer = wx.BoxSizer(wx.HORIZONTAL)
        operatorSizer = wx.StaticBoxSizer(self.operatorBox, wx.HORIZONTAL)
        outOpeSizer = wx.BoxSizer(wx.VERTICAL)

        buttonSizer1 = wx.GridBagSizer(5, 1)
        buttonSizer1.Add(self.btn['add'], pos=(0, 0))
        buttonSizer1.Add(self.btn['minus'], pos=(0, 1))
        buttonSizer1.Add(self.btn['mod'], pos=(5, 0))
        buttonSizer1.Add(self.btn['mult'], pos=(1, 0))
        buttonSizer1.Add(self.btn['div'], pos=(1, 1))
        buttonSizer1.Add(self.btn['pow'], pos=(5, 1))
        buttonSizer1.Add(self.btn['gt'], pos=(2, 0))
        buttonSizer1.Add(self.btn['gteq'], pos=(2, 1))
        buttonSizer1.Add(self.btn['eq'], pos=(4, 0))
        buttonSizer1.Add(self.btn['lt'], pos=(3, 0))
        buttonSizer1.Add(self.btn['lteq'], pos=(3, 1))
        buttonSizer1.Add(self.btn['noteq'], pos=(4, 1))

        buttonSizer2 = wx.GridBagSizer(5, 1)
        buttonSizer2.Add(self.btn['and'], pos=(0, 0))
        buttonSizer2.Add(self.btn['andbit'], pos=(1, 0))
        buttonSizer2.Add(self.btn['andnull'], pos=(2, 0))
        buttonSizer2.Add(self.btn['or'], pos=(0, 1))
        buttonSizer2.Add(self.btn['orbit'], pos=(1, 1))
        buttonSizer2.Add(self.btn['ornull'], pos=(2, 1))
        buttonSizer2.Add(self.btn['lshift'], pos=(3, 0))
        buttonSizer2.Add(self.btn['rshift'], pos=(3, 1))
        buttonSizer2.Add(self.btn['rshiftu'], pos=(4, 0))
        buttonSizer2.Add(self.btn['cond'], pos=(5, 0))
        buttonSizer2.Add(self.btn['compl'], pos=(5, 1))
        buttonSizer2.Add(self.btn['not'], pos=(4, 1))

        outputSizer = wx.StaticBoxSizer(self.outputBox, wx.VERTICAL)
        outputSizer.Add(self.newmaplabel,
                        flag=wx.ALIGN_CENTER | wx.TOP,
                        border=5)
        outputSizer.Add(self.newmaptxt, flag=wx.EXPAND | wx.ALL, border=5)

        operandSizer = wx.StaticBoxSizer(self.operandBox, wx.HORIZONTAL)

        buttonSizer3 = wx.GridBagSizer(7, 1)
        buttonSizer3.Add(self.functlabel,
                         pos=(0, 0),
                         span=(1, 2),
                         flag=wx.ALIGN_CENTER | wx.EXPAND)
        buttonSizer3.Add(self.function, pos=(1, 0), span=(1, 2))
        buttonSizer3.Add(self.mapsellabel,
                         pos=(2, 0),
                         span=(1, 2),
                         flag=wx.ALIGN_CENTER)
        buttonSizer3.Add(self.mapselect, pos=(3, 0), span=(1, 2))
        threebutton = wx.GridBagSizer(1, 2)
        threebutton.Add(self.btn['parenl'],
                        pos=(0, 0),
                        span=(1, 1),
                        flag=wx.ALIGN_LEFT)
        threebutton.Add(self.btn['parenr'],
                        pos=(0, 1),
                        span=(1, 1),
                        flag=wx.ALIGN_CENTER)
        threebutton.Add(self.btn_clear,
                        pos=(0, 2),
                        span=(1, 1),
                        flag=wx.ALIGN_RIGHT)
        buttonSizer3.Add(threebutton,
                         pos=(4, 0),
                         span=(1, 1),
                         flag=wx.ALIGN_CENTER)

        buttonSizer4 = wx.BoxSizer(wx.HORIZONTAL)
        buttonSizer4.Add(self.btn_load, flag=wx.ALL, border=5)
        buttonSizer4.Add(self.btn_save, flag=wx.ALL, border=5)
        buttonSizer4.Add(self.btn_copy, flag=wx.ALL, border=5)
        buttonSizer4.AddSpacer(30)
        buttonSizer4.Add(self.btn_help, flag=wx.ALL, border=5)
        buttonSizer4.Add(self.btn_run, flag=wx.ALL, border=5)
        buttonSizer4.Add(self.btn_close, flag=wx.ALL, border=5)

        operatorSizer.Add(buttonSizer1,
                          proportion=0,
                          flag=wx.ALL | wx.EXPAND,
                          border=5)
        operatorSizer.Add(buttonSizer2,
                          proportion=0,
                          flag=wx.TOP | wx.BOTTOM | wx.RIGHT | wx.EXPAND,
                          border=5)

        operandSizer.Add(buttonSizer3, proportion=0, flag=wx.ALL, border=5)

        controlSizer.Add(operatorSizer,
                         proportion=1,
                         flag=wx.RIGHT | wx.EXPAND,
                         border=5)
        outOpeSizer.Add(outputSizer, proportion=0, flag=wx.EXPAND)
        outOpeSizer.Add(operandSizer,
                        proportion=1,
                        flag=wx.EXPAND | wx.TOP,
                        border=5)
        controlSizer.Add(outOpeSizer, proportion=0, flag=wx.EXPAND)

        expressSizer = wx.StaticBoxSizer(self.expressBox, wx.HORIZONTAL)
        expressSizer.Add(self.text_mcalc, proportion=1, flag=wx.EXPAND)

        sizer.Add(controlSizer,
                  proportion=0,
                  flag=wx.EXPAND | wx.ALL,
                  border=5)
        sizer.Add(expressSizer,
                  proportion=1,
                  flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
                  border=5)
        sizer.Add(buttonSizer4,
                  proportion=0,
                  flag=wx.ALIGN_RIGHT | wx.ALL,
                  border=3)

        randomSizer = wx.BoxSizer(wx.HORIZONTAL)
        randomSizer.Add(self.randomSeed,
                        proportion=0,
                        flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
                        border=20)
        randomSizer.Add(self.randomSeedStaticText,
                        proportion=0,
                        flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL,
                        border=5)
        randomSizer.Add(self.randomSeedText, proportion=0)
        sizer.Add(randomSizer, proportion=0, flag=wx.LEFT | wx.RIGHT, border=5)

        sizer.Add(self.overwrite,
                  proportion=0,
                  flag=wx.LEFT | wx.RIGHT,
                  border=5)
        if self.addbox.IsShown():
            sizer.Add(self.addbox,
                      proportion=0,
                      flag=wx.LEFT | wx.RIGHT,
                      border=5)

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

        self.Layout()

    def AddMark(self, event):
        """Sends operators to insertion method
        """
        if event.GetId() == self.btn['compl'].GetId():
            mark = "~"
        elif event.GetId() == self.btn['not'].GetId():
            mark = "!"
        elif event.GetId() == self.btn['pow'].GetId():
            mark = "^"
        elif event.GetId() == self.btn['div'].GetId():
            mark = "/"
        elif event.GetId() == self.btn['add'].GetId():
            mark = "+"
        elif event.GetId() == self.btn['minus'].GetId():
            mark = "-"
        elif event.GetId() == self.btn['mod'].GetId():
            mark = "%"
        elif event.GetId() == self.btn['mult'].GetId():
            mark = "*"
        elif event.GetId() == self.btn['lshift'].GetId():
            mark = "<<"
        elif event.GetId() == self.btn['rshift'].GetId():
            mark = ">>"
        elif event.GetId() == self.btn['rshiftu'].GetId():
            mark = ">>>"
        elif event.GetId() == self.btn['gt'].GetId():
            mark = ">"
        elif event.GetId() == self.btn['gteq'].GetId():
            mark = ">="
        elif event.GetId() == self.btn['lt'].GetId():
            mark = "<"
        elif event.GetId() == self.btn['lteq'].GetId():
            mark = "<="
        elif event.GetId() == self.btn['eq'].GetId():
            mark = "=="
        elif event.GetId() == self.btn['noteq'].GetId():
            mark = "!="
        elif event.GetId() == self.btn['andbit'].GetId():
            mark = "&"
        elif event.GetId() == self.btn['orbit'].GetId():
            mark = "|"
        elif event.GetId() == self.btn['or'].GetId():
            mark = "||"
        elif event.GetId() == self.btn['ornull'].GetId():
            mark = "|||"
        elif event.GetId() == self.btn['and'].GetId():
            mark = "&&"
        elif event.GetId() == self.btn['andnull'].GetId():
            mark = "&&&"
        elif event.GetId() == self.btn['cond'].GetId():
            mark = " ? : "
        elif event.GetId() == self.btn['parenl'].GetId():
            mark = "("
        elif event.GetId() == self.btn['parenr'].GetId():
            mark = ")"
        self._addSomething(mark)

    # unused
    # def OnSelectTextEvt(self, event):
    #     """Checks if user is typing or the event was emited by map selection.
    #     Prevents from changing focus.
    #     """
    #     item = self.mapselect.GetValue().strip()
    #     if not (abs(len(item) - len(self.lastMapName)) == 1 and \
    #         self.lastMapName in item or item in self.lastMapName):
    #         self.OnSelect(event)

    #     self.lastMapName = item

    def OnSelect(self, event):
        """Gets raster map or function selection and send it to
        insertion method.

        Checks for characters which can be in raster map name but
        the raster map name must be then quoted.
        """
        win = self.FindWindowById(event.GetId())
        item = win.GetValue().strip()
        if any((char in item) for char in self.charactersToQuote):
            item = '"' + item + '"'
        self._addSomething(item)

        win.ChangeValue('')  # reset
        # Map selector likes to keep focus. Set it back to expression input area
        wx.CallAfter(self.text_mcalc.SetFocus)

    def OnUpdateStatusBar(self, event):
        """Update statusbar text"""
        command = self._getCommand()
        self.SetStatusText(command)
        event.Skip()

    def OnSeedFlag(self, event):
        checked = self.randomSeed.IsChecked()
        self.randomSeedText.Enable(not checked)
        self.randomSeedStaticText.Enable(not checked)

        event.Skip()

    def _getCommand(self):
        """Returns entire command as string."""
        expr = self.text_mcalc.GetValue().strip().replace("\n", " ")
        cmd = 'r.mapcalc'
        if self.rast3d:
            cmd = 'r3.mapcalc'
        overwrite = ''
        if self.overwrite.IsChecked():
            overwrite = ' --overwrite'
        seed_flag = seed = ''
        if re.search(pattern="rand *\(.+\)", string=expr):
            if self.randomSeed.IsChecked():
                seed_flag = ' -s'
            else:
                seed = " seed={val}".format(
                    val=self.randomSeedText.GetValue().strip())

        return ('{cmd} expression="{new} = {expr}"{seed}{seed_flag}{overwrite}'
                .format(cmd=cmd,
                        expr=expr,
                        new=self.newmaptxt.GetValue(),
                        seed_flag=seed_flag,
                        seed=seed,
                        overwrite=overwrite))

    def _addSomething(self, what):
        """Inserts operators, map names, and functions into text area
        """
        mcalcstr = self.text_mcalc.GetValue()
        position = self.text_mcalc.GetInsertionPoint()

        newmcalcstr = mcalcstr[:position]

        position_offset = 0
        try:
            if newmcalcstr[-1] != ' ':
                newmcalcstr += ' '
                position_offset += 1
        except:
            pass

        newmcalcstr += what

        # Do not add extra space if there is already one
        try:
            if newmcalcstr[-1] != ' ' and mcalcstr[position] != ' ':
                newmcalcstr += ' '
        except:
            newmcalcstr += ' '

        newmcalcstr += mcalcstr[position:]

        self.text_mcalc.SetValue(newmcalcstr)
        if len(what) > 0:
            match = re.search(pattern="\(.*\)", string=what)
            if match:
                position_offset += match.start() + 1
            else:
                position_offset += len(what)
                try:
                    if newmcalcstr[position + position_offset] == ' ':
                        position_offset += 1
                except:
                    pass

        self.text_mcalc.SetInsertionPoint(position + position_offset)
        self.text_mcalc.Update()
        self.text_mcalc.SetFocus()

    def OnMCalcRun(self, event):
        """Builds and runs r.mapcalc statement
        """
        name = self.newmaptxt.GetValue().strip()
        if not name:
            GError(parent=self,
                   message=_("You must enter the name of "
                             "a new raster map to create."))
            return

        if not (name[0] == '"' and name[-1] == '"') and any(
            (char in name) for char in self.charactersToQuote):
            name = '"' + name + '"'

        expr = self.text_mcalc.GetValue().strip().replace("\n", " ")
        if not expr:
            GError(parent=self,
                   message=_("You must enter an expression "
                             "to create a new raster map."))
            return

        seed_flag = seed = None
        if re.search(pattern="rand *\(.+\)", string=expr):
            if self.randomSeed.IsChecked():
                seed_flag = '-s'
            else:
                seed = self.randomSeedText.GetValue().strip()
        if self.log:
            cmd = [self.cmd]
            if seed_flag:
                cmd.append('-s')
            if seed:
                cmd.append("seed={val}".format(val=seed))
            if self.overwrite.IsChecked():
                cmd.append('--overwrite')
            cmd.append(str('expression=%s = %s' % (name, expr)))

            self.log.RunCmd(cmd, onDone=self.OnDone)
            self.parent.Raise()
        else:
            if self.overwrite.IsChecked():
                overwrite = True
            else:
                overwrite = False
            params = dict(expression="%s=%s" % (name, expr),
                          overwrite=overwrite)
            if seed_flag:
                params['flags'] = 's'
            if seed:
                params['seed'] = seed

            RunCommand(self.cmd, **params)

    def OnDone(self, event):
        """Add create map to the layer tree

        Sends the mapCreated signal from the grass interface.
        """
        if event.returncode != 0:
            return
        name = self.newmaptxt.GetValue().strip(
            ' "') + '@' + grass.gisenv()['MAPSET']
        ltype = 'raster'
        if self.rast3d:
            ltype = 'raster_3d'
        self._giface.mapCreated.emit(name=name,
                                     ltype=ltype,
                                     add=self.addbox.IsChecked())
        gisenv = grass.gisenv()
        self._giface.grassdbChanged.emit(grassdb=gisenv['GISDBASE'],
                                         location=gisenv['LOCATION_NAME'],
                                         mapset=gisenv['MAPSET'],
                                         action='new',
                                         map=name.split('@')[0],
                                         element=ltype)

    def OnSaveExpression(self, event):
        """Saves expression to file
        """
        mctxt = self.newmaptxt.GetValue() + ' = ' + self.text_mcalc.GetValue(
        ) + os.linesep

        # dialog
        dlg = wx.FileDialog(
            parent=self,
            message=_("Choose a file name to save the expression"),
            wildcard=_("Expression file (*)|*"),
            style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            if not path:
                dlg.Destroy()
                return

            try:
                fobj = open(path, 'w')
                fobj.write(mctxt)
            finally:
                fobj.close()

        dlg.Destroy()

    def OnLoadExpression(self, event):
        """Load expression from file
        """
        dlg = wx.FileDialog(
            parent=self,
            message=_("Choose a file name to load the expression"),
            wildcard=_("Expression file (*)|*"),
            style=wx.FD_OPEN)
        if dlg.ShowModal() == wx.ID_OK:
            path = dlg.GetPath()
            if not path:
                dlg.Destroy()
                return

            try:
                fobj = open(path, 'r')
                mctxt = fobj.read()
            finally:
                fobj.close()

            try:
                result, exp = mctxt.split('=', 1)
            except ValueError:
                result = ''
                exp = mctxt

            self.newmaptxt.SetValue(result.strip())
            self.text_mcalc.SetValue(exp.strip())
            self.text_mcalc.SetFocus()
            self.text_mcalc.SetInsertionPointEnd()

        dlg.Destroy()

    def OnCopyCommand(self, event):
        command = self._getCommand()
        cmddata = wx.TextDataObject()
        cmddata.SetText(command)
        if wx.TheClipboard.Open():
            wx.TheClipboard.SetData(cmddata)
            wx.TheClipboard.Close()
            self.SetStatusText(
                _("'{cmd}' copied to clipboard").format(cmd=command))

    def OnClear(self, event):
        """Clears text area
        """
        self.text_mcalc.SetValue('')

    def OnHelp(self, event):
        """Launches r.mapcalc help
        """
        RunCommand('g.manual', parent=self, entry=self.cmd)

    def OnClose(self, event):
        """Close window"""
        self.Destroy()
Esempio n. 23
0
    def __init__(self,
                 parent,
                 data,
                 title=_("List of duplicates"),
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
                 pos=wx.DefaultPosition):
        """Show duplicated feature ids
        """
        wx.Dialog.__init__(self,
                           parent=parent,
                           id=wx.ID_ANY,
                           title=title,
                           style=style,
                           pos=pos)

        self.parent = parent  # map window instance
        self.data = data
        self.winList = []

        # panel  = wx.Panel(parent=self, id=wx.ID_ANY)

        # notebook
        self.notebook = wx.Notebook(parent=self,
                                    id=wx.ID_ANY,
                                    style=wx.BK_DEFAULT)

        id = 1
        for key in self.data.keys():
            panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
            self.notebook.AddPage(page=panel, text=" %d " % (id))

            # notebook body
            border = wx.BoxSizer(wx.VERTICAL)

            win = CheckListFeature(parent=panel, data=list(self.data[key]))
            self.winList.append(win.GetId())

            border.Add(win, proportion=1, flag=wx.ALL | wx.EXPAND, border=5)

            panel.SetSizer(border)

            id += 1

        # buttons
        btnCancel = Button(self, wx.ID_CANCEL)
        btnOk = Button(self, wx.ID_OK)
        btnOk.SetDefault()

        # sizers
        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(btnCancel)
        btnSizer.AddButton(btnOk)
        btnSizer.Realize()

        mainSizer = wx.BoxSizer(wx.VERTICAL)
        mainSizer.Add(self.notebook,
                      proportion=1,
                      flag=wx.EXPAND | wx.ALL,
                      border=5)
        mainSizer.Add(btnSizer,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
                      border=5)

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

        # set min size for dialog
        self.SetMinSize((250, 180))
Esempio n. 24
0
    def __init__(self,
                 parent,
                 map,
                 query=None,
                 cats=None,
                 line=None,
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
                 pos=wx.DefaultPosition,
                 action="add",
                 ignoreError=False):
        """Standard dialog used to add/update/display attributes linked
        to the vector map.

        Attribute data can be selected based on layer and category number
        or coordinates.

        :param parent:
        :param map: vector map
        :param query: query coordinates and distance (used for v.edit)
        :param cats: {layer: cats}
        :param line: feature id (requested for cats)
        :param style:
        :param pos:
        :param action: (add, update, display)
        :param ignoreError: True to ignore errors
        """
        self.parent = parent  # mapdisplay.BufferedWindow
        self.map = map
        self.action = action

        # ids/cats of selected features
        # fid : {layer : cats}
        self.cats = {}
        self.fid = -1  # feature id

        # get layer/table/column information
        self.mapDBInfo = VectorDBInfo(self.map)

        layers = self.mapDBInfo.layers.keys()  # get available layers

        # check if db connection / layer exists
        if len(layers) <= 0:
            if not ignoreError:
                dlg = wx.MessageDialog(
                    parent=self.parent,
                    message=_("No attribute table found.\n\n"
                              "Do you want to create a new attribute table "
                              "and defined a link to vector map <%s>?") %
                    self.map,
                    caption=_("Create table?"),
                    style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
                if dlg.ShowModal() == wx.ID_YES:
                    lmgr = self.parent.lmgr
                    lmgr.OnShowAttributeTable(event=None, selection='layers')

                dlg.Destroy()

            self.mapDBInfo = None

        wx.Dialog.__init__(self,
                           parent=self.parent,
                           id=wx.ID_ANY,
                           title="",
                           style=style,
                           pos=pos)

        # dialog body
        mainSizer = wx.BoxSizer(wx.VERTICAL)

        # notebook
        self.notebook = wx.Notebook(parent=self,
                                    id=wx.ID_ANY,
                                    style=wx.BK_DEFAULT)

        self.closeDialog = wx.CheckBox(parent=self,
                                       id=wx.ID_ANY,
                                       label=_("Close dialog on submit"))
        self.closeDialog.SetValue(True)
        if self.action == 'display':
            self.closeDialog.Enable(False)

        # feature id (text/choice for duplicates)
        self.fidMulti = wx.Choice(parent=self, id=wx.ID_ANY, size=(150, -1))
        self.fidMulti.Bind(wx.EVT_CHOICE, self.OnFeature)
        self.fidText = StaticText(parent=self, id=wx.ID_ANY)

        self.noFoundMsg = StaticText(parent=self,
                                     id=wx.ID_ANY,
                                     label=_("No attributes found"))

        self.UpdateDialog(query=query, cats=cats)

        # set title
        if self.action == "update":
            self.SetTitle(_("Update attributes"))
        elif self.action == "add":
            self.SetTitle(_("Define attributes"))
        else:
            self.SetTitle(_("Display attributes"))

        # buttons
        btnCancel = Button(self, wx.ID_CANCEL)
        btnReset = Button(self, wx.ID_UNDO, _("&Reload"))
        btnSubmit = Button(self, wx.ID_OK, _("&Submit"))
        if self.action == 'display':
            btnSubmit.Enable(False)

        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(btnCancel)
        btnSizer.AddButton(btnReset)
        btnSizer.SetNegativeButton(btnReset)
        btnSubmit.SetDefault()
        btnSizer.AddButton(btnSubmit)
        btnSizer.Realize()

        mainSizer.Add(self.noFoundMsg,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALL,
                      border=5)
        mainSizer.Add(self.notebook,
                      proportion=1,
                      flag=wx.EXPAND | wx.ALL,
                      border=5)
        fidSizer = wx.BoxSizer(wx.HORIZONTAL)
        fidSizer.Add(StaticText(parent=self,
                                id=wx.ID_ANY,
                                label=_("Feature id:")),
                     proportion=0,
                     border=5,
                     flag=wx.ALIGN_CENTER_VERTICAL)
        fidSizer.Add(self.fidMulti,
                     proportion=0,
                     flag=wx.EXPAND | wx.ALL,
                     border=5)
        fidSizer.Add(self.fidText,
                     proportion=0,
                     flag=wx.EXPAND | wx.ALL,
                     border=5)
        mainSizer.Add(fidSizer,
                      proportion=0,
                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
                      border=5)
        mainSizer.Add(self.closeDialog,
                      proportion=0,
                      flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
                      border=5)
        mainSizer.Add(btnSizer,
                      proportion=0,
                      flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER,
                      border=5)

        # bindigs
        btnReset.Bind(wx.EVT_BUTTON, self.OnReset)
        btnSubmit.Bind(wx.EVT_BUTTON, self.OnSubmit)
        btnCancel.Bind(wx.EVT_BUTTON, self.OnClose)
        self.Bind(wx.EVT_CLOSE, self.OnClose)

        self.SetSizer(mainSizer)
        mainSizer.Fit(self)

        # set min size for dialog
        w, h = self.GetBestSize()
        w += 50
        if h < 200:
            self.SetMinSize((w, 200))
        else:
            self.SetMinSize((w, h))

        if self.notebook.GetPageCount() == 0:
            Debug.msg(2, "DisplayAttributesDialog(): Nothing found!")
Esempio n. 25
0
class WSPropertiesDialog(WSDialogBase):
    """Dialog for editing web service properties."""
    def __init__(
        self,
        parent,
        giface,
        layer,
        ws_cap_files,
        cmd,
        id=wx.ID_ANY,
        style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
        **kwargs,
    ):
        """
        :param giface: grass interface
        :param layer: layer tree item
        :param ws_cap_files: dict web service('WMS_1.1.1', 'WMS_1.3.0',
        'WMTS', 'OnEarth') : cap file path cap files, which will be parsed
        :param cmd: cmd to which dialog widgets will be initialized if
        it is possible (cmp parameters exists in parsed web service cap_file)
        """

        WSDialogBase.__init__(
            self,
            parent,
            id=wx.ID_ANY,
            style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
            **kwargs,
        )

        self.SetTitle(_("Web service layer properties"))

        self.layer = layer
        self.giface = giface

        # after web service panels are connected, set dialog widgets
        # according to cmd in this variable (if it is not None)
        self.cmd_to_set = None

        # store data needed for reverting
        self.revert_ws_cap_files = {}
        self.revert_cmd = cmd

        ws_cap = self._getWSfromCmd(cmd)
        for ws in six.iterkeys(self.ws_panels):
            # cap file used in cmd will be deleted, thnaks to the dialogs
            # destructor
            if ws == ws_cap and "capfile" in cmd[1]:
                self.revert_ws_cap_files[ws] = cmd[1]["capfile"]
                del ws_cap_files[ws]
            else:
                self.revert_ws_cap_files[ws] = grass.tempfile()

        self._setRevertCapFiles(ws_cap_files)

        self.LoadCapFiles(ws_cap_files=self.revert_ws_cap_files, cmd=cmd)
        self.btn_ok.SetDefault()

    def __del__(self):
        for f in six.itervalues(self.revert_ws_cap_files):
            grass.try_remove(f)

    def _setRevertCapFiles(self, ws_cap_files):

        for ws, f in six.iteritems(ws_cap_files):
            if os.path.isfile(ws_cap_files[ws]):
                shutil.copyfile(f, self.revert_ws_cap_files[ws])
            else:
                # delete file content
                f_o = open(f, "w")
                f_o.close()

    def _createWidgets(self):

        WSDialogBase._createWidgets(self)

        self.btn_apply = Button(parent=self, id=wx.ID_ANY, label=_("&Apply"))
        self.btn_apply.SetToolTip(_("Apply changes"))
        self.btn_apply.Enable(False)
        self.run_btns.append(self.btn_apply)

        self.btn_ok = Button(parent=self, id=wx.ID_ANY, label=_("&OK"))
        self.btn_ok.SetToolTip(_("Apply changes and close dialog"))
        self.btn_ok.Enable(False)
        self.run_btns.append(self.btn_ok)

    def _doLayout(self):

        WSDialogBase._doLayout(self)

        self.btnsizer.Add(self.btn_apply,
                          proportion=0,
                          flag=wx.ALL | wx.ALIGN_CENTER,
                          border=10)

        self.btnsizer.Add(self.btn_ok,
                          proportion=0,
                          flag=wx.ALL | wx.ALIGN_CENTER,
                          border=10)

        # bindings
        self.btn_apply.Bind(wx.EVT_BUTTON, self.OnApply)
        self.btn_ok.Bind(wx.EVT_BUTTON, self.OnSave)

    def LoadCapFiles(self, ws_cap_files, cmd):
        """Parse cap files and update dialog.

        For parameters description, see the constructor.
        """
        self.ch_ws_sizer.Clear(True)

        self.cmd_to_set = cmd

        self.finished_panels_num = 0

        conn = self._getServerConnFromCmd(cmd)

        self.server.SetValue(conn["url"])
        self.password.SetValue(conn["password"])
        self.username.SetValue(conn["username"])

        self.layerName.SetValue(cmd[1]["map"])

        for ws, data in six.iteritems(self.ws_panels):
            cap_file = None

            if ws in ws_cap_files:
                cap_file = ws_cap_files[ws]

            data["panel"].ParseCapFile(
                url=conn["url"],
                username=conn["password"],
                password=conn["username"],
                cap_file=cap_file,
            )

    def _getServerConnFromCmd(self, cmd):
        """Get url/server/passwod from cmd tuple"""
        conn = {"url": "", "username": "", "password": ""}

        for k in six.iterkeys(conn):
            if k in cmd[1]:
                conn[k] = cmd[1][k]
        return conn

    def _apply(self):
        """Apply chosen values from widgets to web service layer."""
        lcmd = self.active_ws_panel.CreateCmd()
        if not lcmd:
            return

        active_ws = self.active_ws_panel.GetWebService()
        if "WMS" not in active_ws:
            lcmd.append("capfile=" + self.revert_ws_cap_files[active_ws])

        self.giface.GetLayerTree().GetOptData(dcmd=lcmd,
                                              layer=self.layer,
                                              params=True,
                                              propwin=self)

        # TODO use just list or tuple
        cmd = cmdlist_to_tuple(lcmd)
        self.revert_cmd = cmd
        self._setRevertCapFiles(self._getCapFiles())

        self.giface.updateMap.emit()

    def UpdateDialogAfterConnection(self):
        """Connect to the server"""
        WSDialogBase.UpdateDialogAfterConnection(self)
        if self._getConnectedWS():
            self.btn_ok.SetDefault()
        else:
            self.btn_connect.SetDefault()

    def OnApply(self, event):
        self._apply()

    def OnSave(self, event):
        self._apply()
        self._close()

    def OnClose(self, event):
        """Close dialog"""
        self._close()

    def _close(self):
        """Hide dialog"""
        self.Hide()
        self.LoadCapFiles(cmd=self.revert_cmd,
                          ws_cap_files=self.revert_ws_cap_files)

    def OnPanelCapParsed(self, error_msg):
        """Called when panel has downloaded and parsed capabilities file."""
        WSDialogBase.OnPanelCapParsed(self, error_msg)

        if self.finished_panels_num == len(self.ws_panels):
            if self.cmd_to_set:
                self._updateWsPanelWidgetsByCmd(self.cmd_to_set)
                self.cmd_to_set = None

    def _updateWsPanelWidgetsByCmd(self, cmd):
        """Set values of  widgets according to parameters in cmd."""

        ws = self._getWSfromCmd(cmd)
        if self.ws_panels[ws]["panel"].IsConnected():
            self.choose_ws_rb.SetStringSelection(self.ws_panels[ws]["label"])
            self._showWsPanel(ws)
            self.ws_panels[ws]["panel"].UpdateWidgetsByCmd(cmd)

    def _getWSfromCmd(self, cmd):
        driver = cmd[1]["driver"]
        ws = driver.split("_")[0]

        if ws == "WMS":
            ws += "_" + cmd[1]["wms_version"]
        return ws
Esempio n. 26
0
class ModifyTableRecord(wx.Dialog):
    def __init__(self,
                 parent,
                 title,
                 data,
                 keyEditable=(-1, True),
                 id=wx.ID_ANY,
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
        """Dialog for inserting/updating table record

        :param data: a list: [(column, value)]
        :param keyEditable: (id, editable?) indicates if textarea for
                            key column is editable(True) or not
        """
        # parent -> VDigitWindow
        wx.Dialog.__init__(self, parent, id, title, style=style)

        self.CenterOnParent()

        self.keyId = keyEditable[0]

        box = StaticBox(parent=self, id=wx.ID_ANY)
        box.Hide()
        self.dataPanel = scrolled.ScrolledPanel(parent=self,
                                                id=wx.ID_ANY,
                                                style=wx.TAB_TRAVERSAL)
        self.dataPanel.SetupScrolling(scroll_x=False)

        # buttons
        self.btnCancel = Button(self, wx.ID_CANCEL)
        self.btnSubmit = Button(self, wx.ID_OK, _("&Submit"))
        self.btnSubmit.SetDefault()

        # data area
        self.widgets = []
        cId = 0
        self.usebox = False
        self.cat = None
        winFocus = False

        for column, ctype, ctypeStr, value in data:
            if self.keyId == cId:
                self.cat = int(value)
                if not keyEditable[1]:
                    self.usebox = True
                    box.SetLabel(" %s %d " % (_("Category"), self.cat))
                    box.Show()
                    self.boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
                    cId += 1
                    continue
                else:
                    valueWin = SpinCtrl(parent=self.dataPanel,
                                        id=wx.ID_ANY,
                                        value=value,
                                        min=-1e9,
                                        max=1e9,
                                        size=(250, -1))
            else:
                valueWin = TextCtrl(parent=self.dataPanel,
                                    id=wx.ID_ANY,
                                    value=value,
                                    size=(250, -1))
                if ctype == int:
                    valueWin.SetValidator(IntegerValidator())
                elif ctype == float:
                    valueWin.SetValidator(FloatValidator())
                if not winFocus:
                    wx.CallAfter(valueWin.SetFocus)
                    winFocus = True

            label = StaticText(parent=self.dataPanel,
                               id=wx.ID_ANY,
                               label=column)
            ctype = StaticText(parent=self.dataPanel,
                               id=wx.ID_ANY,
                               label="[%s]:" % ctypeStr.lower())
            self.widgets.append(
                (label.GetId(), ctype.GetId(), valueWin.GetId()))

            cId += 1

        self._layout()

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

        # data area
        dataSizer = wx.FlexGridSizer(cols=3, hgap=3, vgap=3)
        dataSizer.AddGrowableCol(2)

        for labelId, ctypeId, valueId in self.widgets:
            label = self.FindWindowById(labelId)
            ctype = self.FindWindowById(ctypeId)
            value = self.FindWindowById(valueId)

            dataSizer.Add(label, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL)
            dataSizer.Add(ctype,
                          proportion=0,
                          flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
            dataSizer.Add(value,
                          proportion=0,
                          flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL)

        self.dataPanel.SetAutoLayout(True)
        self.dataPanel.SetSizer(dataSizer)
        dataSizer.Fit(self.dataPanel)

        if self.usebox:
            self.boxSizer.Add(self.dataPanel,
                              proportion=1,
                              flag=wx.EXPAND | wx.ALL,
                              border=5)

        # buttons
        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(self.btnCancel)
        btnSizer.AddButton(self.btnSubmit)
        btnSizer.Realize()

        if not self.usebox:
            sizer.Add(self.dataPanel,
                      proportion=1,
                      flag=wx.EXPAND | wx.ALL,
                      border=5)
        else:
            sizer.Add(self.boxSizer,
                      proportion=1,
                      flag=wx.EXPAND | wx.ALL,
                      border=5)

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

        framewidth = self.GetBestSize()[0] + 25
        self.SetMinSize((framewidth, 250))

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

        self.Layout()

    def GetValues(self, columns=None):
        """Return list of values (casted to string).

        If columns is given (list), return only values of given columns.
        """
        valueList = list()
        for labelId, ctypeId, valueId in self.widgets:
            column = self.FindWindowById(labelId).GetLabel()
            if columns is None or column in columns:
                value = GetUnicodeValue(
                    self.FindWindowById(valueId).GetValue())
                valueList.append(value)

        # add key value
        if self.usebox:
            valueList.insert(self.keyId, GetUnicodeValue(str(self.cat)))

        return valueList
Esempio n. 27
0
    def __init__(self, parent, transforms,
                 title=_("Select datum transformation"),
                 pos=wx.DefaultPosition, size=wx.DefaultSize,
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):

        wx.Dialog.__init__(self, parent, wx.ID_ANY, title, pos, size, style)

        global transformlist
        self.CentreOnParent()

        # default transform number
        self.transnum = 0

        panel = scrolled.ScrolledPanel(self, wx.ID_ANY)
        sizer = wx.BoxSizer(wx.VERTICAL)

        #
        # set panel sizer
        #
        panel.SetSizer(sizer)
        panel.SetupScrolling()

        #
        # dialog body
        #
        bodyBox = StaticBox(
            parent=panel, id=wx.ID_ANY, label=" %s " %
            _("Select from list of datum transformations"))
        bodySizer = wx.StaticBoxSizer(bodyBox)

        # add no transform option
        transforms = '---\n\n0\nDo not apply any datum transformations\n\n' + transforms

        transformlist = transforms.split('---')
        tlistlen = len(transformlist)

        # calculate size for transform list
        height = 0
        width = 0
        for line in transforms.splitlines():
            w, h = self.GetTextExtent(line)
            height += h
            width = max(width, w)

        height = height + 5
        if height > 400:
            height = 400
        width = width + 5
        if width > 400:
            width = 400

        #
        # VListBox for displaying and selecting transformations
        #
        self.translist = TransList(
            panel, id=-1, size=(width, height),
            style=wx.SUNKEN_BORDER)
        self.translist.SetItemCount(tlistlen)
        self.translist.SetSelection(2)
        self.translist.SetFocus()

        self.Bind(wx.EVT_LISTBOX, self.ClickTrans, self.translist)

        bodySizer.Add(
            self.translist,
            proportion=1,
            flag=wx.ALIGN_CENTER | wx.ALL | wx.EXPAND)

        #
        # buttons
        #
        btnsizer = wx.StdDialogButtonSizer()

        btn = Button(parent=panel, id=wx.ID_OK)
        btn.SetDefault()
        btnsizer.AddButton(btn)

        btn = Button(parent=panel, id=wx.ID_CANCEL)
        btnsizer.AddButton(btn)
        btnsizer.Realize()

        sizer.Add(bodySizer, proportion=1,
                  flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5)

        sizer.Add(btnsizer, proportion=0,
                  flag=wx.ALL | wx.ALIGN_RIGHT, border=5)

        sizer.Fit(panel)

        self.SetSize(self.GetBestSize())
        self.Layout()
Esempio n. 28
0
class AddColumnDialog(wx.Dialog):
    def __init__(self,
                 parent,
                 title,
                 id=wx.ID_ANY,
                 style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER):
        """Dialog for adding column into table
        """
        wx.Dialog.__init__(self, parent, id, title, style=style)

        self.CenterOnParent()

        self.data = {}
        self.data['addColName'] = TextCtrl(parent=self,
                                           id=wx.ID_ANY,
                                           value='',
                                           size=(150, -1),
                                           style=wx.TE_PROCESS_ENTER)

        self.data['addColType'] = wx.Choice(
            parent=self,
            id=wx.ID_ANY,
            choices=["integer", "double", "varchar", "date"])  # FIXME
        self.data['addColType'].SetSelection(0)
        self.data['addColType'].Bind(wx.EVT_CHOICE, self.OnTableChangeType)

        self.data['addColLength'] = SpinCtrl(parent=self,
                                             id=wx.ID_ANY,
                                             size=(65, -1),
                                             initial=250,
                                             min=1,
                                             max=1e6)
        self.data['addColLength'].Enable(False)

        # buttons
        self.btnCancel = Button(self, wx.ID_CANCEL)
        self.btnOk = Button(self, wx.ID_OK)
        self.btnOk.SetDefault()

        self._layout()

    def _layout(self):

        sizer = wx.BoxSizer(wx.VERTICAL)
        addSizer = wx.BoxSizer(wx.HORIZONTAL)

        addSizer.Add(StaticText(parent=self, id=wx.ID_ANY, label=_("Column")),
                     flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
                     border=5)
        addSizer.Add(self.data['addColName'],
                     proportion=1,
                     flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
                     border=5)

        addSizer.Add(StaticText(parent=self, id=wx.ID_ANY, label=_("Type")),
                     flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
                     border=5)
        addSizer.Add(self.data['addColType'],
                     flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
                     border=5)

        addSizer.Add(StaticText(parent=self, id=wx.ID_ANY, label=_("Length")),
                     flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
                     border=5)
        addSizer.Add(self.data['addColLength'],
                     flag=wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT,
                     border=5)

        sizer.Add(addSizer,
                  proportion=0,
                  flag=wx.ALIGN_RIGHT | wx.ALL,
                  border=5)

        btnSizer = wx.StdDialogButtonSizer()
        btnSizer.AddButton(self.btnCancel)
        btnSizer.AddButton(self.btnOk)
        btnSizer.Realize()

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

        self.SetSizer(sizer)

        self.Fit()

    def GetData(self):
        """Get inserted data from dialog's widgets"""
        values = {}
        values['name'] = self.data['addColName'].GetValue()
        values['ctype'] = self.data['addColType'].GetStringSelection()
        values['length'] = int(self.data['addColLength'].GetValue())

        return values

    def OnTableChangeType(self, event):
        """Data type for new column changed. Enable or disable
        data length widget"""
        if event.GetString() == "varchar":
            self.data['addColLength'].Enable(True)
        else:
            self.data['addColLength'].Enable(False)
Esempio n. 29
0
class SettingsDialog(wx.Dialog):

    def __init__(
            self, parent, id, title, scatt_mgr, pos=wx.DefaultPosition,
            size=wx.DefaultSize, style=wx.DEFAULT_DIALOG_STYLE):
        """Settings dialog"""
        wx.Dialog.__init__(self, parent, id, title, pos, size, style)

        self.scatt_mgr = scatt_mgr

        maxValue = 1e8
        self.parent = parent
        self.settings = {}

        settsLabels = {}

        self.settings["show_ellips"] = wx.CheckBox(
            parent=self, id=wx.ID_ANY, label=_('Show confidence ellipses'))
        show_ellips = UserSettings.Get(
            group='scatt', key="ellipses", subkey="show_ellips")
        self.settings["show_ellips"].SetValue(show_ellips)

        self.colorsSetts = {
            "sel_pol": [
                "selection", _("Selection polygon color:")], "sel_pol_vertex": [
                "selection", _("Color of selection polygon vertex:")], "sel_area": [
                "selection", _("Selected area color:")]}

        for settKey, sett in six.iteritems(self.colorsSetts):
            settsLabels[settKey] = StaticText(
                parent=self, id=wx.ID_ANY, label=sett[1])
            col = UserSettings.Get(group='scatt', key=sett[0], subkey=settKey)
            self.settings[settKey] = csel.ColourSelect(
                parent=self, id=wx.ID_ANY, colour=wx.Colour(
                    col[0], col[1], col[2], 255))

        self.sizeSetts = {
            "snap_tresh": ["selection", _("Snapping threshold in pixels:")],
            "sel_area_opacty": ["selection", _("Selected area opacity:")]
        }

        for settKey, sett in six.iteritems(self.sizeSetts):
            settsLabels[settKey] = StaticText(
                parent=self, id=wx.ID_ANY, label=sett[1])
            self.settings[settKey] = SpinCtrl(
                parent=self, id=wx.ID_ANY, min=0, max=100)
            size = int(
                UserSettings.Get(
                    group='scatt',
                    key=sett[0],
                    subkey=settKey))
            self.settings[settKey].SetValue(size)

        # buttons
        self.btnSave = Button(self, wx.ID_SAVE)
        self.btnApply = Button(self, wx.ID_APPLY)
        self.btnClose = Button(self, wx.ID_CLOSE)
        self.btnApply.SetDefault()

        # bindings
        self.btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
        self.btnApply.SetToolTip(
            _("Apply changes for the current session"))
        self.btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
        self.btnSave.SetToolTip(
            _("Apply and save changes to user settings file (default for next sessions)"))
        self.btnClose.Bind(wx.EVT_BUTTON, self.OnClose)
        self.btnClose.SetToolTip(_("Close dialog"))

        # Layout

        # Analysis result style layout
        self.SetMinSize(self.GetBestSize())

        sizer = wx.BoxSizer(wx.VERTICAL)

        sel_pol_box = StaticBox(parent=self, id=wx.ID_ANY,
                                label=" %s " % _("Selection style:"))
        selPolBoxSizer = wx.StaticBoxSizer(sel_pol_box, wx.VERTICAL)

        gridSizer = wx.GridBagSizer(vgap=1, hgap=1)

        row = 0
        setts = dict()
        setts.update(self.colorsSetts)
        setts.update(self.sizeSetts)

        settsOrder = ["sel_pol", "sel_pol_vertex", "sel_area",
                      "sel_area_opacty", "snap_tresh"]
        for settKey in settsOrder:
            sett = setts[settKey]
            gridSizer.Add(
                settsLabels[settKey],
                flag=wx.ALIGN_CENTER_VERTICAL,
                pos=(
                    row,
                    0))
            gridSizer.Add(self.settings[settKey],
                          flag=wx.ALIGN_RIGHT | wx.ALL, border=5,
                          pos=(row, 1))
            row += 1

        gridSizer.AddGrowableCol(1)
        selPolBoxSizer.Add(gridSizer, flag=wx.EXPAND)

        ell_box = StaticBox(parent=self, id=wx.ID_ANY,
                            label=" %s " % _("Ellipses settings:"))
        ellPolBoxSizer = wx.StaticBoxSizer(ell_box, wx.VERTICAL)
        gridSizer = wx.GridBagSizer(vgap=1, hgap=1)

        sett = setts[settKey]

        row = 0
        gridSizer.Add(self.settings["show_ellips"],
                      flag=wx.ALIGN_CENTER_VERTICAL,
                      pos=(row, 0))

        gridSizer.AddGrowableCol(0)
        ellPolBoxSizer.Add(gridSizer, flag=wx.EXPAND)

        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(self.btnApply, flag=wx.LEFT | wx.RIGHT, border=5)
        btnSizer.Add(self.btnSave, flag=wx.LEFT | wx.RIGHT, border=5)
        btnSizer.Add(self.btnClose, flag=wx.LEFT | wx.RIGHT, border=5)

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

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

    def OnSave(self, event):
        """Button 'Save' pressed"""
        self.UpdateSettings()

        fileSettings = {}
        UserSettings.ReadSettingsFile(settings=fileSettings)
        fileSettings['scatt'] = UserSettings.Get(group='scatt')
        UserSettings.SaveToFile(fileSettings)

        self.Close()

    def UpdateSettings(self):

        chanaged_setts = []
        for settKey, sett in six.iteritems(self.colorsSetts):
            col = tuple(self.settings[settKey].GetColour())
            col_s = UserSettings.Get(
                group='scatt', key=sett[0], subkey=settKey)
            if col_s != col:
                UserSettings.Set(group='scatt',
                                 key=sett[0],
                                 subkey=settKey,
                                 value=col)
                chanaged_setts.append([settKey, sett[0]])

        for settKey, sett in six.iteritems(self.sizeSetts):
            val = self.settings[settKey].GetValue()
            val_s = UserSettings.Get(
                group='scatt', key=sett[0], subkey=settKey)

            if val_s != val:
                UserSettings.Set(group='scatt', key=sett[0], subkey=settKey,
                                 value=val)
                chanaged_setts.append([settKey, sett[0]])

        val = self.settings['show_ellips'].IsChecked()
        val_s = UserSettings.Get(
            group='scatt',
            key='ellipses',
            subkey='show_ellips')

        if val != val_s:
            UserSettings.Set(
                group='scatt',
                key='ellipses',
                subkey='show_ellips',
                value=val)
            chanaged_setts.append(['ellipses', 'show_ellips'])

        if chanaged_setts:
            self.scatt_mgr.SettingsUpdated(chanaged_setts)

    def OnApply(self, event):
        """Button 'Apply' pressed"""
        self.UpdateSettings()
        # self.Close()

    def OnClose(self, event):
        """Button 'Cancel' pressed"""
        self.Close()
Esempio n. 30
0
class GRASSStartup(wx.Frame):
    exit_success = 0
    # 2 is file not found from python interpreter
    exit_user_requested = 5
    """GRASS start-up screen"""
    def __init__(self,
                 parent=None,
                 id=wx.ID_ANY,
                 style=wx.DEFAULT_FRAME_STYLE):

        #
        # GRASS variables
        #
        self.gisbase = os.getenv("GISBASE")
        self.grassrc = sgui.read_gisrc()
        self.gisdbase = self.GetRCValue("GISDBASE")

        #
        # list of locations/mapsets
        #
        self.listOfLocations = []
        self.listOfMapsets = []
        self.listOfMapsetsSelectable = []

        wx.Frame.__init__(self, parent=parent, id=id, style=style)

        self.locale = wx.Locale(language=wx.LANGUAGE_DEFAULT)

        # scroll panel was used here but not properly and is probably not need
        # as long as it is not high too much
        self.panel = wx.Panel(parent=self, id=wx.ID_ANY)

        # i18N

        #
        # graphical elements
        #
        # image
        try:
            if os.getenv('ISISROOT'):
                name = os.path.join(globalvar.GUIDIR, "images",
                                    "startup_banner_isis.png")
            else:
                name = os.path.join(globalvar.GUIDIR, "images",
                                    "startup_banner.png")
            self.hbitmap = wx.StaticBitmap(
                self.panel, wx.ID_ANY,
                wx.Bitmap(name=name, type=wx.BITMAP_TYPE_PNG))
        except:
            self.hbitmap = wx.StaticBitmap(
                self.panel, wx.ID_ANY, BitmapFromImage(wx.EmptyImage(530,
                                                                     150)))

        # labels
        # crashes when LOCATION doesn't exist
        # get version & revision
        grassVersion, grassRevisionStr = sgui.GetVersion()

        self.gisdbase_box = StaticBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=" %s " % _("1. Select GRASS GIS database directory"))
        self.location_box = StaticBox(parent=self.panel,
                                      id=wx.ID_ANY,
                                      label=" %s " %
                                      _("2. Select GRASS Location"))
        self.mapset_box = StaticBox(parent=self.panel,
                                    id=wx.ID_ANY,
                                    label=" %s " % _("3. Select GRASS Mapset"))

        self.lmessage = StaticText(parent=self.panel)
        # It is not clear if all wx versions supports color, so try-except.
        # The color itself may not be correct for all platforms/system settings
        # but in http://xoomer.virgilio.it/infinity77/wxPython/Widgets/wx.SystemSettings.html
        # there is no 'warning' color.
        try:
            self.lmessage.SetForegroundColour(wx.Colour(255, 0, 0))
        except AttributeError:
            pass

        self.gisdbase_panel = wx.Panel(parent=self.panel)
        self.location_panel = wx.Panel(parent=self.panel)
        self.mapset_panel = wx.Panel(parent=self.panel)

        self.ldbase = StaticText(
            parent=self.gisdbase_panel,
            id=wx.ID_ANY,
            label=_("GRASS GIS database directory contains Locations."))

        self.llocation = StaticWrapText(
            parent=self.location_panel,
            id=wx.ID_ANY,
            label=_("All data in one Location is in the same "
                    " coordinate reference system (projection)."
                    " One Location can be one project."
                    " Location contains Mapsets."),
            style=wx.ALIGN_LEFT)

        self.lmapset = StaticWrapText(
            parent=self.mapset_panel,
            id=wx.ID_ANY,
            label=_("Mapset contains GIS data related"
                    " to one project, task within one project,"
                    " subregion or user."),
            style=wx.ALIGN_LEFT)

        try:
            for label in [self.ldbase, self.llocation, self.lmapset]:
                label.SetForegroundColour(
                    wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT))
        except AttributeError:
            # for explanation of try-except see above
            pass

        # buttons
        self.bstart = Button(parent=self.panel,
                             id=wx.ID_ANY,
                             label=_("Start &GRASS session"))
        self.bstart.SetDefault()
        self.bexit = Button(parent=self.panel, id=wx.ID_EXIT)
        self.bstart.SetMinSize((180, self.bexit.GetSize()[1]))
        self.bhelp = Button(parent=self.panel, id=wx.ID_HELP)
        self.bbrowse = Button(parent=self.gisdbase_panel,
                              id=wx.ID_ANY,
                              label=_("&Browse"))
        self.bmapset = Button(
            parent=self.mapset_panel,
            id=wx.ID_ANY,
            # GTC New mapset
            label=_("&New"))
        self.bmapset.SetToolTip(_("Create a new Mapset in selected Location"))
        self.bwizard = Button(
            parent=self.location_panel,
            id=wx.ID_ANY,
            # GTC New location
            label=_("N&ew"))
        self.bwizard.SetToolTip(
            _("Create a new location using location wizard."
              " After location is created successfully,"
              " GRASS session is started."))
        self.rename_location_button = Button(
            parent=self.location_panel,
            id=wx.ID_ANY,
            # GTC Rename location
            label=_("Ren&ame"))
        self.rename_location_button.SetToolTip(_("Rename selected location"))
        self.delete_location_button = Button(
            parent=self.location_panel,
            id=wx.ID_ANY,
            # GTC Delete location
            label=_("De&lete"))
        self.delete_location_button.SetToolTip(_("Delete selected location"))
        self.download_location_button = Button(parent=self.location_panel,
                                               id=wx.ID_ANY,
                                               label=_("Do&wnload"))
        self.download_location_button.SetToolTip(_("Download sample location"))

        self.rename_mapset_button = Button(
            parent=self.mapset_panel,
            id=wx.ID_ANY,
            # GTC Rename mapset
            label=_("&Rename"))
        self.rename_mapset_button.SetToolTip(_("Rename selected mapset"))
        self.delete_mapset_button = Button(
            parent=self.mapset_panel,
            id=wx.ID_ANY,
            # GTC Delete mapset
            label=_("&Delete"))
        self.delete_mapset_button.SetToolTip(_("Delete selected mapset"))

        # textinputs
        self.tgisdbase = TextCtrl(parent=self.gisdbase_panel,
                                  id=wx.ID_ANY,
                                  value="",
                                  size=(300, -1),
                                  style=wx.TE_PROCESS_ENTER)

        # Locations
        self.lblocations = GListBox(parent=self.location_panel,
                                    id=wx.ID_ANY,
                                    size=(180, 200),
                                    choices=self.listOfLocations)
        self.lblocations.SetColumnWidth(0, 180)

        # TODO: sort; but keep PERMANENT on top of list
        # Mapsets
        self.lbmapsets = GListBox(parent=self.mapset_panel,
                                  id=wx.ID_ANY,
                                  size=(180, 200),
                                  choices=self.listOfMapsets)
        self.lbmapsets.SetColumnWidth(0, 180)

        # layout & properties, first do layout so everything is created
        self._do_layout()
        self._set_properties(grassVersion, grassRevisionStr)

        # events
        self.bbrowse.Bind(wx.EVT_BUTTON, self.OnBrowse)
        self.bstart.Bind(wx.EVT_BUTTON, self.OnStart)
        self.bexit.Bind(wx.EVT_BUTTON, self.OnExit)
        self.bhelp.Bind(wx.EVT_BUTTON, self.OnHelp)
        self.bmapset.Bind(wx.EVT_BUTTON, self.OnCreateMapset)
        self.bwizard.Bind(wx.EVT_BUTTON, self.OnWizard)

        self.rename_location_button.Bind(wx.EVT_BUTTON, self.RenameLocation)
        self.delete_location_button.Bind(wx.EVT_BUTTON, self.DeleteLocation)
        self.download_location_button.Bind(wx.EVT_BUTTON,
                                           self.DownloadLocation)
        self.rename_mapset_button.Bind(wx.EVT_BUTTON, self.RenameMapset)
        self.delete_mapset_button.Bind(wx.EVT_BUTTON, self.DeleteMapset)

        self.lblocations.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelectLocation)
        self.lbmapsets.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnSelectMapset)
        self.lbmapsets.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self.OnStart)
        self.tgisdbase.Bind(wx.EVT_TEXT_ENTER, self.OnSetDatabase)
        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

    def _set_properties(self, version, revision):
        """Set frame properties

        :param version: Version in the form of X.Y.Z
        :param revision: Version control revision with leading space

        *revision* should be an empty string in case of release and
        otherwise it needs a leading space to be separated from the rest
        of the title.
        """
        self.SetTitle(_("GRASS GIS %s Startup%s") % (version, revision))
        self.SetIcon(
            wx.Icon(os.path.join(globalvar.ICONDIR, "grass.ico"),
                    wx.BITMAP_TYPE_ICO))

        self.bstart.SetForegroundColour(wx.Colour(35, 142, 35))
        self.bstart.SetToolTip(_("Enter GRASS session"))
        self.bstart.Enable(False)
        self.bmapset.Enable(False)
        # this all was originally a choice, perhaps just mapset needed
        self.rename_location_button.Enable(False)
        self.delete_location_button.Enable(False)
        self.rename_mapset_button.Enable(False)
        self.delete_mapset_button.Enable(False)

        # set database
        if not self.gisdbase:
            # sets an initial path for gisdbase if nothing in GISRC
            if os.path.isdir(os.getenv("HOME")):
                self.gisdbase = os.getenv("HOME")
            else:
                self.gisdbase = os.getcwd()
        try:
            self.tgisdbase.SetValue(self.gisdbase)
        except UnicodeDecodeError:
            wx.MessageBox(parent=self,
                          caption=_("Error"),
                          message=_("Unable to set GRASS database. "
                                    "Check your locale settings."),
                          style=wx.OK | wx.ICON_ERROR | wx.CENTRE)

        self.OnSetDatabase(None)
        location = self.GetRCValue("LOCATION_NAME")
        if location == "<UNKNOWN>" or location is None:
            return
        if not os.path.isdir(os.path.join(self.gisdbase, location)):
            location = None

        # list of locations
        self.UpdateLocations(self.gisdbase)
        try:
            self.lblocations.SetSelection(self.listOfLocations.index(location),
                                          force=True)
            self.lblocations.EnsureVisible(
                self.listOfLocations.index(location))
        except ValueError:
            sys.stderr.write(
                _("ERROR: Location <%s> not found\n") %
                self.GetRCValue("LOCATION_NAME"))
            if len(self.listOfLocations) > 0:
                self.lblocations.SetSelection(0, force=True)
                self.lblocations.EnsureVisible(0)
                location = self.listOfLocations[0]
            else:
                return

        # list of mapsets
        self.UpdateMapsets(os.path.join(self.gisdbase, location))
        mapset = self.GetRCValue("MAPSET")
        if mapset:
            try:
                self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset),
                                            force=True)
                self.lbmapsets.EnsureVisible(self.listOfMapsets.index(mapset))
            except ValueError:
                sys.stderr.write(_("ERROR: Mapset <%s> not found\n") % mapset)
                self.lbmapsets.SetSelection(0, force=True)
                self.lbmapsets.EnsureVisible(0)

    def _do_layout(self):
        sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer = sizer  # for the layout call after changing message
        dbase_sizer = wx.BoxSizer(wx.HORIZONTAL)

        location_mapset_sizer = wx.BoxSizer(wx.HORIZONTAL)

        gisdbase_panel_sizer = wx.BoxSizer(wx.VERTICAL)
        gisdbase_boxsizer = wx.StaticBoxSizer(self.gisdbase_box, wx.VERTICAL)

        btns_sizer = wx.BoxSizer(wx.HORIZONTAL)

        self.gisdbase_panel.SetSizer(gisdbase_panel_sizer)

        # gis data directory

        gisdbase_boxsizer.Add(self.gisdbase_panel,
                              proportion=1,
                              flag=wx.EXPAND | wx.ALL,
                              border=1)

        gisdbase_panel_sizer.Add(dbase_sizer,
                                 proportion=1,
                                 flag=wx.EXPAND | wx.ALL,
                                 border=1)
        gisdbase_panel_sizer.Add(self.ldbase,
                                 proportion=0,
                                 flag=wx.EXPAND | wx.ALL,
                                 border=1)

        dbase_sizer.Add(self.tgisdbase,
                        proportion=1,
                        flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
                        border=1)
        dbase_sizer.Add(self.bbrowse,
                        proportion=0,
                        flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
                        border=1)

        gisdbase_panel_sizer.Fit(self.gisdbase_panel)

        # location and mapset lists

        def layout_list_box(box, panel, list_box, buttons, description):
            panel_sizer = wx.BoxSizer(wx.VERTICAL)
            main_sizer = wx.BoxSizer(wx.HORIZONTAL)
            box_sizer = wx.StaticBoxSizer(box, wx.VERTICAL)
            buttons_sizer = wx.BoxSizer(wx.VERTICAL)

            panel.SetSizer(panel_sizer)
            panel_sizer.Fit(panel)

            main_sizer.Add(list_box,
                           proportion=1,
                           flag=wx.EXPAND | wx.ALL,
                           border=1)
            main_sizer.Add(buttons_sizer,
                           proportion=0,
                           flag=wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
                           border=1)
            for button in buttons:
                buttons_sizer.Add(button,
                                  proportion=0,
                                  flag=wx.EXPAND | wx.LEFT | wx.RIGHT
                                  | wx.BOTTOM,
                                  border=3)
            box_sizer.Add(panel,
                          proportion=1,
                          flag=wx.EXPAND | wx.ALL,
                          border=1)
            panel_sizer.Add(main_sizer,
                            proportion=1,
                            flag=wx.EXPAND | wx.ALL,
                            border=1)
            panel_sizer.Add(description,
                            proportion=0,
                            flag=wx.EXPAND | wx.ALL,
                            border=1)
            return box_sizer

        location_boxsizer = layout_list_box(box=self.location_box,
                                            panel=self.location_panel,
                                            list_box=self.lblocations,
                                            buttons=[
                                                self.bwizard,
                                                self.rename_location_button,
                                                self.delete_location_button,
                                                self.download_location_button
                                            ],
                                            description=self.llocation)
        mapset_boxsizer = layout_list_box(box=self.mapset_box,
                                          panel=self.mapset_panel,
                                          list_box=self.lbmapsets,
                                          buttons=[
                                              self.bmapset,
                                              self.rename_mapset_button,
                                              self.delete_mapset_button
                                          ],
                                          description=self.lmapset)

        # location and mapset sizer
        location_mapset_sizer.Add(location_boxsizer,
                                  proportion=1,
                                  flag=wx.LEFT | wx.RIGHT | wx.EXPAND,
                                  border=3)
        location_mapset_sizer.Add(mapset_boxsizer,
                                  proportion=1,
                                  flag=wx.RIGHT | wx.EXPAND,
                                  border=3)

        # buttons
        btns_sizer.Add(self.bstart,
                       proportion=0,
                       flag=wx.ALIGN_CENTER_HORIZONTAL
                       | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
                       border=5)
        btns_sizer.Add(self.bexit,
                       proportion=0,
                       flag=wx.ALIGN_CENTER_HORIZONTAL
                       | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
                       border=5)
        btns_sizer.Add(self.bhelp,
                       proportion=0,
                       flag=wx.ALIGN_CENTER_HORIZONTAL
                       | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
                       border=5)

        # main sizer
        sizer.Add(self.hbitmap,
                  proportion=0,
                  flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL
                  | wx.ALL,
                  border=3)  # image
        sizer.Add(gisdbase_boxsizer,
                  proportion=0,
                  flag=wx.ALIGN_CENTER_HORIZONTAL | wx.RIGHT | wx.LEFT | wx.TOP
                  | wx.EXPAND,
                  border=3)  # GISDBASE setting

        # warning/error message
        sizer.Add(self.lmessage,
                  proportion=0,
                  flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.ALL
                  | wx.EXPAND,
                  border=5)
        sizer.Add(location_mapset_sizer,
                  proportion=1,
                  flag=wx.RIGHT | wx.LEFT | wx.EXPAND,
                  border=1)
        sizer.Add(btns_sizer,
                  proportion=0,
                  flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL
                  | wx.RIGHT | wx.LEFT,
                  border=3)

        self.panel.SetAutoLayout(True)
        self.panel.SetSizer(sizer)
        sizer.Fit(self.panel)
        sizer.SetSizeHints(self)
        self.Layout()

    def _showWarning(self, text):
        """Displays a warning, hint or info message to the user.

        This function can be used for all kinds of messages except for
        error messages.

        .. note::
            There is no cleaning procedure. You should call _hideMessage when
            you know that there is everything correct now.
        """
        self.lmessage.SetLabel(text)
        self.lmessage.Wrap(self.GetClientSize()[0])
        self.sizer.Layout()

    def _showError(self, text):
        """Displays a error message to the user.

        This function should be used only when something serious and unexpected
        happens, otherwise _showWarning should be used.

        .. note::
            There is no cleaning procedure. You should call _hideMessage when
            you know that there is everything correct now.
        """
        self.lmessage.SetLabel(_("Error: {text}").format(text=text))
        self.lmessage.Wrap(self.GetClientSize()[0])
        self.sizer.Layout()

    def _hideMessage(self):
        """Clears/hides the error message."""
        # we do no hide widget
        # because we do not want the dialog to change the size
        self.lmessage.SetLabel("")
        self.sizer.Layout()

    def GetRCValue(self, value):
        """Return GRASS variable (read from GISRC)
        """
        if value in self.grassrc:
            return self.grassrc[value]
        else:
            return None

    def SuggestDatabase(self):
        """Suggest (set) possible GRASS Database value"""
        # only if nothing is set (<UNKNOWN> comes from init script)
        if self.GetRCValue("LOCATION_NAME") != "<UNKNOWN>":
            return
        path = get_possible_database_path()
        if path:
            try:
                self.tgisdbase.SetValue(path)
            except UnicodeDecodeError:
                # restore previous state
                # wizard gives error in this case, we just ignore
                path = None
                self.tgisdbase.SetValue(self.gisdbase)
            # if we still have path
            if path:
                self.gisdbase = path
                self.OnSetDatabase(None)
        else:
            # nothing found
            # TODO: should it be warning, hint or message?
            self._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.'))

    def OnWizard(self, event):
        """Location wizard started"""
        from location_wizard.wizard import LocationWizard
        gWizard = LocationWizard(parent=self,
                                 grassdatabase=self.tgisdbase.GetValue())
        if gWizard.location is not None:
            self.tgisdbase.SetValue(gWizard.grassdatabase)
            self.OnSetDatabase(None)
            self.UpdateMapsets(os.path.join(self.gisdbase, gWizard.location))
            self.lblocations.SetSelection(
                self.listOfLocations.index(gWizard.location))
            self.lbmapsets.SetSelection(0)
            self.SetLocation(self.gisdbase, gWizard.location, 'PERMANENT')
            if gWizard.georeffile:
                message = _(
                    "Do you want to import <%(name)s> to the newly created location?"
                ) % {
                    'name': gWizard.georeffile
                }
                dlg = wx.MessageDialog(parent=self,
                                       message=message,
                                       caption=_("Import data?"),
                                       style=wx.YES_NO | wx.YES_DEFAULT
                                       | wx.ICON_QUESTION)
                dlg.CenterOnParent()
                if dlg.ShowModal() == wx.ID_YES:
                    self.ImportFile(gWizard.georeffile)
                dlg.Destroy()
            if gWizard.default_region:
                defineRegion = RegionDef(self, location=gWizard.location)
                defineRegion.CenterOnParent()
                defineRegion.ShowModal()
                defineRegion.Destroy()

            if gWizard.user_mapset:
                self.OnCreateMapset(event)

    def ImportFile(self, filePath):
        """Tries to import file as vector or raster.

        If successfull sets default region from imported map.
        """
        RunCommand('db.connect', flags='c')
        mapName = os.path.splitext(os.path.basename(filePath))[0]
        vectors = RunCommand('v.in.ogr', input=filePath, flags='l', read=True)

        wx.BeginBusyCursor()
        wx.GetApp().Yield()
        if vectors:
            # vector detected
            returncode, error = RunCommand('v.in.ogr',
                                           input=filePath,
                                           output=mapName,
                                           flags='e',
                                           getErrorMsg=True)
        else:
            returncode, error = RunCommand('r.in.gdal',
                                           input=filePath,
                                           output=mapName,
                                           flags='e',
                                           getErrorMsg=True)
        wx.EndBusyCursor()

        if returncode != 0:
            GError(parent=self,
                   message=_("Import of <%(name)s> failed.\n"
                             "Reason: %(msg)s") % ({
                                 'name': filePath,
                                 'msg': error
                             }))
        else:
            GMessage(message=_(
                "Data file <%(name)s> imported successfully. "
                "The location's default region was set from this imported map."
            ) % {'name': filePath},
                     parent=self)

    # the event can be refactored out by using lambda in bind
    def RenameMapset(self, event):
        """Rename selected mapset
        """
        location = self.listOfLocations[self.lblocations.GetSelection()]
        mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]
        if mapset == 'PERMANENT':
            GMessage(
                parent=self,
                message=_(
                    'Mapset <PERMANENT> is required for valid GRASS location.\n\n'
                    'This mapset cannot be renamed.'))
            return

        dlg = TextEntryDialog(
            parent=self,
            message=_('Current name: %s\n\nEnter new name:') % mapset,
            caption=_('Rename selected mapset'),
            validator=GenericValidator(grass.legal_name,
                                       self._nameValidationFailed))

        if dlg.ShowModal() == wx.ID_OK:
            newmapset = dlg.GetValue()
            if newmapset == mapset:
                dlg.Destroy()
                return

            if newmapset in self.listOfMapsets:
                wx.MessageBox(
                    parent=self,
                    caption=_('Message'),
                    message=_('Unable to rename mapset.\n\n'
                              'Mapset <%s> already exists in location.') %
                    newmapset,
                    style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
            else:
                try:
                    sutils.rename_mapset(self.gisdbase, location, mapset,
                                         newmapset)
                    self.OnSelectLocation(None)
                    self.lbmapsets.SetSelection(
                        self.listOfMapsets.index(newmapset))
                except Exception as e:
                    wx.MessageBox(parent=self,
                                  caption=_('Error'),
                                  message=_('Unable to rename mapset.\n\n%s') %
                                  e,
                                  style=wx.OK | wx.ICON_ERROR | wx.CENTRE)

        dlg.Destroy()

    def RenameLocation(self, event):
        """Rename selected location
        """
        location = self.listOfLocations[self.lblocations.GetSelection()]

        dlg = TextEntryDialog(
            parent=self,
            message=_('Current name: %s\n\nEnter new name:') % location,
            caption=_('Rename selected location'),
            validator=GenericValidator(grass.legal_name,
                                       self._nameValidationFailed))

        if dlg.ShowModal() == wx.ID_OK:
            newlocation = dlg.GetValue()
            if newlocation == location:
                dlg.Destroy()
                return

            if newlocation in self.listOfLocations:
                wx.MessageBox(
                    parent=self,
                    caption=_('Message'),
                    message=_(
                        'Unable to rename location.\n\n'
                        'Location <%s> already exists in GRASS database.') %
                    newlocation,
                    style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
            else:
                try:
                    sutils.rename_location(self.gisdbase, location,
                                           newlocation)
                    self.UpdateLocations(self.gisdbase)
                    self.lblocations.SetSelection(
                        self.listOfLocations.index(newlocation))
                    self.UpdateMapsets(newlocation)
                except Exception as e:
                    wx.MessageBox(
                        parent=self,
                        caption=_('Error'),
                        message=_('Unable to rename location.\n\n%s') % e,
                        style=wx.OK | wx.ICON_ERROR | wx.CENTRE)

        dlg.Destroy()

    def DeleteMapset(self, event):
        """Delete selected mapset
        """
        location = self.listOfLocations[self.lblocations.GetSelection()]
        mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]
        if mapset == 'PERMANENT':
            GMessage(
                parent=self,
                message=_(
                    'Mapset <PERMANENT> is required for valid GRASS location.\n\n'
                    'This mapset cannot be deleted.'))
            return

        dlg = wx.MessageDialog(
            parent=self,
            message=_(
                "Do you want to continue with deleting mapset <%(mapset)s> "
                "from location <%(location)s>?\n\n"
                "ALL MAPS included in this mapset will be "
                "PERMANENTLY DELETED!") % {
                    'mapset': mapset,
                    'location': location
                },
            caption=_("Delete selected mapset"),
            style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)

        if dlg.ShowModal() == wx.ID_YES:
            try:
                sutils.delete_mapset(self.gisdbase, location, mapset)
                self.OnSelectLocation(None)
                self.lbmapsets.SetSelection(0)
            except:
                wx.MessageBox(message=_('Unable to delete mapset'))

        dlg.Destroy()

    def DeleteLocation(self, event):
        """
        Delete selected location
        """

        location = self.listOfLocations[self.lblocations.GetSelection()]

        dlg = wx.MessageDialog(
            parent=self,
            message=_("Do you want to continue with deleting "
                      "location <%s>?\n\n"
                      "ALL MAPS included in this location will be "
                      "PERMANENTLY DELETED!") % (location),
            caption=_("Delete selected location"),
            style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)

        if dlg.ShowModal() == wx.ID_YES:
            try:
                sutils.delete_location(self.gisdbase, location)
                self.UpdateLocations(self.gisdbase)
                self.lblocations.SetSelection(0)
                self.OnSelectLocation(None)
                self.lbmapsets.SetSelection(0)
            except:
                wx.MessageBox(message=_('Unable to delete location'))

        dlg.Destroy()

    def DownloadLocation(self, event):
        """Download location online"""
        from startup.locdownload import LocationDownloadDialog

        loc_download = LocationDownloadDialog(parent=self,
                                              database=self.gisdbase)
        loc_download.ShowModal()
        location = loc_download.GetLocation()
        if location:
            # get the new location to the list
            self.UpdateLocations(self.gisdbase)
            # seems to be used in similar context
            self.UpdateMapsets(os.path.join(self.gisdbase, location))
            self.lblocations.SetSelection(self.listOfLocations.index(location))
            # wizard does this as well, not sure if needed
            self.SetLocation(self.gisdbase, location, 'PERMANENT')
            # seems to be used in similar context
            self.OnSelectLocation(None)
        loc_download.Destroy()

    def UpdateLocations(self, dbase):
        """Update list of locations"""
        try:
            self.listOfLocations = GetListOfLocations(dbase)
        except (UnicodeEncodeError, UnicodeDecodeError) as e:
            GError(parent=self,
                   message=_(
                       "Unicode error detected. "
                       "Check your locale settings. Details: {0}").format(e),
                   showTraceback=False)

        self.lblocations.Clear()
        self.lblocations.InsertItems(self.listOfLocations, 0)

        if len(self.listOfLocations) > 0:
            self._hideMessage()
            self.lblocations.SetSelection(0)
        else:
            self.lblocations.SetSelection(wx.NOT_FOUND)
            self._showWarning(
                _("No GRASS Location found in '%s'."
                  " Create a new Location or choose different"
                  " GRASS database directory.") % self.gisdbase)

        return self.listOfLocations

    def UpdateMapsets(self, location):
        """Update list of mapsets"""
        self.FormerMapsetSelection = wx.NOT_FOUND  # for non-selectable item

        self.listOfMapsetsSelectable = list()
        self.listOfMapsets = GetListOfMapsets(self.gisdbase, location)

        self.lbmapsets.Clear()

        # disable mapset with denied permission
        locationName = os.path.basename(location)

        ret = RunCommand('g.mapset',
                         read=True,
                         flags='l',
                         location=locationName,
                         gisdbase=self.gisdbase)

        if ret:
            for line in ret.splitlines():
                self.listOfMapsetsSelectable += line.split(' ')
        else:
            self.SetLocation(self.gisdbase, locationName, "PERMANENT")
            # first run only
            self.listOfMapsetsSelectable = copy.copy(self.listOfMapsets)

        disabled = []
        idx = 0
        for mapset in self.listOfMapsets:
            if mapset not in self.listOfMapsetsSelectable or \
                    get_lockfile_if_present(self.gisdbase,
                                            locationName, mapset):
                disabled.append(idx)
            idx += 1

        self.lbmapsets.InsertItems(self.listOfMapsets, 0, disabled=disabled)

        return self.listOfMapsets

    def OnSelectLocation(self, event):
        """Location selected"""
        if event:
            self.lblocations.SetSelection(event.GetIndex())

        if self.lblocations.GetSelection() != wx.NOT_FOUND:
            self.UpdateMapsets(
                os.path.join(
                    self.gisdbase,
                    self.listOfLocations[self.lblocations.GetSelection()]))
        else:
            self.listOfMapsets = []

        disabled = []
        idx = 0
        try:
            locationName = self.listOfLocations[
                self.lblocations.GetSelection()]
        except IndexError:
            locationName = ''

        for mapset in self.listOfMapsets:
            if mapset not in self.listOfMapsetsSelectable or \
                    get_lockfile_if_present(self.gisdbase,
                                            locationName, mapset):
                disabled.append(idx)
            idx += 1

        self.lbmapsets.Clear()
        self.lbmapsets.InsertItems(self.listOfMapsets, 0, disabled=disabled)

        if len(self.listOfMapsets) > 0:
            self.lbmapsets.SetSelection(0)
            if locationName:
                # enable start button when location and mapset is selected
                self.bstart.Enable()
                self.bstart.SetFocus()
                self.bmapset.Enable()
                # replacing disabled choice, perhaps just mapset needed
                self.rename_location_button.Enable()
                self.delete_location_button.Enable()
                self.rename_mapset_button.Enable()
                self.delete_mapset_button.Enable()
        else:
            self.lbmapsets.SetSelection(wx.NOT_FOUND)
            self.bstart.Enable(False)
            self.bmapset.Enable(False)
            # this all was originally a choice, perhaps just mapset needed
            self.rename_location_button.Enable(False)
            self.delete_location_button.Enable(False)
            self.rename_mapset_button.Enable(False)
            self.delete_mapset_button.Enable(False)

    def OnSelectMapset(self, event):
        """Mapset selected"""
        self.lbmapsets.SetSelection(event.GetIndex())

        if event.GetText() not in self.listOfMapsetsSelectable:
            self.lbmapsets.SetSelection(self.FormerMapsetSelection)
        else:
            self.FormerMapsetSelection = event.GetIndex()
            event.Skip()

    def OnSetDatabase(self, event):
        """Database set"""
        gisdbase = self.tgisdbase.GetValue()
        self._hideMessage()
        if not os.path.exists(gisdbase):
            self._showError(_("Path '%s' doesn't exist.") % gisdbase)
            return

        self.gisdbase = self.tgisdbase.GetValue()
        self.UpdateLocations(self.gisdbase)

        self.OnSelectLocation(None)

    def OnBrowse(self, event):
        """'Browse' button clicked"""
        if not event:
            defaultPath = os.getenv('HOME')
        else:
            defaultPath = ""

        dlg = wx.DirDialog(parent=self,
                           message=_("Choose GIS Data Directory"),
                           defaultPath=defaultPath,
                           style=wx.DD_DEFAULT_STYLE)

        if dlg.ShowModal() == wx.ID_OK:
            self.gisdbase = dlg.GetPath()
            self.tgisdbase.SetValue(self.gisdbase)
            self.OnSetDatabase(event)

        dlg.Destroy()

    def OnCreateMapset(self, event):
        """Create new mapset"""
        dlg = NewMapsetDialog(
            parent=self,
            default=self._getDefaultMapsetName(),
            validation_failed_handler=self._nameValidationFailed,
            help_hanlder=self.OnHelp,
        )
        if dlg.ShowModal() == wx.ID_OK:
            mapset = dlg.GetValue()
            return self.CreateNewMapset(mapset=mapset)
        else:
            return False

    def CreateNewMapset(self, mapset):
        if mapset in self.listOfMapsets:
            GMessage(parent=self,
                     message=_("Mapset <%s> already exists.") % mapset)
            return False

        if mapset.lower() == 'ogr':
            dlg1 = wx.MessageDialog(
                parent=self,
                message=_(
                    "Mapset <%s> is reserved for direct "
                    "read access to OGR layers. Please consider to use "
                    "another name for your mapset.\n\n"
                    "Are you really sure that you want to create this mapset?")
                % mapset,
                caption=_("Reserved mapset name"),
                style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
            ret = dlg1.ShowModal()
            dlg1.Destroy()
            if ret == wx.ID_NO:
                dlg1.Destroy()
                return False

        try:
            self.gisdbase = self.tgisdbase.GetValue()
            location = self.listOfLocations[self.lblocations.GetSelection()]
            create_mapset(self.gisdbase, location, mapset)
            self.OnSelectLocation(None)
            self.lbmapsets.SetSelection(self.listOfMapsets.index(mapset))
            self.bstart.SetFocus()

            return True
        except Exception as e:
            GError(parent=self,
                   message=_("Unable to create new mapset: %s") % e,
                   showTraceback=False)
            return False

    def OnStart(self, event):
        """'Start GRASS' button clicked"""
        dbase = self.tgisdbase.GetValue()
        location = self.listOfLocations[self.lblocations.GetSelection()]
        mapset = self.listOfMapsets[self.lbmapsets.GetSelection()]

        lockfile = get_lockfile_if_present(dbase, location, mapset)
        if lockfile:
            dlg = wx.MessageDialog(
                parent=self,
                message=_(
                    "GRASS is already running in selected mapset <%(mapset)s>\n"
                    "(file %(lock)s found).\n\n"
                    "Concurrent use not allowed.\n\n"
                    "Do you want to try to remove .gislock (note that you "
                    "need permission for this operation) and continue?") % {
                        'mapset': mapset,
                        'lock': lockfile
                    },
                caption=_("Lock file found"),
                style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.CENTRE)

            ret = dlg.ShowModal()
            dlg.Destroy()
            if ret == wx.ID_YES:
                dlg1 = wx.MessageDialog(
                    parent=self,
                    message=
                    _("ARE YOU REALLY SURE?\n\n"
                      "If you really are running another GRASS session doing this "
                      "could corrupt your data. Have another look in the processor "
                      "manager just to be sure..."),
                    caption=_("Lock file found"),
                    style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION
                    | wx.CENTRE)

                ret = dlg1.ShowModal()
                dlg1.Destroy()

                if ret == wx.ID_YES:
                    try:
                        os.remove(lockfile)
                    except IOError as e:
                        GError(
                            _("Unable to remove '%(lock)s'.\n\n"
                              "Details: %(reason)s") % {
                                  'lock': lockfile,
                                  'reason': e
                              })
                else:
                    return
            else:
                return
        self.SetLocation(dbase, location, mapset)
        self.ExitSuccessfully()

    def SetLocation(self, dbase, location, mapset):
        SetSessionMapset(dbase, location, mapset)

    def _getDefaultMapsetName(self):
        """Returns default name for mapset."""
        try:
            defaultName = getpass.getuser()
            # raise error if not ascii (not valid mapset name)
            defaultName.encode('ascii')
        except:  # whatever might go wrong
            defaultName = 'user'

        return defaultName

    def ExitSuccessfully(self):
        self.Destroy()
        sys.exit(self.exit_success)

    def OnExit(self, event):
        """'Exit' button clicked"""
        self.Destroy()
        sys.exit(self.exit_user_requested)

    def OnHelp(self, event):
        """'Help' button clicked"""

        # help text in lib/init/helptext.html
        RunCommand('g.manual', entry='helptext')

    def OnCloseWindow(self, event):
        """Close window event"""
        event.Skip()
        sys.exit(self.exit_user_requested)

    def _nameValidationFailed(self, ctrl):
        message = _(
            "Name <%(name)s> is not a valid name for location or mapset. "
            "Please use only ASCII characters excluding %(chars)s "
            "and space.") % {
                'name': ctrl.GetValue(),
                'chars': '/"\'@,=*~'
            }
        GError(parent=self, message=message, caption=_("Invalid name"))