Пример #1
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()
Пример #2
0
    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)