Exemplo n.º 1
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 = SearchCtrl(self.panel)
        self.search.SetDescriptiveText(_("Search"))
        self.search.ShowCancelButton(True)
        # 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 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.search.Bind(wx.EVT_TEXT, lambda evt: self.Filter(evt.GetString()))
        self.search.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN,
                         lambda evt: self.Filter(""))
        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)

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

        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(
            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.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)

        # 'url=' + self.repo.GetValue().strip()]
        return ["g.extension"] + flags + ["extension={}".format(name)]

    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 (be patient)..."), 0)
        try:
            self.thread.Run(
                callable=self.modelBuilder.Load,
                url="",  # self.repo.GetValue().strip(),
                ondone=lambda event: self._fetchDone(),
            )
        except GException as error:
            self._fetchDone()
            GError(str(error), 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 Filter(self, text):
        model = self.modelBuilder.GetModel()
        if text:
            model = model.Filtered(key=["command", "keywords", "description"],
                                   value=text)
            self.tree.SetModel(model)
            self.tree.ExpandAll()
        else:
            self.tree.SetModel(model)

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

        data = node.data
        if data and "command" in data:
            self.popupMenu = Menu()
            self.popupMenu.Append(self.popupID["install"], _("Install"))
            self.Bind(wx.EVT_MENU, self.OnInstall, id=self.popupID["install"])
            self.popupMenu.AppendSeparator()
            self.popupMenu.Append(self.popupID["help"], _("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)
Exemplo n.º 2
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 = wx.StaticBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=" %s " %
            _("Repository (leave empty to use the official one)"))
        self.treeBox = wx.StaticBox(
            parent=self.panel,
            id=wx.ID_ANY,
            label=" %s " % _("List of extensions - double-click to install"))

        self.repo = wx.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 = wx.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 = wx.Button(parent=self.panel,
                                  id=wx.ID_ANY,
                                  label=_("&Fetch"))
        self.btnFetch.SetToolTipString(
            _("Fetch list of available modules "
              "from GRASS Addons SVN repository"))
        self.btnClose = wx.Button(parent=self.panel, id=wx.ID_CLOSE)
        self.btnInstall = wx.Button(parent=self.panel,
                                    id=wx.ID_ANY,
                                    label=_("&Install"))
        self.btnInstall.SetToolTipString(
            _("Install selected add-ons GRASS module"))
        self.btnInstall.Enable(False)
        self.btnHelp = wx.Button(parent=self.panel, id=wx.ID_HELP)
        self.btnHelp.SetToolTipString(_("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(item=self.repo,
                       proportion=1,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                       border=1)
        repo1Sizer.Add(item=self.btnFetch,
                       proportion=0,
                       flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
                       border=1)
        repoSizer.Add(item=repo1Sizer, flag=wx.EXPAND)

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

        treeSizer = wx.StaticBoxSizer(self.treeBox, wx.HORIZONTAL)
        treeSizer.Add(item=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(item=self.options[key], proportion=0)

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

        sizer.Add(item=repoSizer,
                  proportion=0,
                  flag=wx.ALL | wx.EXPAND,
                  border=3)
        sizer.Add(item=findSizer,
                  proportion=0,
                  flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
                  border=3)
        sizer.Add(item=treeSizer,
                  proportion=1,
                  flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
                  border=3)
        sizer.Add(item=optionSizer,
                  proportion=0,
                  flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND,
                  border=3)
        sizer.Add(item=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 = wx.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)
Exemplo n.º 3
0
class SearchModuleWindow(wx.Panel):
    """Menu tree and search widget for searching modules.

    Signal:
        showNotification - attribute 'message'
    """

    def __init__(self, parent, handlerObj, giface, model, id=wx.ID_ANY,
                 **kwargs):
        self.parent = parent
        self._handlerObj = handlerObj
        self._giface = giface

        self.showNotification = Signal('SearchModuleWindow.showNotification')
        wx.Panel.__init__(self, parent=parent, id=id, **kwargs)

        # tree
        self._tree = CTreeView(model=model, parent=self)
        self._tree.SetToolTip(
            _("Double-click or Ctrl-Enter to run selected module"))

#        self._dataBox = wx.StaticBox(parent = self, id = wx.ID_ANY,
#                                     label = " %s " % _("Module tree"))

        # search widget
        self._search = SearchModuleWidget(parent=self,
                                          model=model,
                                          showChoice=False)
        self._search.showSearchResult.connect(
            lambda result: self._tree.Select(result))
        self._search.showNotification.connect(self.showNotification)

        self._helpText = StaticText(
            parent=self, id=wx.ID_ANY,
            label="Press Enter for next match, Ctrl+Enter to run command")
        self._helpText.SetForegroundColour(
            wx.SystemSettings.GetColour(
                wx.SYS_COLOUR_GRAYTEXT))

        # buttons
        self._btnRun = Button(self, id=wx.ID_OK, label=_("&Run"))
        self._btnRun.SetToolTip(_("Run selected module from the tree"))
        self._btnHelp = Button(self, id=wx.ID_ANY, label=_("H&elp"))
        self._btnHelp.SetToolTip(
            _("Show manual for selected module from the tree"))
        self._btnAdvancedSearch = Button(self, id=wx.ID_ANY,
                                         label=_("Adva&nced search..."))
        self._btnAdvancedSearch.SetToolTip(
            _("Do advanced search using %s module") % 'g.search.module')

        # bindings
        self._btnRun.Bind(wx.EVT_BUTTON, lambda evt: self.Run())
        self._btnHelp.Bind(wx.EVT_BUTTON, lambda evt: self.Help())
        self._btnAdvancedSearch.Bind(wx.EVT_BUTTON,
                                     lambda evt: self.AdvancedSearch())
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)

        self._tree.selectionChanged.connect(self.OnItemSelected)
        self._tree.itemActivated.connect(lambda node: self.Run(node))

        self._layout()

        self._search.SetFocus()

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

        # body
        dataSizer = wx.BoxSizer(wx.HORIZONTAL)
        dataSizer.Add(self._tree, proportion=1,
                      flag=wx.EXPAND)

        # buttons
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(self._btnAdvancedSearch, proportion=0)
        btnSizer.AddStretchSpacer()
        btnSizer.Add(self._btnHelp, proportion=0)
        btnSizer.Add(self._btnRun, proportion=0)

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

        sizer.Add(self._search, proportion=0,
                  flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5)

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

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

        sizer.Fit(self)
        sizer.SetSizeHints(self)

        self.SetSizer(sizer)

        self.Fit()
        self.SetAutoLayout(True)
        self.Layout()

    def _GetSelectedNode(self):
        selection = self._tree.GetSelected()
        if not selection:
            return None
        return selection[0]

    def Run(self, node=None):
        """Run selected command.

        :param node: a tree node associated with the module or other item
        """
        if not node:
            node = self._GetSelectedNode()
        # nothing selected
        if not node:
            return
        data = node.data
        # non-leaf nodes
        if not data:
            return

        # extract name of the handler and create a new call
        handler = 'self._handlerObj.' + data['handler'].lstrip('self.')

        if data['command']:
            eval(handler)(event=None, cmd=data['command'].split())
        else:
            eval(handler)(event=None)

    def Help(self, node=None):
        """Show documentation for a module"""
        if not node:
            node = self._GetSelectedNode()
        # nothing selected
        if not node:
            return
        data = node.data
        # non-leaf nodes
        if not data:
            return

        if not data['command']:
            # showing nothing for non-modules
            return
        # strip parameters from command if present
        name = data['command'].split()[0]
        self._giface.Help(name)
        self.showNotification.emit(
            message=_("Documentation for %s is now open in the web browser")
            % name)

    def AdvancedSearch(self):
        """Show advanced search window"""
        self._handlerObj.RunMenuCmd(cmd=['g.search.modules'])

    def OnKeyUp(self, event):
        """Key or key combination pressed"""
        if event.ControlDown() and \
                event.GetKeyCode() in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER):
            self.Run()

    def OnItemSelected(self, node):
        """Item selected"""
        data = node.data
        if not data or 'command' not in data:
            return

        if data['command']:
            label = data['command']
            if data['description']:
                label += ' -- ' + data['description']
        else:
            label = data['description']

        self.showNotification.emit(message=label)
Exemplo n.º 4
0
class SearchModuleWindow(wx.Panel):
    """Menu tree and search widget for searching modules.

    Signal:
        showNotification - attribute 'message'
    """

    def __init__(self, parent, handlerObj, giface, model, id=wx.ID_ANY, **kwargs):
        self.parent = parent
        self._handlerObj = handlerObj
        self._giface = giface
        self._model = model

        self.showNotification = Signal("SearchModuleWindow.showNotification")
        wx.Panel.__init__(self, parent=parent, id=id, **kwargs)

        # search widget
        self._search = SearchCtrl(self)
        self._search.SetDescriptiveText(_("Search"))
        self._search.ShowCancelButton(True)
        self._btnAdvancedSearch = Button(
            self, id=wx.ID_ANY, label=_("Adva&nced search...")
        )
        self._btnAdvancedSearch.SetToolTip(
            _("Do advanced search using %s tool") % "g.search.module"
        )
        # tree
        self._tree = CTreeView(model=model, parent=self)
        self._tree.SetToolTip(_("Double-click to run selected tool"))

        # buttons
        self._btnRun = Button(self, id=wx.ID_OK, label=_("&Run..."))
        self._btnRun.SetToolTip(_("Run selected tool from the tree"))
        self._btnHelp = Button(self, id=wx.ID_ANY, label=_("H&elp"))
        self._btnHelp.SetToolTip(_("Show manual for selected tool from the tree"))

        # bindings
        self._search.Bind(wx.EVT_TEXT, lambda evt: self.Filter(evt.GetString()))
        self._search.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, lambda evt: self.Filter(""))
        self._btnRun.Bind(wx.EVT_BUTTON, lambda evt: self.Run())
        self._btnHelp.Bind(wx.EVT_BUTTON, lambda evt: self.Help())
        self._btnAdvancedSearch.Bind(wx.EVT_BUTTON, lambda evt: self.AdvancedSearch())

        self._tree.selectionChanged.connect(self.OnItemSelected)
        self._tree.itemActivated.connect(lambda node: self.Run(node))

        self._layout()

        self._search.SetFocus()

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

        # search
        searchSizer = wx.BoxSizer(wx.HORIZONTAL)
        searchSizer.Add(self._search, proportion=1, flag=wx.EXPAND | wx.RIGHT, border=5)
        searchSizer.Add(self._btnAdvancedSearch, proportion=0, flag=wx.EXPAND)
        sizer.Add(searchSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5)
        # body
        sizer.Add(
            self._tree, proportion=1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5
        )

        # buttons
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.AddStretchSpacer()
        btnSizer.Add(self._btnHelp, proportion=0, flag=wx.EXPAND | wx.RIGHT, border=5)
        btnSizer.Add(self._btnRun, proportion=0)

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

        self.SetSizerAndFit(sizer)
        self.SetAutoLayout(True)
        self.Layout()

    def Filter(self, text):
        if text:
            model = self._model.Filtered(
                key=["command", "keywords", "description"], value=text
            )
            self._tree.SetModel(model)
            self._tree.ExpandAll()
        else:
            self._tree.SetModel(self._model)

    def _GetSelectedNode(self):
        selection = self._tree.GetSelected()
        if not selection:
            return None
        return selection[0]

    def Run(self, node=None):
        """Run selected command.

        :param node: a tree node associated with the module or other item
        """
        if not node:
            node = self._GetSelectedNode()
        # nothing selected
        if not node:
            return
        data = node.data
        # non-leaf nodes
        if not data:
            # expand/collapse location/mapset...
            if self._tree.IsNodeExpanded(node):
                self._tree.CollapseNode(node, recursive=False)
            else:
                self._tree.ExpandNode(node, recursive=False)
            return

        # extract name of the handler and create a new call
        handler = "self._handlerObj." + data["handler"].lstrip("self.")

        if data["command"]:
            eval(handler)(event=None, cmd=data["command"].split())
        else:
            eval(handler)(event=None)

    def Help(self, node=None):
        """Show documentation for a module"""
        if not node:
            node = self._GetSelectedNode()
        # nothing selected
        if not node:
            return
        data = node.data
        # non-leaf nodes
        if not data:
            return

        if not data["command"]:
            # showing nothing for non-modules
            return
        # strip parameters from command if present
        name = data["command"].split()[0]
        self._giface.Help(name)
        self.showNotification.emit(
            message=_("Documentation for %s is now open in the web browser") % name
        )

    def AdvancedSearch(self):
        """Show advanced search window"""
        self._handlerObj.RunMenuCmd(cmd=["g.search.modules"])

    def OnItemSelected(self, node):
        """Item selected"""
        data = node.data
        if not data or "command" not in data:
            return

        if data["command"]:
            label = data["command"]
            if data["description"]:
                label += " -- " + data["description"]
        else:
            label = data["description"]

        self.showNotification.emit(message=label)
Exemplo n.º 5
0
class SearchModuleWindow(wx.Panel):
    """Menu tree and search widget for searching modules.
    
    Signal:
        showNotification - attribute 'message'
    """
    def __init__(self, parent, handlerObj, model, id=wx.ID_ANY, **kwargs):
        self.parent = parent
        self.handlerObj = handlerObj

        self.showNotification = Signal('SearchModuleWindow.showNotification')
        wx.Panel.__init__(self, parent=parent, id=id, **kwargs)

        # tree
        self._tree = CTreeView(model=model, parent=self)
        self._tree.SetToolTipString(
            _("Double-click or Ctrl-Enter to run selected module"))

        #        self._dataBox = wx.StaticBox(parent = self, id = wx.ID_ANY,
        #                                     label = " %s " % _("Module tree"))

        # search widget
        self._search = SearchModuleWidget(parent=self,
                                          model=model,
                                          showChoice=False)
        self._search.showSearchResult.connect(
            lambda result: self._tree.Select(result))
        self._search.showNotification.connect(self.showNotification)

        self._helpText = wx.StaticText(
            parent=self,
            id=wx.ID_ANY,
            label="Press Enter for next match, Ctrl+Enter to run command")
        self._helpText.SetForegroundColour(
            wx.SystemSettings_GetColour(wx.SYS_COLOUR_GRAYTEXT))

        # buttons
        self._btnRun = wx.Button(self, id=wx.ID_OK, label=_("&Run"))
        self._btnRun.SetToolTipString(_("Run selected module from the tree"))

        # bindings
        self._btnRun.Bind(wx.EVT_BUTTON, lambda evt: self.Run())
        self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)

        self._tree.selectionChanged.connect(self.OnItemSelected)
        self._tree.itemActivated.connect(lambda node: self.Run(node))

        self._layout()

        self._search.SetFocus()

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

        # body
        dataSizer = wx.BoxSizer(wx.HORIZONTAL)
        dataSizer.Add(item=self._tree, proportion=1, flag=wx.EXPAND)

        # buttons
        btnSizer = wx.BoxSizer(wx.HORIZONTAL)
        btnSizer.Add(item=self._btnRun, proportion=0)

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

        sizer.Add(item=self._search,
                  proportion=0,
                  flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
                  border=5)

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

        sizer.Add(item=self._helpText,
                  proportion=0,
                  flag=wx.EXPAND | wx.LEFT,
                  border=5)

        sizer.Fit(self)
        sizer.SetSizeHints(self)

        self.SetSizer(sizer)

        self.Fit()
        self.SetAutoLayout(True)
        self.Layout()

    def Run(self, module=None):
        """Run selected command.
        
        :param module: module (represented by tree node)
        """
        if module is None:
            if not self._tree.GetSelected():
                return

            module = self._tree.GetSelected()[0]
        data = module.data
        if not data:
            return

        handler = 'self.handlerObj.' + data['handler'].lstrip('self.')

        if data['command']:
            eval(handler)(event=None, cmd=data['command'].split())
        else:
            eval(handler)(event=None)

    def OnKeyUp(self, event):
        """Key or key combination pressed"""
        if event.ControlDown() and \
                event.GetKeyCode() in (wx.WXK_RETURN, wx.WXK_NUMPAD_ENTER):
            self.Run()

    def OnItemSelected(self, node):
        """Item selected"""
        data = node.data
        if not data or 'command' not in data:
            return

        if data['command']:
            label = data['command']
            if data['description']:
                label += ' -- ' + data['description']
        else:
            label = data['description']

        self.showNotification.emit(message=label)