Exemplo n.º 1
0
class RenameClassDialog(SimpleDialog):

    def __init__(self, parent, old_name, title=("Change class name")):
        SimpleDialog.__init__(self, parent, title)

        self.name = TextCtrl(self.panel, id=wx.ID_ANY)
        self.name.SetValue(old_name)

        self.dataSizer.Add(self.name, proportion=0,
                           flag=wx.EXPAND | wx.ALL, border=1)

        self.panel.SetSizer(self.sizer)
        self.name.SetMinSize((200, -1))
        self.sizer.Fit(self)

    def GetNewName(self):
        return self.name.GetValue()
Exemplo n.º 2
0
class ViewFrame(wx.Frame):

    def __init__(self, parent, conf, giface=None, id=wx.ID_ANY,
                 title=_("Modify the configuration file"),
                 style=wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER, **kwargs):
        # VARIABLES
        self.parent = parent
        self.rlipath = retRLiPath()
        self.confile = conf
        self.pathfile = os.path.join(self.rlipath, conf)
        wx.Frame.__init__(self, parent=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.confilesBox = StaticBox(
            parent=self.panel, id=wx.ID_ANY, label=_(
                "View and modify the "
                "configuration file '{name}'".format(
                    name=self.confile)))
        self.textCtrl = TextCtrl(parent=self.panel, id=wx.ID_ANY,
                                 style=wx.TE_MULTILINE, size=(-1, 75))
        self.textCtrl.Bind(wx.EVT_TEXT, self.OnFileText)
        f = open(self.pathfile)
        self.textCtrl.SetValue(''.join(f.readlines()))
        f.close()
        # BUTTONS      #definition
        self.btn_close = Button(parent=self, id=wx.ID_EXIT)
        self.btn_ok = Button(parent=self, id=wx.ID_SAVE)
        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
        self.btn_ok.Bind(wx.EVT_BUTTON, self.OnOk)
        self._layout()
        self.enc = locale.getdefaultlocale()[1]

    def _layout(self):
        """Set the layout"""
        panelsizer = wx.GridBagSizer(1, 1)
        mainsizer = wx.BoxSizer(wx.VERTICAL)
        # CONFILES
        confilesSizer = wx.StaticBoxSizer(self.confilesBox, wx.HORIZONTAL)
        confilesSizer.Add(self.textCtrl, proportion=1, flag=wx.EXPAND)
        # END CONFILES
        # BUTTONS
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
        buttonSizer.Add(self.btn_ok, flag=wx.ALL, border=5)
        buttonSizer.Add(self.btn_close, flag=wx.ALL, border=5)
        # END BUTTONS
        # add listbox to staticbox
        panelsizer.Add(confilesSizer, pos=(0, 0), flag=wx.EXPAND,
                       border=3)
        # add panel and buttons
        mainsizer.Add(self.panel, proportion=1, flag=wx.EXPAND, border=3)
        mainsizer.Add(buttonSizer, proportion=0, flag=wx.EXPAND, border=3)
        panelsizer.AddGrowableRow(0)
        panelsizer.AddGrowableCol(0)
        self.panel.SetAutoLayout(True)
        self.panel.SetSizerAndFit(panelsizer)
        self.SetSizer(mainsizer)
        self.Layout()

    def OnClose(self, event):
        """Close window"""
        self.Destroy()

    def OnOk(self, event):
        """Launches help"""
        dlg = wx.MessageDialog(
            parent=self.parent,
            message=_(
                "Are you sure that you want modify"
                " r.li configuration file {name}?"
                "\nYou could broke the configuration"
                " file...").format(
                name=self.confile),
            caption=_("WARNING"),
            style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_WARNING)

        if dlg.ShowModal() == wx.ID_YES:
            f = codecs.open(self.pathfile, encoding=self.enc, mode='w',
                            errors='replace')
            f.write(self.text + os.linesep)
            f.close()
        dlg.Destroy()
        self.Destroy()

    def OnFileText(self, event):
        """File input interactively entered"""
        self.text = event.GetString()
Exemplo n.º 3
0
class RegionDef(BaseClass, wx.Dialog):
    """Page for setting default region extents and resolution
    """

    def __init__(self, parent, id=wx.ID_ANY, size=(800, 600), title=_(
            "Set default region extent and resolution"), location=None):
        wx.Dialog.__init__(self, parent, id, title, size=size)
        panel = wx.Panel(self, id=wx.ID_ANY)

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

        self.parent = parent
        self.location = location

        #
        # default values
        #
        # 2D
        self.north = 1.0
        self.south = 0.0
        self.east = 1.0
        self.west = 0.0
        self.nsres = 1.0
        self.ewres = 1.0
        # 3D
        self.top = 1.0
        self.bottom = 0.0
        #         self.nsres3 = 1.0
        #         self.ewres3 = 1.0
        self.tbres = 1.0

        #
        # inputs
        #
        # 2D
        self.tnorth = self.MakeTextCtrl(
            text=str(
                self.north), size=(
                150, -1), parent=panel)
        self.tsouth = self.MakeTextCtrl(
            str(self.south),
            size=(150, -1),
            parent=panel)
        self.twest = self.MakeTextCtrl(
            str(self.west),
            size=(150, -1),
            parent=panel)
        self.teast = self.MakeTextCtrl(
            str(self.east),
            size=(150, -1),
            parent=panel)
        self.tnsres = self.MakeTextCtrl(
            str(self.nsres),
            size=(150, -1),
            parent=panel)
        self.tewres = self.MakeTextCtrl(
            str(self.ewres),
            size=(150, -1),
            parent=panel)

        #
        # labels
        #
        self.lrows = self.MakeLabel(parent=panel)
        self.lcols = self.MakeLabel(parent=panel)
        self.lcells = self.MakeLabel(parent=panel)

        #
        # buttons
        #
        self.bset = self.MakeButton(
            text=_("&Set region"),
            id=wx.ID_OK, parent=panel)
        self.bcancel = Button(panel, id=wx.ID_CANCEL)
        self.bset.SetDefault()

        #
        # image
        #
        self.img = wx.Image(os.path.join(globalvar.IMGDIR, "qgis_world.png"),
                            wx.BITMAP_TYPE_PNG).ConvertToBitmap()

        #
        # set current working environment to PERMANENT mapset
        # in selected location in order to set default region (WIND)
        #
        envval = {}
        ret = RunCommand('g.gisenv',
                         read=True)
        if ret:
            for line in ret.splitlines():
                key, val = line.split('=')
                envval[key] = val
            self.currlocation = envval['LOCATION_NAME'].strip("';")
            self.currmapset = envval['MAPSET'].strip("';")
            if self.currlocation != self.location or self.currmapset != 'PERMANENT':
                RunCommand('g.gisenv',
                           set='LOCATION_NAME=%s' % self.location)
                RunCommand('g.gisenv',
                           set='MAPSET=PERMANENT')
        else:
            dlg = wx.MessageBox(
                parent=self,
                message=_('Invalid location selected.'),
                caption=_("Error"),
                style=wx.ID_OK | wx.ICON_ERROR)
            return

        #
        # get current region settings
        #
        region = {}
        ret = RunCommand('g.region',
                         read=True,
                         flags='gp3')
        if ret:
            for line in ret.splitlines():
                key, val = line.split('=')
                region[key] = float(val)
        else:
            dlg = wx.MessageBox(
                parent=self,
                message=_("Invalid region"),
                caption=_("Error"),
                style=wx.ID_OK | wx.ICON_ERROR)
            dlg.ShowModal()
            dlg.Destroy()
            return

        #
        # update values
        # 2D
        self.north = float(region['n'])
        self.south = float(region['s'])
        self.east = float(region['e'])
        self.west = float(region['w'])
        self.nsres = float(region['nsres'])
        self.ewres = float(region['ewres'])
        self.rows = int(region['rows'])
        self.cols = int(region['cols'])
        self.cells = int(region['cells'])
        # 3D
        self.top = float(region['t'])
        self.bottom = float(region['b'])
        #         self.nsres3 = float(region['nsres3'])
        #         self.ewres3 = float(region['ewres3'])
        self.tbres = float(region['tbres'])
        self.depth = int(region['depths'])
        self.cells3 = int(region['cells3'])

        #
        # 3D box collapsable
        #
        self.infoCollapseLabelExp = _("Click here to show 3D settings")
        self.infoCollapseLabelCol = _("Click here to hide 3D settings")
        self.settings3D = wx.CollapsiblePane(parent=panel,
                                             label=self.infoCollapseLabelExp,
                                             style=wx.CP_DEFAULT_STYLE |
                                             wx.CP_NO_TLW_RESIZE | wx.EXPAND)
        self.MakeSettings3DPaneContent(self.settings3D.GetPane())
        self.settings3D.Collapse(False)  # FIXME
        self.Bind(
            wx.EVT_COLLAPSIBLEPANE_CHANGED,
            self.OnSettings3DPaneChanged,
            self.settings3D)

        #
        # set current region settings
        #
        self.tnorth.SetValue(str(self.north))
        self.tsouth.SetValue(str(self.south))
        self.twest.SetValue(str(self.west))
        self.teast.SetValue(str(self.east))
        self.tnsres.SetValue(str(self.nsres))
        self.tewres.SetValue(str(self.ewres))
        self.ttop.SetValue(str(self.top))
        self.tbottom.SetValue(str(self.bottom))
        #         self.tnsres3.SetValue(str(self.nsres3))
        #         self.tewres3.SetValue(str(self.ewres3))
        self.ttbres.SetValue(str(self.tbres))
        self.lrows.SetLabel(_("Rows: %d") % self.rows)
        self.lcols.SetLabel(_("Cols: %d") % self.cols)
        self.lcells.SetLabel(_("Cells: %d") % self.cells)

        #
        # bindings
        #
        self.Bind(wx.EVT_BUTTON, self.OnSetButton, self.bset)
        self.Bind(wx.EVT_BUTTON, self.OnCancel, self.bcancel)
        self.tnorth.Bind(wx.EVT_TEXT, self.OnValue)
        self.tsouth.Bind(wx.EVT_TEXT, self.OnValue)
        self.teast.Bind(wx.EVT_TEXT, self.OnValue)
        self.twest.Bind(wx.EVT_TEXT, self.OnValue)
        self.tnsres.Bind(wx.EVT_TEXT, self.OnValue)
        self.tewres.Bind(wx.EVT_TEXT, self.OnValue)
        self.ttop.Bind(wx.EVT_TEXT, self.OnValue)
        self.tbottom.Bind(wx.EVT_TEXT, self.OnValue)
        #         self.tnsres3.Bind(wx.EVT_TEXT,  self.OnValue)
        #         self.tewres3.Bind(wx.EVT_TEXT,  self.OnValue)
        self.ttbres.Bind(wx.EVT_TEXT, self.OnValue)

        self.__DoLayout(panel)
        self.SetMinSize(self.GetBestSize())
        self.minWindowSize = self.GetMinSize()
        wx.CallAfter(self.settings3D.Collapse, True)

    def MakeSettings3DPaneContent(self, pane):
        """Create 3D region settings pane"""
        border = wx.BoxSizer(wx.VERTICAL)
        gridSizer = wx.GridBagSizer(vgap=0, hgap=0)

        # inputs
        self.ttop = TextCtrl(parent=pane, id=wx.ID_ANY, value=str(self.top),
                             size=(150, -1))
        self.tbottom = TextCtrl(
            parent=pane, id=wx.ID_ANY, value=str(
                self.bottom), size=(
                150, -1))
        self.ttbres = TextCtrl(
            parent=pane, id=wx.ID_ANY, value=str(
                self.tbres), size=(
                150, -1))
        #         self.tnsres3 = wx.TextCtrl(parent = pane, id = wx.ID_ANY, value = str(self.nsres3),
        #                                    size = (150, -1))
        #         self.tewres3  =  wx.TextCtrl(parent = pane, id = wx.ID_ANY, value = str(self.ewres3),
        #                                    size = (150, -1))

        # labels
        self.ldepth = StaticText(
            parent=pane,
            label=_("Depth: %d") %
            self.depth)
        self.lcells3 = StaticText(
            parent=pane,
            label=_("3D Cells: %d") %
            self.cells3)

        # top
        gridSizer.Add(StaticText(parent=pane, label=_("Top")),
                      flag=wx.ALIGN_CENTER |
                      wx.LEFT | wx.RIGHT | wx.TOP, border=5,
                      pos=(0, 1))
        gridSizer.Add(self.ttop,
                      flag=wx.ALIGN_CENTER_HORIZONTAL |
                      wx.ALL, border=5, pos=(1, 1))
        # bottom
        gridSizer.Add(StaticText(parent=pane, label=_("Bottom")),
                      flag=wx.ALIGN_CENTER |
                      wx.LEFT | wx.RIGHT | wx.TOP, border=5,
                      pos=(0, 2))
        gridSizer.Add(self.tbottom,
                      flag=wx.ALIGN_CENTER_HORIZONTAL |
                      wx.ALL, border=5, pos=(1, 2))
        # tbres
        gridSizer.Add(
            StaticText(
                parent=pane,
                label=_("T-B resolution")),
            flag=wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.TOP,
            border=5,
            pos=(
                0,
                3))
        gridSizer.Add(self.ttbres,
                      flag=wx.ALIGN_CENTER_HORIZONTAL |
                      wx.ALL, border=5, pos=(1, 3))

        # res
        #         gridSizer.Add(item = wx.StaticText(parent = pane, label = _("3D N-S resolution")),
        #                       flag = wx.ALIGN_CENTER |
        #                       wx.LEFT | wx.RIGHT | wx.TOP, border = 5,
        #                       pos = (2, 1))
        #         gridSizer.Add(item = self.tnsres3,
        #                       flag = wx.ALIGN_CENTER_HORIZONTAL |
        #                       wx.ALL, border = 5, pos = (3, 1))
        #         gridSizer.Add(item = wx.StaticText(parent = pane, label = _("3D E-W resolution")),
        #                       flag = wx.ALIGN_CENTER |
        #                       wx.LEFT | wx.RIGHT | wx.TOP, border = 5,
        #                       pos = (2, 3))
        #         gridSizer.Add(item = self.tewres3,
        #                       flag = wx.ALIGN_CENTER_HORIZONTAL |
        #                       wx.ALL, border = 5, pos = (3, 3))

        # rows/cols/cells
        gridSizer.Add(self.ldepth,
                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
                      wx.ALL, border=5, pos=(2, 1))

        gridSizer.Add(self.lcells3,
                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
                      wx.ALL, border=5, pos=(2, 2))

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

        pane.SetSizer(border)
        border.Fit(pane)

    def OnSettings3DPaneChanged(self, event):
        """Collapse 3D settings box"""

        if self.settings3D.IsExpanded():
            self.settings3D.SetLabel(self.infoCollapseLabelCol)
            self.Layout()
            self.SetSize(self.GetBestSize())
            self.SetMinSize(self.GetSize())
        else:
            self.settings3D.SetLabel(self.infoCollapseLabelExp)
            self.Layout()
            self.SetSize(self.minWindowSize)
            self.SetMinSize(self.minWindowSize)

        self.SendSizeEvent()

    def __DoLayout(self, panel):
        """Window layout"""
        frameSizer = wx.BoxSizer(wx.VERTICAL)
        gridSizer = wx.GridBagSizer(vgap=0, hgap=0)
        settings3DSizer = wx.BoxSizer(wx.VERTICAL)
        buttonSizer = wx.BoxSizer(wx.HORIZONTAL)

        # north
        gridSizer.Add(self.MakeLabel(text=_("North"), parent=panel),
                      flag=wx.ALIGN_BOTTOM | wx.ALIGN_CENTER_HORIZONTAL |
                      wx.TOP | wx.LEFT | wx.RIGHT, border=5, pos=(0, 2))
        gridSizer.Add(self.tnorth,
                      flag=wx.ALIGN_CENTER_HORIZONTAL |
                      wx.ALIGN_CENTER_VERTICAL |
                      wx.ALL, border=5, pos=(1, 2))
        # west
        gridSizer.Add(self.MakeLabel(text=_("West"), parent=panel),
                      flag=wx.ALIGN_RIGHT |
                      wx.ALIGN_CENTER_VERTICAL |
                      wx.LEFT | wx.TOP | wx.BOTTOM, border=5, pos=(2, 0))
        gridSizer.Add(self.twest,
                      flag=wx.ALIGN_RIGHT |
                      wx.ALIGN_CENTER_VERTICAL |
                      wx.ALL, border=5, pos=(2, 1))

        gridSizer.Add(
            wx.StaticBitmap(
                panel, wx.ID_ANY, self.img, (-1, -1),
                (self.img.GetWidth(),
                 self.img.GetHeight())),
            flag=wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border=5,
            pos=(2, 2))

        # east
        gridSizer.Add(self.teast,
                      flag=wx.ALIGN_CENTER_HORIZONTAL |
                      wx.ALIGN_CENTER_VERTICAL |
                      wx.ALL, border=5, pos=(2, 3))
        gridSizer.Add(self.MakeLabel(text=_("East"), parent=panel),
                      flag=wx.ALIGN_LEFT |
                      wx.ALIGN_CENTER_VERTICAL |
                      wx.RIGHT | wx.TOP | wx.BOTTOM, border=5, pos=(2, 4))
        # south
        gridSizer.Add(self.tsouth,
                      flag=wx.ALIGN_CENTER_HORIZONTAL |
                      wx.ALIGN_CENTER_VERTICAL |
                      wx.ALL, border=5, pos=(3, 2))
        gridSizer.Add(self.MakeLabel(text=_("South"), parent=panel),
                      flag=wx.ALIGN_TOP | wx.ALIGN_CENTER_HORIZONTAL |
                      wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5, pos=(4, 2))
        # ns-res
        gridSizer.Add(self.MakeLabel(text=_("N-S resolution"), parent=panel),
                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
                      wx.TOP | wx.LEFT | wx.RIGHT, border=5, pos=(5, 1))
        gridSizer.Add(self.tnsres,
                      flag=wx.ALIGN_RIGHT |
                      wx.ALIGN_CENTER_VERTICAL |
                      wx.ALL, border=5, pos=(6, 1))
        # ew-res
        gridSizer.Add(self.MakeLabel(text=_("E-W resolution"), parent=panel),
                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
                      wx.TOP | wx.LEFT | wx.RIGHT, border=5, pos=(5, 3))
        gridSizer.Add(self.tewres,
                      flag=wx.ALIGN_RIGHT |
                      wx.ALIGN_CENTER_VERTICAL |
                      wx.ALL, border=5, pos=(6, 3))
        # rows/cols/cells
        gridSizer.Add(self.lrows,
                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
                      wx.ALL, border=5, pos=(7, 1))

        gridSizer.Add(self.lcells,
                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
                      wx.ALL, border=5, pos=(7, 2))

        gridSizer.Add(self.lcols,
                      flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER |
                      wx.ALL, border=5, pos=(7, 3))

        # 3D
        settings3DSizer.Add(self.settings3D,
                            flag=wx.ALL,
                            border=5)

        # buttons
        buttonSizer.Add(self.bcancel, proportion=1,
                        flag=wx.ALIGN_RIGHT |
                        wx.ALIGN_CENTER_VERTICAL |
                        wx.ALL, border=10)
        buttonSizer.Add(self.bset, proportion=1,
                        flag=wx.ALIGN_CENTER |
                        wx.ALIGN_CENTER_VERTICAL |
                        wx.ALL, border=10)

        frameSizer.Add(gridSizer, proportion=1,
                       flag=wx.ALL | wx.ALIGN_CENTER, border=5)
        frameSizer.Add(settings3DSizer, proportion=0,
                       flag=wx.ALL | wx.ALIGN_CENTER, border=5)
        frameSizer.Add(buttonSizer, proportion=0,
                       flag=wx.ALL | wx.ALIGN_RIGHT, border=5)

        self.SetAutoLayout(True)
        panel.SetSizer(frameSizer)
        frameSizer.Fit(panel)
        self.Layout()

    def OnValue(self, event):
        """Set given value"""
        try:
            if event.GetId() == self.tnorth.GetId():
                self.north = float(event.GetString())
            elif event.GetId() == self.tsouth.GetId():
                self.south = float(event.GetString())
            elif event.GetId() == self.teast.GetId():
                self.east = float(event.GetString())
            elif event.GetId() == self.twest.GetId():
                self.west = float(event.GetString())
            elif event.GetId() == self.tnsres.GetId():
                self.nsres = float(event.GetString())
            elif event.GetId() == self.tewres.GetId():
                self.ewres = float(event.GetString())
            elif event.GetId() == self.ttop.GetId():
                self.top = float(event.GetString())
            elif event.GetId() == self.tbottom.GetId():
                self.bottom = float(event.GetString())
            #             elif event.GetId() == self.tnsres3.GetId():
            #                 self.nsres3 = float(event.GetString())
            #             elif event.GetId() == self.tewres3.GetId():
            #                 self.ewres3 = float(event.GetString())
            elif event.GetId() == self.ttbres.GetId():
                self.tbres = float(event.GetString())

            self.__UpdateInfo()

        except ValueError as e:
            if len(event.GetString()) > 0 and event.GetString() != '-':
                dlg = wx.MessageBox(parent=self,
                                    message=_("Invalid value: %s") % e,
                                    caption=_("Error"),
                                    style=wx.OK | wx.ICON_ERROR)
                # reset values
                self.tnorth.SetValue(str(self.north))
                self.tsouth.SetValue(str(self.south))
                self.teast.SetValue(str(self.east))
                self.twest.SetValue(str(self.west))
                self.tnsres.SetValue(str(self.nsres))
                self.tewres.SetValue(str(self.ewres))
                self.ttop.SetValue(str(self.top))
                self.tbottom.SetValue(str(self.bottom))
                self.ttbres.SetValue(str(self.tbres))
                # self.tnsres3.SetValue(str(self.nsres3))
                # self.tewres3.SetValue(str(self.ewres3))

        event.Skip()

    def __UpdateInfo(self):
        """Update number of rows/cols/cells"""
        try:
            rows = int((self.north - self.south) / self.nsres)
            cols = int((self.east - self.west) / self.ewres)
        except ZeroDivisionError:
            return
        self.rows = rows
        self.cols = cols
        self.cells = self.rows * self.cols

        try:
            depth = int((self.top - self.bottom) / self.tbres)
        except ZeroDivisionError:
            return
        self.depth = depth
        self.cells3 = self.rows * self.cols * self.depth

        # 2D
        self.lrows.SetLabel(_("Rows: %d") % self.rows)
        self.lcols.SetLabel(_("Cols: %d") % self.cols)
        self.lcells.SetLabel(_("Cells: %d") % self.cells)
        # 3D
        self.ldepth.SetLabel(_("Depth: %d" % self.depth))
        self.lcells3.SetLabel(_("3D Cells: %d" % self.cells3))

    def OnSetButton(self, event=None):
        """Set default region"""
        ret = RunCommand('g.region',
                         flags='sa',
                         n=self.north,
                         s=self.south,
                         e=self.east,
                         w=self.west,
                         nsres=self.nsres,
                         ewres=self.ewres,
                         t=self.top,
                         b=self.bottom,
                         tbres=self.tbres)
        if ret == 0:
            self.Destroy()

    def OnCancel(self, event):
        self.Destroy()
Exemplo n.º 4
0
class WSDialogBase(wx.Dialog):
    """Base class for web service dialogs."""
    def __init__(
        self,
        parent,
        id=wx.ID_ANY,
        style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER,
        **kwargs,
    ):

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

        self.parent = parent

        # contains panel for every web service on server
        self.ws_panels = {
            "WMS_1.1.1": {
                "panel": None,
                "label": "WMS 1.1.1"
            },
            "WMS_1.3.0": {
                "panel": None,
                "label": "WMS 1.3.0"
            },
            "WMTS": {
                "panel": None,
                "label": "WMTS"
            },
            "OnEarth": {
                "panel": None,
                "label": "OnEarth"
            },
        }

        # TODO: should be in file
        self.default_servers = {
            "OSM-WMS-EUROPE": [
                "http://watzmann-geog.urz.uni-heidelberg.de/cached/osm",
                "",
                "",
            ],
            "irs.gis-lab.info (OSM)": ["http://irs.gis-lab.info", "", ""],
            "NASA GIBS WMTS": [
                "http://gibs.earthdata.nasa.gov/wmts/epsg4326/best/wmts.cgi",
                "",
                "",
            ],
        }

        # holds reference to web service panel which is showed
        self.active_ws_panel = None

        # buttons which are disabled when the dialog is not connected
        self.run_btns = []

        # stores error messages for GError dialog showed when all web service
        # connections were unsuccessful
        self.error_msgs = ""

        self._createWidgets()
        self._doLayout()

    def _createWidgets(self):

        settingsFile = os.path.join(GetSettingsPath(), "wxWS")

        self.settsManager = WSManageSettingsWidget(
            parent=self,
            settingsFile=settingsFile,
            default_servers=self.default_servers)

        self.settingsBox = StaticBox(parent=self,
                                     id=wx.ID_ANY,
                                     label=_(" Server settings "))

        self.serverText = StaticText(parent=self,
                                     id=wx.ID_ANY,
                                     label=_("Server:"))
        self.server = TextCtrl(parent=self, id=wx.ID_ANY)

        self.btn_connect = Button(parent=self,
                                  id=wx.ID_ANY,
                                  label=_("&Connect"))
        self.btn_connect.SetToolTip(_("Connect to the server"))
        if not self.server.GetValue():
            self.btn_connect.Enable(False)

        self.infoCollapseLabelExp = _("Show advanced connection settings")
        self.infoCollapseLabelCol = _("Hide advanced connection settings")

        self.adv_conn = wx.CollapsiblePane(
            parent=self,
            label=self.infoCollapseLabelExp,
            style=wx.CP_DEFAULT_STYLE | wx.CP_NO_TLW_RESIZE | wx.EXPAND,
        )

        self.MakeAdvConnPane(pane=self.adv_conn.GetPane())
        self.adv_conn.Collapse(True)
        self.Bind(wx.EVT_COLLAPSIBLEPANE_CHANGED, self.OnAdvConnPaneChanged,
                  self.adv_conn)

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

        self.layerNameBox = StaticBox(parent=self.reqDataPanel,
                                      id=wx.ID_ANY,
                                      label=_(" Layer Manager Settings "))

        self.layerNameText = StaticText(parent=self.reqDataPanel,
                                        id=wx.ID_ANY,
                                        label=_("Output layer name:"))
        self.layerName = TextCtrl(parent=self.reqDataPanel, id=wx.ID_ANY)

        for ws in six.iterkeys(self.ws_panels):
            # set class WSPanel argument layerNameTxtCtrl
            self.ws_panels[ws]["panel"] = WSPanel(parent=self.reqDataPanel,
                                                  web_service=ws)
            self.ws_panels[ws]["panel"].capParsed.connect(
                self.OnPanelCapParsed)
            self.ws_panels[ws]["panel"].layerSelected.connect(
                self.OnLayerSelected)

        # buttons
        self.btn_close = Button(parent=self, id=wx.ID_CLOSE)
        self.btn_close.SetToolTip(_("Close dialog"))

        # statusbar
        self.statusbar = wx.StatusBar(parent=self, id=wx.ID_ANY)

        # bindings
        self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        self.btn_connect.Bind(wx.EVT_BUTTON, self.OnConnect)

        self.server.Bind(wx.EVT_TEXT, self.OnServer)
        self.layerName.Bind(wx.EVT_TEXT, self.OnOutputLayerName)

        self.settsManager.settingsChanged.connect(self.OnSettingsChanged)
        self.settsManager.settingsSaving.connect(self.OnSettingsSaving)

    def OnLayerSelected(self, title):
        self.layerName.SetValue(title)

    def _doLayout(self):

        dialogSizer = wx.BoxSizer(wx.VERTICAL)

        dialogSizer.Add(
            self.settsManager,
            proportion=0,
            flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT,
            border=5,
        )

        # connectin settings
        settingsSizer = wx.StaticBoxSizer(self.settingsBox, wx.VERTICAL)

        serverSizer = wx.FlexGridSizer(cols=3, vgap=5, hgap=5)

        serverSizer.Add(self.serverText, flag=wx.ALIGN_CENTER_VERTICAL)
        serverSizer.AddGrowableCol(1)
        serverSizer.Add(self.server, flag=wx.EXPAND | wx.ALL)

        serverSizer.Add(self.btn_connect)

        settingsSizer.Add(serverSizer,
                          proportion=0,
                          flag=wx.EXPAND | wx.LEFT | wx.RIGHT,
                          border=5)

        settingsSizer.Add(self.adv_conn, flag=wx.ALL | wx.EXPAND, border=5)

        dialogSizer.Add(
            settingsSizer,
            proportion=0,
            flag=wx.EXPAND | wx.TOP | wx.LEFT | wx.RIGHT,
            border=5,
        )

        # layer name, parsed capabilities

        reqDataSizer = wx.BoxSizer(wx.VERTICAL)

        layerNameSizer = wx.StaticBoxSizer(self.layerNameBox, wx.HORIZONTAL)

        layerNameSizer.Add(self.layerNameText,
                           flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
                           border=5)

        layerNameSizer.Add(self.layerName, flag=wx.EXPAND, proportion=1)

        reqDataSizer.Add(layerNameSizer,
                         flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.EXPAND,
                         border=5)

        self.ch_ws_sizer = wx.BoxSizer(wx.VERTICAL)

        reqDataSizer.Add(self.ch_ws_sizer,
                         proportion=0,
                         flag=wx.TOP | wx.EXPAND,
                         border=5)

        for ws in six.iterkeys(self.ws_panels):
            reqDataSizer.Add(
                self.ws_panels[ws]["panel"],
                proportion=1,
                flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.EXPAND,
                border=5,
            )
            self.ws_panels[ws]["panel"].Hide()

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

        self.reqDataPanel.SetSizer(reqDataSizer)
        self.reqDataPanel.Hide()

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

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

        dialogSizer.Add(self.btnsizer, proportion=0, flag=wx.ALIGN_CENTER)

        # expand wxWidget wx.StatusBar
        statusbarSizer = wx.BoxSizer(wx.HORIZONTAL)
        statusbarSizer.Add(self.statusbar, proportion=1, flag=wx.EXPAND)
        dialogSizer.Add(statusbarSizer, proportion=0, flag=wx.EXPAND)

        self.SetSizer(dialogSizer)
        self.Layout()

        self.SetMinSize((550, -1))
        self.SetMaxSize((-1, self.GetBestSize()[1]))
        self.Fit()

    def MakeAdvConnPane(self, pane):
        """Create advanced connection settings pane"""
        self.usernameText = StaticText(parent=pane,
                                       id=wx.ID_ANY,
                                       label=_("Username:"******"Password:"******"""Check if required data are filled before setting save is performed."""
        server = self.server.GetValue().strip()
        if not server:
            GMessage(
                parent=self,
                message=_("No data source defined, settings are not saved."),
            )
            return

        self.settsManager.SetDataToSave(
            (server, self.username.GetValue(), self.password.GetValue()))
        self.settsManager.SaveSettings(name)

    def OnSettingsChanged(self, data):
        """Update widgets according to chosen settings"""
        # data list: [server, username, password]
        if len(data) < 3:
            return

        self.server.SetValue(data[0])

        self.username.SetValue(data[1])
        self.password.SetValue(data[2])

        if data[1] or data[2]:
            self.adv_conn.Expand()
        else:
            self.adv_conn.Collapse(True)

        # clear content of the wxWidget wx.TextCtrl (Output layer
        # name:), based on changing default server selection in the
        # wxWidget wx.Choice
        if len(self.layerName.GetValue()) > 0:
            self.layerName.Clear()

    def OnClose(self, event):
        """Close the dialog"""
        """Close dialog"""
        if not self.IsModal():
            self.Destroy()
        event.Skip()

    def _getCapFiles(self):
        ws_cap_files = {}
        for v in six.itervalues(self.ws_panels):
            ws_cap_files[v["panel"].GetWebService()] = v["panel"].GetCapFile()

        return ws_cap_files

    def OnServer(self, event):
        """Server settings edited"""
        value = event.GetString()
        if value:
            self.btn_connect.Enable(True)
        else:
            self.btn_connect.Enable(False)

        # clear content of the wxWidget wx.TextCtrl (Output Layer
        # name:), based on changing content of the wxWidget
        # wx.TextCtrl (Server:)
        self.layerName.Clear()

    def OnOutputLayerName(self, event):
        """Update layer name to web service panel"""
        lname = event.GetString()
        for v in six.itervalues(self.ws_panels):
            v["panel"].SetOutputLayerName(lname.strip())

    def OnConnect(self, event):
        """Connect to the server"""
        server = self.server.GetValue().strip()

        self.ch_ws_sizer.Clear(True)

        if self.active_ws_panel is not None:
            self.reqDataPanel.Hide()
            for btn in self.run_btns:
                btn.Enable(False)
            self.active_ws_panel = None

            self.Layout()
            self.Fit()

        self.statusbar.SetStatusText(
            _("Connecting to <%s>..." % self.server.GetValue().strip()))

        # number of panels already connected
        self.finished_panels_num = 0
        for ws in six.iterkeys(self.ws_panels):
            self.ws_panels[ws]["panel"].ConnectToServer(
                url=server,
                username=self.username.GetValue(),
                password=self.password.GetValue(),
            )
            self.ws_panels[ws]["panel"].Hide()

    def OnPanelCapParsed(self, error_msg):
        """Called when panel has downloaded and parsed capabilities file."""
        # how many web service panels are finished
        self.finished_panels_num += 1

        if error_msg:
            self.error_msgs += "\n" + error_msg

        # if all are finished, show panels, which succeeded in connection
        if self.finished_panels_num == len(self.ws_panels):
            self.UpdateDialogAfterConnection()

            # show error dialog only if connections to all web services were
            # unsuccessful
            if not self._getConnectedWS() and self.error_msgs:
                GError(self.error_msgs, parent=self)
            self.error_msgs = ""

            self.Layout()
            self.Fit()

    def _getConnectedWS(self):
        """
        :return: list of found web services on server (identified as keys in self.ws_panels)
        """
        conn_ws = []
        for ws, data in six.iteritems(self.ws_panels):
            if data["panel"].IsConnected():
                conn_ws.append(ws)

        return conn_ws

    def UpdateDialogAfterConnection(self):
        """Update dialog after all web service panels downloaded and parsed capabilities data."""
        avail_ws = {}
        conn_ws = self._getConnectedWS()

        for ws in conn_ws:
            avail_ws[ws] = self.ws_panels[ws]

        self.web_service_sel = []
        self.rb_choices = []

        # at least one web service found on server
        if len(avail_ws) > 0:
            self.reqDataPanel.Show()
            self.rb_order = ["WMS_1.1.1", "WMS_1.3.0", "WMTS", "OnEarth"]

            for ws in self.rb_order:

                if ws in avail_ws:
                    self.web_service_sel.append(ws)
                    self.rb_choices.append(avail_ws[ws]["label"])

            self.choose_ws_rb = wx.RadioBox(
                parent=self.reqDataPanel,
                id=wx.ID_ANY,
                label=_("Available web services"),
                pos=wx.DefaultPosition,
                choices=self.rb_choices,
                majorDimension=1,
                style=wx.RA_SPECIFY_ROWS,
            )

            self.Bind(wx.EVT_RADIOBOX, self.OnChooseWs, self.choose_ws_rb)
            self.ch_ws_sizer.Add(
                self.choose_ws_rb,
                flag=wx.TOP | wx.LEFT | wx.RIGHT | wx.EXPAND,
                border=5,
            )
            self._showWsPanel(
                self.web_service_sel[self.choose_ws_rb.GetSelection()])
            self.statusbar.SetStatusText(
                _("Connected to <%s>" % self.server.GetValue().strip()))
            for btn in self.run_btns:
                btn.Enable(True)
        # no web service found on server
        else:
            self.statusbar.SetStatusText(
                _("Unable to connect to <%s>" %
                  self.server.GetValue().strip()))
            for btn in self.run_btns:
                btn.Enable(False)
            self.reqDataPanel.Hide()
            self.active_ws_panel = None

    def OnChooseWs(self, event):
        """Show panel corresponding to selected web service."""
        choosen_r = event.GetInt()
        self._showWsPanel(self.web_service_sel[choosen_r])

    def _showWsPanel(self, ws):
        """Helper function"""
        if self.active_ws_panel is not None:
            self.active_ws_panel.Hide()

        self.active_ws_panel = self.ws_panels[ws]["panel"]
        if not self.active_ws_panel.IsShown():
            self.active_ws_panel.Show()
            self.SetMaxSize((-1, -1))
            self.active_ws_panel.GetContainingSizer().Layout()

    def OnAdvConnPaneChanged(self, event):
        """Collapse search module box"""
        if self.adv_conn.IsExpanded():
            self.adv_conn.SetLabel(self.infoCollapseLabelCol)
        else:
            self.adv_conn.SetLabel(self.infoCollapseLabelExp)

        self.Layout()
        self.SetMaxSize((-1, self.GetBestSize()[1]))
        self.SendSizeEvent()
        self.Fit()
Exemplo n.º 5
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()
Exemplo 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()
Exemplo n.º 7
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()
Exemplo n.º 8
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"))
Exemplo n.º 9
0
class AnimationSliderBase(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)
        self.label1 = StaticText(self, id=wx.ID_ANY)
        self.slider = wx.Slider(self, id=wx.ID_ANY, style=wx.SL_HORIZONTAL)
        self.indexField = TextCtrl(self, id=wx.ID_ANY, size=(40, -1),
                                   style=wx.TE_PROCESS_ENTER | wx.TE_RIGHT,
                                   validator=IntegerValidator())

        self.callbackSliderChanging = None
        self.callbackSliderChanged = None
        self.callbackFrameIndexChanged = None

        self.framesCount = 0

        self.enable = True

        self.slider.Bind(wx.EVT_SPIN, self.OnSliderChanging)
        self.slider.Bind(wx.EVT_SCROLL_THUMBRELEASE, self.OnSliderChanged)
        self.indexField.Bind(wx.EVT_TEXT_ENTER, self.OnFrameIndexChanged)

    def UpdateFrame(self, index):
        self._updateFrameIndex(index)
        if not self.enable:
            return

        self.slider.SetValue(index)

    def _updateFrameIndex(self, index):
        raise NotImplementedError

    def OnFrameIndexChanged(self, event):
        self._onFrameIndexChanged(event)

    def SetFrames(self, frames):
        self._setFrames(frames)

    def _setFrames(self, frames):
        raise NotImplementedError

    def SetCallbackSliderChanging(self, callback):
        self.callbackSliderChanging = callback

    def SetCallbackSliderChanged(self, callback):
        self.callbackSliderChanged = callback

    def SetCallbackFrameIndexChanged(self, callback):
        self.callbackFrameIndexChanged = callback

    def EnableSlider(self, enable=True):
        if enable and self.framesCount <= 1:
            enable = False  # we don't want to enable it
        self.enable = enable
        self.slider.Enable(enable)
        self.indexField.Enable(enable)

    def OnSliderChanging(self, event):
        self.callbackSliderChanging(event.GetInt())

    def OnSliderChanged(self, event):
        self.callbackSliderChanged()

    def _onFrameIndexChanged(self, event):
        index = self.indexField.GetValue()
        index = self._validate(index)
        if index is not None:
            self.slider.SetValue(index)
            self.callbackFrameIndexChanged(index)

    def _validate(self, index):
        try:
            index = int(index)
        except ValueError:
            index = self.slider.GetValue()
            self.indexField.SetValue(str(index + 1))
            return None
        start, end = self.slider.GetRange()
        index -= 1
        if index > end:
            index = end
            self.indexField.SetValue(str(end + 1))
        elif index < start:
            index = start
            self.indexField.SetValue(str(start + 1))

        return index
Exemplo n.º 10
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()
Exemplo n.º 11
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'])
Exemplo n.º 12
0
class InstallExtensionWindow(wx.Frame):
    def __init__(self,
                 parent,
                 giface,
                 id=wx.ID_ANY,
                 title=_("Fetch & install extension from GRASS Addons"),
                 **kwargs):
        self.parent = parent
        self._giface = giface
        self.options = dict()  # list of options

        wx.Frame.__init__(self, parent=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.repoBox = StaticBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=" %s " %
            _("Repository (leave empty to use the official one)"))
        self.treeBox = StaticBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=" %s " % _("List of extensions - double-click to install"))

        self.repo = TextCtrl(parent=self.panel, id=wx.ID_ANY)

        # modelBuilder loads data into tree model
        self.modelBuilder = ExtensionTreeModelBuilder()
        # tree view displays model data
        self.tree = CTreeView(parent=self.panel,
                              model=self.modelBuilder.GetModel())

        self.search = SearchModuleWidget(parent=self.panel,
                                         model=self.modelBuilder.GetModel(),
                                         showChoice=False)
        self.search.showSearchResult.connect(
            lambda result: self.tree.Select(result))
        # show text in statusbar when notification appears
        self.search.showNotification.connect(
            lambda message: self.SetStatusText(message))
        # load data in different thread
        self.thread = gThread()

        self.optionBox = StaticBox(parent=self.panel,
                                   id=wx.ID_ANY,
                                   label=" %s " % _("Options"))
        task = gtask.parse_interface('g.extension')
        ignoreFlags = ['l', 'c', 'g', 'a', 'f', 't', 'help', 'quiet']
        if sys.platform == 'win32':
            ignoreFlags.append('d')
            ignoreFlags.append('i')

        for f in task.get_options()['flags']:
            name = f.get('name', '')
            desc = f.get('label', '')
            if not desc:
                desc = f.get('description', '')
            if not name and not desc:
                continue
            if name in ignoreFlags:
                continue
            self.options[name] = wx.CheckBox(parent=self.panel,
                                             id=wx.ID_ANY,
                                             label=desc)
        defaultUrl = ''  # default/official one will be used when option empty
        self.repo.SetValue(
            task.get_param(value='url').get('default', defaultUrl))

        self.statusbar = self.CreateStatusBar(number=1)

        self.btnFetch = Button(parent=self.panel,
                               id=wx.ID_ANY,
                               label=_("&Fetch"))
        self.btnFetch.SetToolTip(
            _("Fetch list of available modules "
              "from GRASS Addons SVN repository"))
        self.btnClose = Button(parent=self.panel, id=wx.ID_CLOSE)
        self.btnInstall = Button(parent=self.panel,
                                 id=wx.ID_ANY,
                                 label=_("&Install"))
        self.btnInstall.SetToolTip(_("Install selected add-ons GRASS module"))
        self.btnInstall.Enable(False)
        self.btnHelp = Button(parent=self.panel, id=wx.ID_HELP)
        self.btnHelp.SetToolTip(_("Show g.extension manual page"))

        self.btnClose.Bind(wx.EVT_BUTTON, lambda evt: self.Close())
        self.btnFetch.Bind(wx.EVT_BUTTON, self.OnFetch)
        self.btnInstall.Bind(wx.EVT_BUTTON, self.OnInstall)
        self.btnHelp.Bind(wx.EVT_BUTTON, self.OnHelp)
        self.tree.selectionChanged.connect(self.OnItemSelected)
        self.tree.itemActivated.connect(self.OnItemActivated)
        self.tree.contextMenu.connect(self.OnContextMenu)

        wx.CallAfter(self._fetch)

        self._layout()

    def _layout(self):
        """Do layout"""
        sizer = wx.BoxSizer(wx.VERTICAL)
        repoSizer = wx.StaticBoxSizer(self.repoBox, wx.VERTICAL)
        repo1Sizer = wx.BoxSizer(wx.HORIZONTAL)
        repo1Sizer.Add(self.repo,
                       proportion=1,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                       border=1)
        repo1Sizer.Add(self.btnFetch,
                       proportion=0,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                       border=1)
        repoSizer.Add(repo1Sizer, flag=wx.EXPAND)

        findSizer = wx.BoxSizer(wx.HORIZONTAL)
        findSizer.Add(self.search, proportion=1)

        treeSizer = wx.StaticBoxSizer(self.treeBox, wx.HORIZONTAL)
        treeSizer.Add(self.tree,
                      proportion=1,
                      flag=wx.ALL | wx.EXPAND,
                      border=1)

        # options
        optionSizer = wx.StaticBoxSizer(self.optionBox, wx.VERTICAL)
        for key in self.options.keys():
            optionSizer.Add(self.options[key], proportion=0)

        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(self.btnHelp, proportion=0)
        btnSizer.AddStretchSpacer()
        btnSizer.Add(self.btnClose, proportion=0, flag=wx.RIGHT, border=5)
        btnSizer.Add(self.btnInstall, proportion=0)

        sizer.Add(repoSizer, proportion=0, flag=wx.ALL | wx.EXPAND, border=3)
        sizer.Add(findSizer,
                  proportion=0,
                  flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
                  border=3)
        sizer.Add(treeSizer,
                  proportion=1,
                  flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
                  border=3)
        sizer.Add(optionSizer,
                  proportion=0,
                  flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
                  border=3)
        sizer.Add(btnSizer,
                  proportion=0,
                  flag=wx.ALIGN_RIGHT | wx.ALL | wx.EXPAND,
                  border=5)

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

        self.Layout()

    def _getCmd(self):
        item = self.tree.GetSelected()
        if not item or 'command' not in item[0].data:
            GError(_("Extension not defined"), parent=self)
            return

        name = item[0].data['command']

        flags = list()
        for key in self.options.keys():
            if self.options[key].IsChecked():
                if len(key) == 1:
                    flags.append('-%s' % key)
                else:
                    flags.append('--%s' % key)

        return ['g.extension'] + flags + [
            'extension=' + name, 'url=' + self.repo.GetValue().strip()
        ]

    def OnFetch(self, event):
        """Fetch list of available extensions"""
        self._fetch()

    def _fetch(self):
        """Fetch list of available extensions"""
        wx.BeginBusyCursor()
        self.SetStatusText(
            _("Fetching list of modules from GRASS-Addons SVN (be patient)..."
              ), 0)
        try:
            self.thread.Run(callable=self.modelBuilder.Load,
                            url=self.repo.GetValue().strip(),
                            ondone=lambda event: self._fetchDone())
        except GException as e:
            self._fetchDone()
            GError(unicode(e), parent=self, showTraceback=False)

    def _fetchDone(self):
        self.tree.RefreshItems()
        nitems = len(self.modelBuilder.GetModel().SearchNodes(key='command',
                                                              value='*'))
        self.SetStatusText(_("%d extensions loaded") % nitems, 0)
        wx.EndBusyCursor()

    def OnContextMenu(self, node):
        if not hasattr(self, "popupID"):
            self.popupID = dict()
            for key in ('install', 'help'):
                self.popupID[key] = wx.NewId()

        data = node.data
        if data and 'command' in data:
            self.popupMenu = Menu()
            self.popupMenu.Append(self.popupID['install'], text=_("Install"))
            self.Bind(wx.EVT_MENU, self.OnInstall, id=self.popupID['install'])
            self.popupMenu.AppendSeparator()
            self.popupMenu.Append(self.popupID['help'],
                                  text=_("Show manual page"))
            self.Bind(wx.EVT_MENU, self.OnItemHelp, id=self.popupID['help'])

            self.PopupMenu(self.popupMenu)
            self.popupMenu.Destroy()

    def OnItemActivated(self, node):
        data = node.data
        if data and 'command' in data:
            self.OnInstall(event=None)

    def OnInstall(self, event):
        """Install selected extension"""
        log = self.parent.GetLogWindow()
        cmd = self._getCmd()
        if cmd:
            log.RunCmd(cmd, onDone=self.OnDone)

    def OnDone(self, event):
        if event.returncode == 0:
            if not os.getenv('GRASS_ADDON_BASE'):
                SetAddOnPath(key='BASE')

            globalvar.UpdateGRASSAddOnCommands()
            toolboxesOutdated()

    def OnItemHelp(self, event):
        item = self.tree.GetSelected()
        if not item or 'command' not in item[0].data:
            return

        self._giface.Help(entry=item[0].data['command'], online=True)

    def OnHelp(self, event):
        self._giface.Help(entry='g.extension')

    def OnItemSelected(self, node):
        """Item selected"""
        data = node.data
        if data is None:
            self.SetStatusText('', 0)
            self.btnInstall.Enable(False)
        else:
            self.SetStatusText(data.get('description', ''), 0)
            self.btnInstall.Enable(True)