Esempio n. 1
0
    def __init__(self, order, dialog):
        super().__init__()
        self.dialog = dialog
        self.order = order

        datestring = iso8601.parse_date(self.order.date).date().isoformat()
        txt = (f'<b>Order {self.order.name}<br>({datestring})</b><br>'
               f'{self.order.description}')
        label = QLabel(txt)

        button = QPushButton(
            'Re-Download' if self.order.downloaded() else 'Download')
        button.clicked.connect(self.download)

        vlayout = QVBoxLayout()
        vlayout.addWidget(button)
        if self.order.downloaded():
            labelOpenFolder = QLabel("<a href='#'>Open order folder</a>")
            vlayout.addWidget(labelOpenFolder)
            labelOpenFolder.setOpenExternalLinks(False)
            labelOpenFolder.linkActivated.connect(
                lambda: QDesktopServices.openUrl(
                    QUrl.fromLocalFile(self.order.download_folder())))

        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addStretch()
        layout.addLayout(vlayout)

        self.setLayout(layout)
    def __init__(self, order, dialog):
        super().__init__()
        self.dialog = dialog
        self.order = order

        datestring = iso8601.parse_date(order.date).date().isoformat()

        txt = ('<style>h3{margin-bottom: 0px;}</style>'
               f'<b><h3>Order {order.name}</h3></b>'
               f'<b>Placed on</b>: {datestring}<br>'
               f'<b>Id</b>: {order.id()}<br>'
               f'<b>Quad count</b>: {len(order.quads)}<br>')
        label = QLabel(txt)

        button = QPushButton(
            'Re-Download' if self.order.downloaded() else 'Download')
        button.clicked.connect(self.download)

        vlayout = QVBoxLayout()
        vlayout.addWidget(button)
        if self.order.downloaded():
            labelOpenFolder = QLabel("<a href='#'>Open order folder</a>")
            vlayout.addWidget(labelOpenFolder)
            labelOpenFolder.setOpenExternalLinks(False)
            labelOpenFolder.linkActivated.connect(
                lambda: QDesktopServices.openUrl(
                    QUrl.fromLocalFile(self.order.download_folder())))

        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addStretch()
        layout.addLayout(vlayout)

        self.setLayout(layout)
Esempio n. 3
0
    def __init__(self, order, dialog):
        super().__init__()
        self.dialog = dialog
        self.order = order
        txt = (f'<b>Order {order.name()}<br>({order.date()})</b><br>'
               f'{order.assets_count()} assets - state: {order.state()}')

        label = QLabel(txt)
        if not order.is_zipped():
            label.setStyleSheet("color: gray")
        button = QPushButton(
            'Re-Download' if order.downloaded() else 'Download')
        button.clicked.connect(self.download)
        button.setEnabled(order.state() == 'success' and order.is_zipped())

        vlayout = QVBoxLayout()
        vlayout.addWidget(button)
        if order.downloaded():
            labelOpenFolder = QLabel("<a href='#'>Open order folder</a>")
            vlayout.addWidget(labelOpenFolder)
            labelOpenFolder.setOpenExternalLinks(False)
            labelOpenFolder.linkActivated.connect(
                lambda: QDesktopServices.openUrl(
                    QUrl.fromLocalFile(self.order.download_folder())))

        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addStretch()
        layout.addLayout(vlayout)

        self.setLayout(layout)
class ConnectCredentialsWidget(QWidget):
    rememberStateChanged = pyqtSignal(int)

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.leLogin = IconLineEdit(self)
        self.leLogin.setIcon(QIcon(os.path.join(iconsPath, "envelope.svg")))
        self.leLogin.setPlaceholderText("Email")

        self.lePassword = PasswordLineEdit(self)

        self.chkRemember = QCheckBox(self)
        self.chkRemember.setText("Remember me")

        self.lblResetPassword = QLabel(self)
        self.lblResetPassword.setAlignment(Qt.AlignCenter)
        self.lblResetPassword.setOpenExternalLinks(True)
        self.lblResetPassword.setTextInteractionFlags(Qt.LinksAccessibleByKeyboard | Qt.LinksAccessibleByMouse)
        self.lblResetPassword.setText("<html><head/><body><p><a href='https://boundlessgeo.auth0.com/login?client=rmtncamSKiwRBuVYTvFYJGtTspVuplMh'><span style='text-decoration: underline; color:#0000ff;'>Don't remember your password?</span></a></p></body></html>")

        self.lblRegister = QLabel(self)
        self.lblRegister.setAlignment(Qt.AlignCenter)
        self.lblRegister.setOpenExternalLinks(True)
        self.lblRegister.setTextInteractionFlags(Qt.LinksAccessibleByKeyboard | Qt.LinksAccessibleByMouse)
        self.lblRegister.setText("<html><head/><body><p><a href='https://connect.boundlessgeo.com'><span style='text-decoration: underline; color:#0000ff;'>Don't have an account?</span></a></p></body></html>")

        self.layout = QVBoxLayout(self)
        self.layout.addWidget(self.leLogin)
        self.layout.addWidget(self.lePassword)
        self.layout.addWidget(self.chkRemember)
        self.layout.addWidget(self.lblResetPassword)
        self.layout.addWidget(self.lblRegister)
        self.setLayout(self.layout)

        self.chkRemember.stateChanged.connect(self.rememberCheckChanged)


    def login(self):
        return self.leLogin.text()

    def setLogin(self, login):
        self.leLogin.setText(login)

    def password(self):
        return self.lePassword.text()

    def setPassword(self, password):
        self.lePassword.setText(password)

    def remember(self):
        return self.chkRemember.isChecked()

    def setRemember(self, state):
        self.chkRemember.setCheckState(state)

    def rememberCheckChanged(self, state):
        self.rememberStateChanged.emit(state)
Esempio n. 5
0
 def show_error(self, error_text):
     self.lstSearchResult.clear()
     new_widget = QLabel()
     new_widget.setTextFormat(Qt.RichText)
     new_widget.setOpenExternalLinks(True)
     new_widget.setWordWrap(True)
     new_widget.setText(
         u"<div align='center'> <strong>{}</strong> </div><div align='center' style='margin-top: 3px'> {} </div>"
         .format(self.tr('Error'), error_text))
     new_item = QListWidgetItem(self.lstSearchResult)
     new_item.setSizeHint(new_widget.sizeHint())
     self.lstSearchResult.addItem(new_item)
     self.lstSearchResult.setItemWidget(new_item, new_widget)
Esempio n. 6
0
 def search_finished_progress(self):
     self.lstSearchResult.takeItem(0)
     if self.lstSearchResult.count() == 0:
         new_widget = QLabel()
         new_widget.setTextFormat(Qt.RichText)
         new_widget.setOpenExternalLinks(True)
         new_widget.setWordWrap(True)
         new_widget.setText(
             u"<div align='center'> <strong>{}</strong> </div><div align='center' style='margin-top: 3px'> {} </div>"
             .format(
                 self.tr(u"No results."),
                 self.
                 tr(u"You can add a service to become searchable. Start <a href='{}'>here</a>."
                    ).format(u"https://qms.nextgis.com/create"),
             ))
         new_item = QListWidgetItem(self.lstSearchResult)
         new_item.setSizeHint(new_widget.sizeHint())
         self.lstSearchResult.addItem(new_item)
         self.lstSearchResult.setItemWidget(new_item, new_widget)
 def show_error(self, error_text):
     self.lstSearchResult.clear()
     new_widget = QLabel()
     new_widget.setTextFormat(Qt.RichText)
     new_widget.setOpenExternalLinks(True)
     new_widget.setWordWrap(True)
     new_widget.setText(
         u"<div align='center'> <strong>{}</strong> </div><div align='center' style='margin-top: 3px'> {} </div>".format(
             self.tr('Error'),
             error_text
         )
     )
     new_item = QListWidgetItem(self.lstSearchResult)
     new_item.setSizeHint(new_widget.sizeHint())
     self.lstSearchResult.addItem(new_item)
     self.lstSearchResult.setItemWidget(
         new_item,
         new_widget
     )
 def search_finished_progress(self):
     self.lstSearchResult.takeItem(0)
     if self.lstSearchResult.count() == 0:
         new_widget = QLabel()
         new_widget.setTextFormat(Qt.RichText)
         new_widget.setOpenExternalLinks(True)
         new_widget.setWordWrap(True)
         new_widget.setText(
             u"<div align='center'> <strong>{}</strong> </div><div align='center' style='margin-top: 3px'> {} </div>".format(
                 self.tr(u"No results."),
                 self.tr(u"You can add a service to become searchable. Start <a href='{}'>here</a>.").format(
                     u"https://qms.nextgis.com/create"
                 ),
             )
         )
         new_item = QListWidgetItem(self.lstSearchResult)
         new_item.setSizeHint(new_widget.sizeHint())
         self.lstSearchResult.addItem(new_item)
         self.lstSearchResult.setItemWidget(
             new_item,
             new_widget
         )
    def __init__(self, order, dialog):
        super().__init__()
        self.dialog = dialog
        self.order = order
        txt = (
            '<style>h3{margin-bottom: 0px;}</style>'
            f'<b><h3>Order {order.name()}</h3></b>'
            f'<b>Placed on</b>: {order.date()}<br>'
            f'<b>Id</b>: {order.id()}<br>'
            f'<b>Imagery source</b>: {order.item_type()}<br>'
            #f'<b>Assets ordered</b>: {order.assets_ordered()}<br>'
            #f'<b>File format</b>: {order.file_format()}<br>'
            f'<b>Asset count</b>: {order.assets_count()}<br>')

        label = QLabel(txt)
        if not order.is_zipped():
            label.setStyleSheet("color: gray")
        button = QPushButton(
            'Re-Download' if order.downloaded() else 'Download')
        button.clicked.connect(self.download)
        button.setEnabled(order.state() == 'success' and order.is_zipped())

        vlayout = QVBoxLayout()
        vlayout.addWidget(button)
        if order.downloaded():
            labelOpenFolder = QLabel("<a href='#'>Open order folder</a>")
            vlayout.addWidget(labelOpenFolder)
            labelOpenFolder.setOpenExternalLinks(False)
            labelOpenFolder.linkActivated.connect(
                lambda: QDesktopServices.openUrl(
                    QUrl.fromLocalFile(self.order.download_folder())))

        layout = QHBoxLayout()
        layout.addWidget(label)
        layout.addStretch()
        layout.addLayout(vlayout)

        self.setLayout(layout)
Esempio n. 10
0
    def _creaFila(self, text1, text2):
        lbl1 = QLabel(text1)
        lbl2 = QLabel(text2)

        # Per si hi ha algun enllaç
        lbl1.setOpenExternalLinks(True)
        lbl2.setOpenExternalLinks(True)

        # SizePolicy
        lbl1.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        lbl2.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)

        # Fonts
        # Fem una còpia de la font dels textos per posar-la en negreta
        fontNoms = QFont(QvConstants.FONTTEXT)
        fontNoms.setBold(True)
        lbl1.setFont(fontNoms)
        lbl2.setFont(QvConstants.FONTTEXT)

        self._lay.addWidget(lbl1, self._i, 0, Qt.AlignTop | Qt.AlignRight)
        self._lay.addWidget(lbl2, self._i, 1, Qt.AlignTop)

        self._i += 1
Esempio n. 11
0
class PlanetOrderItemTypeWidget(QWidget):

    selectionChanged = pyqtSignal()

    def __init__(self, item_type, images):
        super().__init__()

        self.thumbnails = []

        self.item_type = item_type
        self.images = images

        layout = QGridLayout()
        layout.setMargin(0)

        self.labelThumbnail = QLabel()
        pixmap = QPixmap(PLACEHOLDER_THUMB, "SVG")
        thumb = pixmap.scaled(96, 96, Qt.KeepAspectRatio,
                              Qt.SmoothTransformation)
        self.labelThumbnail.setPixmap(thumb)
        self.labelThumbnail.setFixedSize(96, 96)
        layout.addWidget(self.labelThumbnail, 0, 0, 3, 1)

        for image in images:
            url = f"{image['_links']['thumbnail']}?api_key={PlanetClient.getInstance().api_key()}"
            download_thumbnail(url, self)

        labelName = IconLabel(
            f"<b>{PlanetClient.getInstance().item_types_names()[self.item_type]}</b>",
            SATELLITE_ICON,
        )
        labelNumItems = IconLabel(f"{len(images)} items", NITEMS_ICON)
        layout.addWidget(labelNumItems, 0, 1)
        layout.addWidget(labelName, 1, 1)

        self.btnDetails = QPushButton()
        self.btnDetails.setFlat(True)
        self.btnDetails.setIcon(EXPAND_MORE_ICON)
        self.btnDetails.clicked.connect(self._btnDetailsClicked)
        layout.addWidget(self.btnDetails, 0, 2)

        self.widgetDetails = QWidget()
        layout.addWidget(self.widgetDetails, 3, 0, 1, 3)

        line = QFrame()
        line.setFrameShape(QFrame.HLine)
        line.setFrameShadow(QFrame.Sunken)
        layout.addWidget(line, 4, 0, 1, 3)

        self.setLayout(layout)

        self.widgetDetails.hide()
        self.updateGeometry()

        self.populate_details()

    def populate_details(self):
        self.bundleWidgets = []

        client = PlanetClient.getInstance()
        permissions = [img[PERMISSIONS] for img in self.images]
        item_bundles = client.bundles_for_item_type(self.item_type,
                                                    permissions=permissions)
        default = default_bundles.get(self.item_type, "")

        def _center(obj):
            hlayout = QHBoxLayout()
            hlayout.addStretch()
            hlayout.addWidget(obj)
            hlayout.addStretch()
            return hlayout

        layout = QVBoxLayout()
        layout.setMargin(0)
        layout.setSpacing(20)

        layout.addLayout(_center(QLabel("<b>RECTIFIED ASSETS</b>")))

        gridlayout = QGridLayout()
        gridlayout.setMargin(0)

        widgets = {}
        i = 0
        for bundleid, bundle in item_bundles.items():
            if bundle["rectification"] == "orthorectified":
                name = bundle["name"]
                description = bundle["description"]
                udm = bundle.get("auxiliaryFiles",
                                 "").lower().startswith("udm2")
                assets = bundle["assets"][self.item_type]
                can_harmonize = ("ortho_analytic_4b_sr" in assets
                                 or "ortho_analytic_8b_sr" in assets)
                w = PlanetOrderBundleWidget(bundleid, name, description, udm,
                                            can_harmonize, True)
                gridlayout.addWidget(w, i // 2, i % 2)
                w.setSelected(False)
                widgets[bundleid] = w
                w.selectionChanged.connect(
                    partial(self._bundle_selection_changed, w))
                self.bundleWidgets.append(w)
                i += 1

        selected = False
        for defaultid in default:
            for bundleid, w in widgets.items():
                if defaultid == bundleid:
                    w.setSelected(True)
                    selected = True
                    break
            if selected:
                break

        layout.addLayout(gridlayout)

        self.labelUnrectified = QLabel("<b>UNRECTIFIED ASSETS</b>")
        layout.addLayout(_center(self.labelUnrectified))

        self.widgetUnrectified = QWidget()

        gridlayoutUnrect = QGridLayout()
        gridlayoutUnrect.setMargin(0)

        i = 0
        for bundleid, bundle in item_bundles.items():
            if bundle["rectification"] != "orthorectified":
                name = bundle["name"]
                description = bundle["description"]
                udm = bundle.get("auxiliaryFiles",
                                 "").lower().startswith("udm2")
                assets = bundle["assets"][self.item_type]
                can_harmonize = ("ortho_analytic_4b_sr" in assets
                                 or "ortho_analytic_8b_sr" in assets)
                w = PlanetOrderBundleWidget(bundleid, name, description, udm,
                                            can_harmonize, False)
                gridlayoutUnrect.addWidget(w, i // 2, i % 2)
                w.selectionChanged.connect(
                    partial(self._bundle_selection_changed, w))
                self.bundleWidgets.append(w)
                i += 1

        self.widgetUnrectified.setLayout(gridlayoutUnrect)
        layout.addWidget(self.widgetUnrectified)

        self.labelMore = QLabel('<a href="#">+ Show More</a>')
        self.labelMore.setOpenExternalLinks(False)
        self.labelMore.setTextInteractionFlags(Qt.LinksAccessibleByMouse)
        self.labelMore.linkActivated.connect(self._showMoreClicked)
        layout.addLayout(_center(self.labelMore))

        self.widgetUnrectified.hide()
        self.labelUnrectified.hide()
        self.widgetDetails.setLayout(layout)

    def _bundle_selection_changed(self, widget):
        for w in self.bundleWidgets:
            if widget != w:
                w.setSelected(False, False)
        self.selectionChanged.emit()

    def _showMoreClicked(self):
        visible = self.widgetUnrectified.isVisible()
        self.widgetUnrectified.setVisible(not visible)
        self.labelUnrectified.setVisible(not visible)
        if visible:
            self.labelMore.setText('<a href="#">+ Show More</a>')
        else:
            self.labelMore.setText('<a href="#">- Show Less</a>')

    def expand(self):
        self.widgetDetails.show()
        self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()

    def _btnDetailsClicked(self):
        if self.widgetDetails.isVisible():
            self.widgetDetails.hide()
            self.btnDetails.setIcon(EXPAND_MORE_ICON)
        else:
            self.widgetDetails.show()
            self.btnDetails.setIcon(EXPAND_LESS_ICON)
        self.updateGeometry()

    def bundles(self):
        bundles = []
        for w in self.bundleWidgets:
            if w.selected():
                bundle = {}
                bundle["id"] = w.bundleid
                bundle["name"] = w.name
                bundle["filetype"] = w.filetype()
                bundle["udm"] = w.udm
                bundle["rectified"] = w.rectified
                bundle["canharmonize"] = w.can_harmonize
                bundles.append(bundle)
        return bundles

    def set_thumbnail(self, img):
        thumbnail = QPixmap(img)
        self.thumbnails.append(
            thumbnail.scaled(96, 96, Qt.KeepAspectRatio,
                             Qt.SmoothTransformation))

        if len(self.images) == len(self.thumbnails):
            bboxes = [img[GEOMETRY] for img in self.images]
            pixmap = createCompoundThumbnail(bboxes, self.thumbnails)
            thumb = pixmap.scaled(128, 128, Qt.KeepAspectRatio,
                                  Qt.SmoothTransformation)
            self.labelThumbnail.setPixmap(thumb)
Esempio n. 12
0
class QmsSearchResultItemWidget(QWidget):
    def __init__(self,
                 geoservice,
                 image_ba,
                 parent=None,
                 extent_renderer=None):
        QWidget.__init__(self, parent)

        self.extent_renderer = extent_renderer

        self.layout = QHBoxLayout(self)
        self.layout.setContentsMargins(5, 10, 5, 10)
        self.setLayout(self.layout)

        self.service_icon = QLabel(self)
        self.service_icon.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.service_icon.resize(24, 24)

        qimg = QImage.fromData(image_ba)
        pixmap = QPixmap.fromImage(qimg)
        self.service_icon.setPixmap(pixmap)
        self.layout.addWidget(self.service_icon)

        self.service_desc_layout = QGridLayout(self)
        self.service_desc_layout.setSpacing(0)
        self.layout.addLayout(self.service_desc_layout)

        self.service_name = QLabel(self)
        self.service_name.setTextFormat(Qt.RichText)
        self.service_name.setWordWrap(True)
        self.service_name.setText(u"   <strong> {} </strong>".format(
            geoservice.get('name', u"")))
        self.service_desc_layout.addWidget(self.service_name, 0, 0, 1, 3)

        self.service_type = QLabel(self)
        self.service_type.setTextFormat(Qt.RichText)
        self.service_type.setWordWrap(True)
        self.service_type.setText(geoservice.get('type', u"").upper() + " ")
        self.service_desc_layout.addWidget(self.service_type, 1, 0)

        self.service_deteils = QLabel(self)
        self.service_deteils.setTextFormat(Qt.RichText)
        self.service_deteils.setWordWrap(True)
        self.service_deteils.setOpenExternalLinks(True)
        self.service_deteils.setText(u"<a href=\"{0}\">{1}</a>, ".format(
            Client().geoservice_info_url(geoservice.get('id', u"")),
            self.tr('details')))
        self.service_desc_layout.addWidget(self.service_deteils, 1, 1)

        self.service_report = QLabel(self)
        self.service_report.setTextFormat(Qt.RichText)
        self.service_report.setWordWrap(True)
        self.service_report.setOpenExternalLinks(True)
        self.service_report.setText(u"<a href=\"{0}\">{1}</a><div/>".format(
            Client().geoservice_report_url(geoservice.get('id', u"")),
            self.tr('report a problem')))
        self.service_desc_layout.addWidget(self.service_report, 1, 2)
        self.service_desc_layout.setColumnStretch(2, 1)

        self.status_label = QLabel(self)
        self.status_label.setTextFormat(Qt.RichText)
        self.status_label.setText(u'\u2022')

        status = geoservice.get('cumulative_status', u'')
        if status == 'works':
            self.status_label.setStyleSheet("color: green; font-size: 30px")
        if status == 'failed':
            self.status_label.setStyleSheet("color: red; font-size: 30px")
        if status == 'problematic':
            self.status_label.setStyleSheet("color: yellow; font-size: 30px")
        self.layout.addWidget(self.status_label)

        self.addButton = QToolButton()
        self.addButton.setText(self.tr("Add"))
        self.addButton.clicked.connect(self.addToMap)
        self.layout.addWidget(self.addButton)

        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)

        self.geoservice = geoservice
        self.image_ba = image_ba

    def addToMap(self):
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            client = Client()
            client.set_proxy(*QGISSettings.get_qgis_proxy())
            geoservice_info = client.get_geoservice_info(self.geoservice)
            ds = DataSourceSerializer.read_from_json(geoservice_info)
            add_layer_to_map(ds)

            CachedServices().add_service(self.geoservice, self.image_ba)
        except Exception as ex:
            plPrint(unicode(ex))
            pass
        finally:
            QApplication.restoreOverrideCursor()

    def mouseDoubleClickEvent(self, event):
        self.addToMap()

    def enterEvent(self, event):
        extent = self.geoservice.get('extent', None)
        if self.extent_renderer and extent:
            if ';' in extent:
                extent = extent.split(';')[1]
            geom = QgsGeometry.fromWkt(extent)
            self.extent_renderer.show_feature(geom)

    def leaveEvent(self, event):
        if self.extent_renderer:
            self.extent_renderer.clear_feature()
class QmsSearchResultItemWidget(QWidget):
    def __init__(self, geoservice, image_ba, parent=None, extent_renderer=None):
        QWidget.__init__(self, parent)

        self.extent_renderer = extent_renderer

        self.layout = QHBoxLayout(self)
        self.layout.setContentsMargins(5, 10, 5, 10)
        self.setLayout(self.layout)

        self.service_icon = QLabel(self)
        self.service_icon.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.service_icon.resize(24, 24)

        qimg = QImage.fromData(image_ba)
        pixmap = QPixmap.fromImage(qimg)
        self.service_icon.setPixmap(pixmap)
        self.layout.addWidget(self.service_icon)

        self.service_desc_layout = QGridLayout(self)
        self.service_desc_layout.setSpacing(0)
        self.layout.addLayout(self.service_desc_layout)

        self.service_name = QLabel(self)
        self.service_name.setTextFormat(Qt.RichText)
        self.service_name.setWordWrap(True)
        self.service_name.setText(u"   <strong> {} </strong>".format(geoservice.get('name', u"")))
        self.service_desc_layout.addWidget(self.service_name, 0, 0, 1, 3)

        self.service_type = QLabel(self)
        self.service_type.setTextFormat(Qt.RichText)
        self.service_type.setWordWrap(True)
        self.service_type.setText(geoservice.get('type', u"").upper() + " ")
        self.service_desc_layout.addWidget(self.service_type, 1, 0)

        self.service_deteils = QLabel(self)
        self.service_deteils.setTextFormat(Qt.RichText)
        self.service_deteils.setWordWrap(True)
        self.service_deteils.setOpenExternalLinks(True)
        self.service_deteils.setText(u"<a href=\"{0}\">{1}</a>, ".format(
            Client().geoservice_info_url(geoservice.get('id', u"")),
            self.tr('details')
        ))
        self.service_desc_layout.addWidget(self.service_deteils, 1, 1)

        self.service_report = QLabel(self)
        self.service_report.setTextFormat(Qt.RichText)
        self.service_report.setWordWrap(True)
        self.service_report.setOpenExternalLinks(True)
        self.service_report.setText(u"<a href=\"{0}\">{1}</a><div/>".format(
            Client().geoservice_report_url(geoservice.get('id', u"")),
            self.tr('report a problem')
        ))
        self.service_desc_layout.addWidget(self.service_report, 1, 2)
        self.service_desc_layout.setColumnStretch(2, 1)


        self.status_label = QLabel(self)
        self.status_label.setTextFormat(Qt.RichText)
        self.status_label.setText(u'\u2022')


        status = geoservice.get('cumulative_status', u'')
        if status == 'works':
            self.status_label.setStyleSheet("color: green; font-size: 30px")
        if status == 'failed':
            self.status_label.setStyleSheet("color: red; font-size: 30px")
        if status == 'problematic':
            self.status_label.setStyleSheet("color: yellow; font-size: 30px")
        self.layout.addWidget(self.status_label)


        self.addButton = QToolButton()
        self.addButton.setText(self.tr("Add"))
        self.addButton.clicked.connect(self.addToMap)
        self.layout.addWidget(self.addButton)
        
        self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum)

        self.geoservice = geoservice
        self.image_ba = image_ba

    def addToMap(self):
        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
            client = Client()
            client.set_proxy(*QGISSettings.get_qgis_proxy())
            geoservice_info = client.get_geoservice_info(self.geoservice)
            ds = DataSourceSerializer.read_from_json(geoservice_info)
            add_layer_to_map(ds)

            CachedServices().add_service(self.geoservice, self.image_ba)
        except Exception as ex:
            plPrint(unicode(ex))
            pass
        finally:
            QApplication.restoreOverrideCursor()

    def mouseDoubleClickEvent(self, event):
        self.addToMap()

    def enterEvent(self, event):
        extent = self.geoservice.get('extent', None)
        if self.extent_renderer and extent:
            if ';' in extent:
                extent = extent.split(';')[1]
            geom = QgsGeometry.fromWkt(extent)
            self.extent_renderer.show_feature(geom)

    def leaveEvent(self, event):
        if self.extent_renderer:
            self.extent_renderer.clear_feature()
def fill_tree_with_element(widget,
                           treeItem,
                           elt,
                           ns_imap={},
                           custom_viewers={},
                           ns_map={}):
    """
    :param widget: the QTreeWidget
    :param treeItem: a QTreeWidgetItem to fill
    :param elt: the XML node
    :param ns_imap: an "inverse" namespace map { uri : prefix }
    :param custom_viewers: a dict giving a custom viewer plugin (QWidget) for some elements {tag : constructor}
    :param ns_map: a namespace map { prefix : uri }
    """
    is_root = treeItem == widget.invisibleRootItem()
    # tag
    ns, tag = split_tag(elt.tag)
    if ns and ns_imap.get(ns):
        treeItem.setText(0, ns_imap[ns] + ":" + tag)
    else:
        treeItem.setText(0, tag)
    f = treeItem.font(0)
    f.setBold(True)
    treeItem.setFont(0, f)

    # custom viewer
    if elt.tag in custom_viewers:
        custom_viewer_widget, filter = custom_viewers[elt.tag]
        if filter is None or elt.find(filter, ns_map) is not None:
            btn = QToolButton(widget)
            btn.setIcon(custom_viewer_widget.icon())
            btn.setIconSize(QSize(32, 32))

            def show_viewer(btn):
                widget.w = custom_viewer_widget.init_from_xml(elt)
                widget.w.setWindowModality(Qt.WindowModal)
                widget.w.show()

            btn.clicked.connect(show_viewer)

            w = QWidget(widget)
            l = QHBoxLayout()
            l.addWidget(btn)
            l.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding))
            w.setLayout(l)
            if is_root:
                # insert an item
                child = QTreeWidgetItem()
                treeItem.addChild(child)
                widget.setItemWidget(child, 0, w)
            else:
                widget.setItemWidget(treeItem, 1, w)

    # attributes
    for k, v in elt.attrib.items():
        child = QTreeWidgetItem()
        treeItem.addChild(child)
        if "}" in k:
            i = k.index("}")
            ns = k[1:i]
            # get ns prefix from ns uri
            p = ns_imap.get(ns)
            if p is not None:
                n = p + ":" + k[i + 1:]
            else:
                n = k[i + 1:]
        else:
            n = no_prefix(k)
        child.setText(0, "@" + n)
        if n == "xlink:href" and v.startswith("http"):
            html = QLabel(widget)
            html.setOpenExternalLinks(True)
            html.setTextFormat(Qt.RichText)
            html.setText('<a href="{}">{}</a>'.format(v, v))
            child.setData(1, Qt.UserRole, v)
            widget.setItemWidget(child, 1, html)
        else:
            child.setText(1, v)
    # text
    if elt.text:
        treeItem.setText(1, elt.text)

    # children
    for xmlChild in elt:
        child = QTreeWidgetItem()
        treeItem.addChild(child)
        fill_tree_with_element(widget, child, xmlChild, ns_imap,
                               custom_viewers, ns_map)