Пример #1
0
    def __init__(self, parent=None, settings_dict=None, wms_connected=False):
        """
        Arguments:
        parent -- Qt widget that is parent to this widget.
        settings_dict -- dictionary containing topview options.
        """
        super(MSS_TV_MapAppearanceDialog, self).__init__(parent)
        self.setupUi(self)
        if settings_dict is None:
            settings_dict = {"draw_graticule": True,
                             "draw_coastlines": True,
                             "fill_waterbodies": True,
                             "fill_continents": True,
                             "draw_flighttrack": True,
                             "label_flighttrack": True,
                             "colour_water": (0, 0, 0, 0),
                             "colour_land": (0, 0, 0, 0),
                             "colour_ft_vertices": (0, 0, 0, 0),
                             "colour_ft_waypoints": (0, 0, 0, 0)}

        settings_dict["fill_waterbodies"] = True  # removing water bodies does not work properly

        self.wms_connected = wms_connected
        # check parent.wms_connected to disable cbFillWaterBodies and cbFillContinents
        if self.wms_connected:
            self.cbFillContinents.setChecked(False)
            self.cbFillWaterBodies.setChecked(False)
            self.cbFillContinents.setEnabled(False)
            self.cbFillContinents.setStyleSheet("color: black")
            self.cbFillWaterBodies.setStyleSheet("color: black")
        else:
            self.cbFillWaterBodies.setChecked(settings_dict["fill_waterbodies"])
            self.cbFillWaterBodies.setEnabled(False)
            self.cbFillContinents.setChecked(settings_dict["fill_continents"])
            self.cbFillContinents.setEnabled(True)

        self.cbDrawGraticule.setChecked(settings_dict["draw_graticule"])
        self.cbDrawCoastlines.setChecked(settings_dict["draw_coastlines"])
        self.cbDrawFlightTrack.setChecked(settings_dict["draw_flighttrack"])
        self.cbLabelFlightTrack.setChecked(settings_dict["label_flighttrack"])

        for button, ids in [(self.btWaterColour, "colour_water"),
                            (self.btLandColour, "colour_land"),
                            (self.btWaypointsColour, "colour_ft_waypoints"),
                            (self.btVerticesColour, "colour_ft_vertices")]:
            palette = QtGui.QPalette(button.palette())
            colour = QtGui.QColor()
            colour.setRgbF(*settings_dict[ids])
            palette.setColor(QtGui.QPalette.Button, colour)
            button.setPalette(palette)

        # Connect colour button signals.
        self.btWaterColour.clicked.connect(functools.partial(self.setColour, "water"))
        self.btLandColour.clicked.connect(functools.partial(self.setColour, "land"))
        self.btWaypointsColour.clicked.connect(functools.partial(self.setColour, "ft_waypoints"))
        self.btVerticesColour.clicked.connect(functools.partial(self.setColour, "ft_vertices"))
Пример #2
0
    def __init__(self, parent=None, view=None):
        """
        Arguments:
        parent -- Qt widget that is parent to this widget.
        view -- reference to mpl canvas class
        """
        super(RemoteSensingControlWidget, self).__init__(parent)
        self.setupUi(self)

        self.view = view
        self.load = Loader(MSS_CONFIG_PATH, verbose=False)
        self.planets = self.load('de421.bsp')
        self.timescale = self.load.timescale(builtin=True)
        # don't download files, use shipped files

        button = self.btTangentsColour
        palette = QtGui.QPalette(button.palette())
        colour = QtGui.QColor()
        colour.setRgbF(1, 0, 0, 1)
        palette.setColor(QtGui.QPalette.Button, colour)
        button.setPalette(palette)

        self.dsbTangentHeight.setValue(10.)
        self.dsbObsAngleAzimuth.setValue(90.)
        self.dsbObsAngleElevation.setValue(-1.0)

        # update plot on every value change
        self.cbDrawTangents.stateChanged.connect(self.update_settings)
        self.cbShowSolarAngle.stateChanged.connect(self.update_settings)
        self.btTangentsColour.clicked.connect(self.set_tangentpoint_colour)
        self.dsbTangentHeight.valueChanged.connect(self.update_settings)
        self.dsbObsAngleAzimuth.valueChanged.connect(self.update_settings)
        self.dsbObsAngleElevation.valueChanged.connect(self.update_settings)
        self.cbSolarBody.currentIndexChanged.connect(self.update_settings)
        self.cbSolarAngleType.currentIndexChanged.connect(self.update_settings)
        self.lbSolarCmap.setText(
            "Solar angle colours, dark to light: reds (0-15), violets (15-45), greens (45-180)"
        )
        self.solar_cmap = ListedColormap([(1.00, 0.00, 0.00, 1.0),
                                          (1.00, 0.45, 0.00, 1.0),
                                          (1.00, 0.75, 0.00, 1.0),
                                          (0.47, 0.10, 1.00, 1.0),
                                          (0.72, 0.38, 1.00, 1.0),
                                          (1.00, 0.55, 1.00, 1.0),
                                          (0.00, 0.70, 0.00, 1.0),
                                          (0.33, 0.85, 0.33, 1.0),
                                          (0.65, 1.00, 0.65, 1.0)])
        self.solar_norm = BoundaryNorm(
            [0, 5, 10, 15, 25, 35, 45, 90, 135, 180], self.solar_cmap.N)

        self.update_settings()
Пример #3
0
    def open_customize_kml_dialog(self):
        file = self.listWidget.currentItem().text()
        # Set the colour of the Colour button to the colour of specific KML plot
        if self.dict_files[file]["color"] is not None:
            palette = QtGui.QPalette(self.dialog.pushButton_colour.palette())
            colour = QtGui.QColor()
            colour.setRgbF(*self.set_color(file))
            palette.setColor(QtGui.QPalette.Button, colour)
            self.dialog.pushButton_colour.setPalette(palette)
        # Set the linewidth value to the linewidth of specific KML plot
        if self.dict_files[file]["linewidth"] is not None:
            self.dialog.dsb_linewidth.setValue(self.set_linewidth(file))

        self.dialog.show()
Пример #4
0
 def paint(self, painter, option, index):
     """Colours waypoints with a minor waypoint number (i.e. intermediate
        waypoints generated by the flight performance service) in red.
     """
     wpnumber_minor = index.model().waypoint_data(
         index.row()).wpnumber_minor
     if wpnumber_minor is not None and wpnumber_minor > 0:
         newpalette = QtGui.QPalette(option.palette)
         colour = QtGui.QColor(170, 0, 0)  # dark red
         newpalette.setColor(QtGui.QPalette.Text, colour)
         colour = QtGui.QColor(255, 255, 0)  # yellow
         newpalette.setColor(QtGui.QPalette.HighlightedText, colour)
         option.palette = newpalette
     QtWidgets.QItemDelegate.paint(self, painter, option, index)
Пример #5
0
    def __init__(self, parent=None, model=None, _id=None):
        """
        """
        super(MSSTableViewWindow, self).__init__(parent, model, _id)
        self.setupUi(self)
        self.setWindowIcon(QtGui.QIcon(icons('64x64')))

        self.setFlightTrackModel(model)
        self.tableWayPoints.setItemDelegate(ft.WaypointDelegate(self))

        toolitems = ["(select to open control)", "Hexagon Control"]
        self.cbTools.clear()
        self.cbTools.addItems(toolitems)
        self.tableWayPoints.dropEvent = types.MethodType(
            dropEvent, self.tableWayPoints)
        self.tableWayPoints.dragEnterEvent = types.MethodType(
            dragEnterEvent, self.tableWayPoints)
        # Dock windows [Hexagon].
        self.docks = [None]

        # Connect slots and signals.
        self.btAddWayPointToFlightTrack.clicked.connect(self.addWayPoint)
        self.btCloneWaypoint.clicked.connect(self.cloneWaypoint)
        self.btDeleteWayPoint.clicked.connect(self.removeWayPoint)
        self.btInvertDirection.clicked.connect(self.invertDirection)
        self.btViewPerformance.clicked.connect(self.settingsDlg)
        # Tool opener.
        self.cbTools.currentIndexChanged.connect(self.openTool)

        self.resizeColumns()
Пример #6
0
    def __init__(self, parent=None, model=None, _id=None):
        """Set up user interface, connect signal/slots.
        """
        super(MSSTopViewWindow, self).__init__(parent, model, _id)
        logging.debug(_id)
        self.setupUi(self)
        self.setWindowIcon(QtGui.QIcon(icons('64x64')))

        # Dock windows [WMS, Satellite, Trajectories, Remote Sensing, KML Overlay]:
        self.docks = [None, None, None, None, None]

        self.settings_tag = "topview"
        self.load_settings()

        # Initialise the GUI elements (map view, items of combo boxes etc.).
        self.setup_top_view()

        # Boolean to store active wms connection
        self.wms_connected = False

        # Connect slots and signals.
        # ==========================

        # Map controls.
        self.btMapRedraw.clicked.connect(self.mpl.canvas.redraw_map)
        self.cbChangeMapSection.activated.connect(self.changeMapSection)

        # Settings
        self.btSettings.clicked.connect(self.settings_dialogue)

        # Tool opener.
        self.cbTools.currentIndexChanged.connect(self.openTool)
Пример #7
0
 def setup_message_box_layout(self):
     container_layout = QtWidgets.QHBoxLayout()
     text_area_layout = QtWidgets.QVBoxLayout()
     if self.chat_window.user["username"] == self.username:
         text_area_layout.addWidget(self.messageBox)
         self.textArea.setLayout(text_area_layout)
         container_layout.addStretch()
         container_layout.addWidget(self.textArea)
     else:
         username_label = QtWidgets.QLabel(f"{self.username}")
         username_label.setContentsMargins(5, 5, 5, 0)
         label_font = QtGui.QFont()
         label_font.setBold(True)
         username_label.setFont(label_font)
         text_area_layout.addWidget(username_label)
         text_area_layout.addWidget(self.messageBox)
         self.textArea.setLayout(text_area_layout)
         container_layout.addWidget(self.textArea)
         container_layout.addStretch()
     for reply in self.replies:
         self.add_message_reply(reply)
     self.textArea.layout().setSpacing(0)
     self.textArea.layout().setContentsMargins(0, 0, 0, 0)
     container_layout.setSpacing(0)
     container_layout.setContentsMargins(5, 5, 5, 5)
     self.set_message_style()
     self.setLayout(container_layout)
Пример #8
0
 def get_color(self):
     """
     Returns the colour of the 'pushButton_colour' Button
     """
     button = self.dialog.pushButton_colour
     return QtGui.QPalette(button.palette()).color(
         QtGui.QPalette.Button).getRgbF()
Пример #9
0
    def __init__(self, parent=None, model=None, _id=None):
        """Set up user interface, connect signal/slots.
        """
        super(MSSSideViewWindow, self).__init__(parent, model, _id)
        self.setupUi(self)
        self.setWindowIcon(QtGui.QIcon(icons('64x64')))

        # Dock windows [WMS]:
        self.cbTools.clear()
        self.cbTools.addItems(["(select to open control)", "Vertical Section WMS"])
        self.docks = [None]

        self.setFlightTrackModel(model)

        self.settings_tag = "sideview"
        self.load_settings()

        # Connect slots and signals.
        # ==========================

        # Buttons to set sideview options.
        self.btOptions.clicked.connect(self.set_options)

        # Tool opener.
        self.cbTools.currentIndexChanged.connect(self.openTool)
Пример #10
0
 def setup_image_message_box(self):
     MAX_WIDTH = MAX_HEIGHT = 300
     self.messageBox = QtWidgets.QLabel()
     img_url = url_join(self.chat_window.mscolab_server_url,
                        self.attachment_path)
     data = requests.get(img_url).content
     image = QtGui.QImage()
     image.loadFromData(data)
     self.message_image = image
     width, height = image.size().width(), image.size().height()
     if width > height and width > MAX_WIDTH:
         image = image.scaledToWidth(MAX_WIDTH)
     elif height > width and height > MAX_HEIGHT:
         image = image.scaledToHeight(MAX_HEIGHT)
     self.messageBox.setPixmap(QtGui.QPixmap(image))
     self.messageBox.setContentsMargins(0, 5, 0, 5)
     self.messageBox.show()
Пример #11
0
 def display_uploaded_img(self, file_path):
     self.messageText.clear()
     image_uri = QtCore.QUrl(f"file://{file_path}")
     image = QtGui.QImage(QtGui.QImageReader(file_path).read())
     self.messageText.document().addResource(
         QtGui.QTextDocument.ImageResource, image_uri,
         QtCore.QVariant(image))
     img_width, img_height = self.get_img_dimensions(image)
     image_format = QtGui.QTextImageFormat()
     image_format.setWidth(img_width)
     image_format.setHeight(img_height)
     image_format.setName(image_uri.toString())
     cursor = self.messageText.textCursor()
     cursor.movePosition(QtGui.QTextCursor.End,
                         QtGui.QTextCursor.MoveAnchor)
     cursor.insertImage(image_format)
     self.messageText.setReadOnly(True)
Пример #12
0
 def add_message_reply(self, reply):
     if self.replyArea is None:
         self.insert_reply_area()
     reply_username_label = QtWidgets.QLabel(f'{reply["username"]}:')
     label_font = QtGui.QFont()
     label_font.setBold(True)
     reply_username_label.setFont(label_font)
     reply_message_box = self.get_text_browser(reply["text"])
     self.replyArea.layout().addRow(reply_username_label, reply_message_box)
Пример #13
0
 def _icon(self, name, *args):
     """
     wrapper around base method to inject our own icons.
     """
     myname = icons("32x32", name)
     if os.path.exists(myname):
         return QtGui.QIcon(myname)
     else:
         return super(NavigationToolbar, self)._icon(name, *args)
Пример #14
0
 def __init__(self, parent=None):
     """
     Arguments:
     parent -- Qt widget that is parent to this widget.
     """
     super(MSS_AboutDialog, self).__init__(parent)
     self.setupUi(self)
     self.lblVersion.setText("Version: {}".format(__version__))
     blub = QtGui.QPixmap(python_powered())
     self.lblPython.setPixmap(blub)
Пример #15
0
    def get_settings(self):
        """
        """
        settings_dict = {
            "draw_graticule": self.cbDrawGraticule.isChecked(),
            "draw_coastlines": self.cbDrawCoastlines.isChecked(),
            "fill_waterbodies": self.cbFillWaterBodies.isChecked(),
            "fill_continents": self.cbFillContinents.isChecked(),
            "draw_flighttrack": self.cbDrawFlightTrack.isChecked(),
            "label_flighttrack": self.cbLabelFlightTrack.isChecked(),

            "colour_water":
                QtGui.QPalette(self.btWaterColour.palette()).color(QtGui.QPalette.Button).getRgbF(),
            "colour_land":
                QtGui.QPalette(self.btLandColour.palette()).color(QtGui.QPalette.Button).getRgbF(),
            "colour_ft_vertices":
                QtGui.QPalette(self.btVerticesColour.palette()).color(QtGui.QPalette.Button).getRgbF(),
            "colour_ft_waypoints":
                QtGui.QPalette(self.btWaypointsColour.palette()).color(QtGui.QPalette.Button).getRgbF(),
        }
        return settings_dict
Пример #16
0
 def set_tangentpoint_colour(self):
     """Slot for the colour buttons: Opens a QColorDialog and sets the
        new button face colour.
     """
     button = self.btTangentsColour
     palette = QtGui.QPalette(button.palette())
     colour = palette.color(QtGui.QPalette.Button)
     colour = QtWidgets.QColorDialog.getColor(colour)
     if colour.isValid():
         palette.setColor(QtGui.QPalette.Button, colour)
         button.setPalette(palette)
     self.update_settings()
Пример #17
0
    def set_active_pid(self, item):
        if item.p_id == self.active_pid:
            return
            # close all hanging window
        self.force_close_view_windows()
        self.close_external_windows()
        # Turn off work locally toggle
        self.workLocallyCheckBox.blockSignals(True)
        self.workLocallyCheckBox.setChecked(False)
        self.workLocallyCheckBox.blockSignals(False)
        self.save_ft.setEnabled(False)
        self.fetch_ft.setEnabled(False)

        # set active_pid here
        self.active_pid = item.p_id
        self.access_level = item.access_level
        self.active_project_name = item.text().split("-")[0].strip()
        self.waypoints_model = None
        # set active flightpath here
        self.load_wps_from_server()
        # enable project specific buttons
        self.helperTextLabel.setVisible(True)
        self.helperTextLabel.setText(self.tr("Working On: Shared File. All your changes will be shared with everyone."
                                             "Turn on work locally to work on local flight track file"))
        self.importBtn.setEnabled(True)
        self.exportBtn.setEnabled(True)
        self.topview.setEnabled(True)
        self.sideview.setEnabled(True)
        self.tableview.setEnabled(True)
        self.workLocallyCheckBox.setEnabled(True)

        if self.access_level == "viewer" or self.access_level == "collaborator":
            if self.access_level == "viewer":
                self.chatWindowBtn.setEnabled(False)
            else:
                self.chatWindowBtn.setEnabled(True)
            self.adminWindowBtn.setEnabled(False)
            self.versionHistoryBtn.setEnabled(False)
        else:
            self.adminWindowBtn.setEnabled(True)
            self.chatWindowBtn.setEnabled(True)
            self.versionHistoryBtn.setEnabled(True)
        if self.access_level == "creator":
            self.deleteProjectBtn.setEnabled(True)
        else:
            self.deleteProjectBtn.setEnabled(False)
        # change font style for selected
        font = QtGui.QFont()
        for i in range(self.listProjects.count()):
            self.listProjects.item(i).setFont(font)
        font.setBold(True)
        item.setFont(font)
Пример #18
0
 def get_settings(self):
     """Return settings dictionary with values from the GUI elements.
     """
     settings_dict = {
         "vertical_extent": (float(self.sbPbot.value()), float(self.sbPtop.value())),
         "vertical_axis": self.cbVerticalAxis.currentText(),
         "flightlevels": self.get_flight_levels(),
         "draw_ceiling": self.cbDrawCeiling.isChecked(),
         "draw_flightlevels": self.cbDrawFlightLevels.isChecked(),
         "draw_flighttrack": self.cbDrawFlightTrack.isChecked(),
         "fill_flighttrack": self.cbFillFlightTrack.isChecked(),
         "label_flighttrack": self.cbLabelFlightTrack.isChecked(),
         "colour_ft_vertices":
             QtGui.QPalette(self.btVerticesColour.palette()).color(QtGui.QPalette.Button).getRgbF(),
         "colour_ft_waypoints":
             QtGui.QPalette(self.btWaypointsColour.palette()).color(QtGui.QPalette.Button).getRgbF(),
         "colour_ft_fill":
             QtGui.QPalette(self.btFillColour.palette()).color(QtGui.QPalette.Button).getRgbF(),
         "colour_ceiling":
             QtGui.QPalette(self.btCeilingColour.palette()).color(QtGui.QPalette.Button).getRgbF(),
     }
     return settings_dict
Пример #19
0
    def compute_tangent_lines(self, bmap, wp_vertices, wp_heights):
        """
        Computes Tangent points of limb sounders aboard the aircraft

        Args:
            bmap: Projection of TopView
            wp_vertices: waypoints of the flight path
            wp_heights: altitude of the waypoints of flight path

        Returns: LineCollection of dotted lines at tangent point locations
        """
        x, y = list(zip(*wp_vertices))
        wp_lons, wp_lats = bmap(x, y, inverse=True)
        fine_lines = [
            bmap.gcpoints2(wp_lons[i],
                           wp_lats[i],
                           wp_lons[i + 1],
                           wp_lats[i + 1],
                           del_s=10.,
                           map_coords=False) for i in range(len(wp_lons) - 1)
        ]
        line_heights = [
            np.linspace(wp_heights[i],
                        wp_heights[i + 1],
                        num=len(fine_lines[i][0]))
            for i in range(len(fine_lines))
        ]
        # fine_lines = list of tuples with x-list and y-list for each segment
        tplines = [
            self.tangent_point_coordinates(
                fine_lines[i][0],
                fine_lines[i][1],
                line_heights[i],
                cut_height=self.dsbTangentHeight.value())
            for i in range(len(fine_lines))
        ]
        dirlines = self.direction_coordinates(wp_lons, wp_lats)
        lines = tplines + dirlines
        for i, line in enumerate(lines):
            for j, (lon, lat) in enumerate(line):
                line[j] = bmap(lon, lat)
            lines[i] = line
        return LineCollection(
            lines,
            colors=QtGui.QPalette(self.btTangentsColour.palette()).color(
                QtGui.QPalette.Button).getRgbF(),
            zorder=2,
            animated=True,
            linewidth=3,
            linestyles=[':'] * len(tplines) + ['-'] * len(dirlines))
Пример #20
0
class Test_MSS_SV_OptionsDialog(object):
    def setup(self):
        self.application = QtWidgets.QApplication(sys.argv)
        self.window = tv.MSS_SV_OptionsDialog()
        self.window.show()
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWaitForWindowExposed(self.window)
        QtWidgets.QApplication.processEvents()

    def teardown(self):
        self.window.hide()
        QtWidgets.QApplication.processEvents()
        self.application.quit()
        QtWidgets.QApplication.processEvents()

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_show(self, mockcrit):
        assert mockcrit.critical.call_count == 0

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_get(self, mockcrit):
        self.window.get_settings()
        assert mockcrit.critical.call_count == 0

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_addLevel(self, mockcrit):
        QtTest.QTest.mouseClick(self.window.btAdd, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert mockcrit.critical.call_count == 0

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_removeLevel(self, mockcrit):
        QtTest.QTest.mouseClick(self.window.btDelete, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert mockcrit.critical.call_count == 0

    def test_getFlightLevels(self):
        levels = self.window.get_flight_levels()
        assert all(x == y for x, y in zip(levels, [300, 320, 340]))
        QtTest.QTest.mouseClick(self.window.btAdd, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        levels = self.window.get_flight_levels()
        assert all(x == y for x, y in zip(levels, [0, 300, 320, 340]))

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QColorDialog.getColor",
                return_value=QtGui.QColor())
    def test_setColour(self, mockdlg):
        QtTest.QTest.mouseClick(self.window.btFillColour, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert mockdlg.call_count == 1
Пример #21
0
 def activate_flight_track(self, item):
     """Set the currently selected flight track to be the active one, i.e.
        the one that is displayed in the views (only one flight track can be
        displayed at a time).
     """
     self.active_flight_track = item.flighttrack_model
     for i in range(self.listViews.count()):
         view_item = self.listViews.item(i)
         view_item.window.setFlightTrackModel(self.active_flight_track)
     font = QtGui.QFont()
     for i in range(self.listFlightTracks.count()):
         self.listFlightTracks.item(i).setFont(font)
     font.setBold(True)
     item.setFont(font)
Пример #22
0
    def select_color(self):
        """
        Stores current selected file; select colour using Palette
        """
        file = self.listWidget.currentItem().text()
        button = self.dialog.pushButton_colour

        palette = QtGui.QPalette(button.palette())
        colour = palette.color(QtGui.QPalette.Button)
        colour = QtWidgets.QColorDialog.getColor(
            colour)  # opens select colour palette
        if colour.isValid():
            palette.setColor(QtGui.QPalette.Button, colour)
            button.setPalette(palette)  # finally sets the colour of the button
        self.set_attribute_color(file)
Пример #23
0
    def setColour(self, which):
        """Slot for the colour buttons: Opens a QColorDialog and sets the
           new button face colour.
        """
        if which == "water":
            button = self.btWaterColour
        elif which == "land":
            button = self.btLandColour
        elif which == "ft_vertices":
            button = self.btVerticesColour
        elif which == "ft_waypoints":
            button = self.btWaypointsColour

        palette = QtGui.QPalette(button.palette())
        colour = palette.color(QtGui.QPalette.Button)
        colour = QtWidgets.QColorDialog.getColor(colour)
        if colour.isValid():
            palette.setColor(QtGui.QPalette.Button, colour)
            button.setPalette(palette)
Пример #24
0
    def preview_change(self, current_item, previous_item):
        font = QtGui.QFont()
        if previous_item is not None:
            previous_item.setFont(font)

        if current_item is None:
            self.changePreviewTable.setModel(None)
            self.deleteVersionNameBtn.setVisible(False)
            self.toggle_version_buttons(False)
            return

        font.setBold(True)
        current_item.setFont(font)
        data = {"token": self.token, "ch_id": current_item.id}
        url = url_join(self.mscolab_server_url, 'get_change_content')
        res = requests.get(url, data=data).json()
        waypoint_model = WaypointsTableModel(xml_content=res["content"])
        self.changePreviewTable.setModel(waypoint_model)
        if current_item.version_name is not None:
            self.deleteVersionNameBtn.setVisible(True)
        else:
            self.deleteVersionNameBtn.setVisible(False)
        self.toggle_version_buttons(True)
Пример #25
0
    def setColour(self, which):
        """Slot for the colour buttons: Opens a QColorDialog and sets the
           new button face colour.
        """
        if which == "ft_fill":
            button = self.btFillColour
        elif which == "ft_vertices":
            button = self.btVerticesColour
        elif which == "ft_waypoints":
            button = self.btWaypointsColour
        elif which == "ceiling":
            button = self.btCeilingColour

        palette = QtGui.QPalette(button.palette())
        colour = palette.color(QtGui.QPalette.Button)
        colour = QtWidgets.QColorDialog.getColor(colour)
        if colour.isValid():
            if which == "ft_fill":
                # Fill colour is transparent with an alpha value of 0.15. If
                # you like to change this, modify the PathInteractor class.
                colour.setAlphaF(0.15)
            palette.setColor(QtGui.QPalette.Button, colour)
            button.setPalette(palette)
Пример #26
0
    def __init__(self, *args):
        super(MSSMainWindow, self).__init__(*args)
        self.setupUi(self)
        self.setWindowIcon(QtGui.QIcon(icons('32x32')))
        # This code is required in Windows 7 to use the icon set by setWindowIcon in taskbar
        # instead of the default Icon of python/pythonw
        try:
            import ctypes
            myappid = "mss.mss_pyui.{}".format(__version__)  # arbitrary string
            ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
        except (ImportError, AttributeError) as error:
            logging.debug("AttributeError, ImportError Exception %s", error)
        # Reference to the flight track that is currently displayed in the
        # views.
        self.active_flight_track = None
        self.last_save_directory = config_loader(dataset="data_dir", default=mss_default.data_dir)
        self.mscolab_window = None
        self.config_editor = None

        # Connect Qt SIGNALs:
        # ===================

        # File menu.
        self.actionNewFlightTrack.triggered.connect(functools.partial(self.create_new_flight_track, None, None))
        self.actionOpenFlightTrack.triggered.connect(self.open_flight_track)
        self.actionActivateSelectedFlightTrack.triggered.connect(self.activate_selected_flight_track)
        self.actionCloseSelectedFlightTrack.triggered.connect(self.close_selected_flight_track)
        self.actionSaveActiveFlightTrack.triggered.connect(self.save_flight_track)
        self.actionSaveActiveFlightTrackAs.triggered.connect(self.save_flight_track_as)

        # Views menu.
        self.actionTopView.triggered.connect(self.create_new_view)
        self.actionSideView.triggered.connect(self.create_new_view)
        self.actionTableView.triggered.connect(self.create_new_view)

        # mscolab menu
        self.actionMscolabProjects.triggered.connect(self.activate_mscolab_window)

        # Help menu.
        self.actionOnlineHelp.triggered.connect(self.show_online_help)
        self.actionAboutMSUI.triggered.connect(self.show_about_dialog)

        # Config
        self.actionConfiguration.triggered.connect(self.open_config_file)

        # Flight Tracks.
        self.listFlightTracks.itemActivated.connect(self.activate_flight_track)

        # Views.
        self.listViews.itemActivated.connect(self.activate_sub_window)

        self.add_import_filter("CSV", "csv", load_from_csv, pickertag="filepicker_flightrack")
        self.add_export_filter("CSV", "csv", save_to_csv, pickertag="filepicker_flightrack")

        self._imported_plugins, self._exported_plugins = {}, {}
        self.add_plugins()

        preload_urls = config_loader(dataset="WMS_preload", default=[])
        self.preload_wms(preload_urls)

        # Status Bar
        self.labelStatusbar.setText(self.status())
Пример #27
0
class Test_KmlOverlayDockWidget(object):
    def setup(self):
        self.application = QtWidgets.QApplication(sys.argv)
        self.view = mock.Mock()
        self.view.map = mock.Mock(side_effect=lambda x, y: (x, y))
        self.view.map.plot = mock.Mock(return_value=[mock.Mock()])

        self.window = kd.KMLOverlayControlWidget(view=self.view)
        self.window.show()
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.qWaitForWindowExposed(self.window)
        # start load test
        self.window.select_all()
        self.window.remove_file()
        QtWidgets.QApplication.processEvents()

    def teardown(self):
        QtWidgets.QApplication.processEvents()
        self.application.quit()
        QtWidgets.QApplication.processEvents()
        self.window.close()
        if os.path.exists(save_kml):
            os.remove(save_kml)

    def select_file(self, file):  # Utility function for single file
        path = fs.path.join(sample_path, "kml", file)
        filename = (path, )  # converted to tuple
        self.window.select_file(filename)
        QtWidgets.QApplication.processEvents()
        return path

    def select_files(self):  # Utility function for multiple files
        for sample in [
                "folder.kml", "line.kml", "color.kml", "style.kml",
                "features.kml"
        ]:
            path = fs.path.join(sample_path, "kml", sample)
            filename = (path, )  # converted to tuple
            self.window.select_file(filename)
            QtWidgets.QApplication.processEvents()

    @mock.patch("mslib.msui.kmloverlay_dockwidget.get_open_filenames",
                return_value=[fs.path.join(sample_path, "kml", "line.kml")])
    def test_get_file(self, mockopen):  # Tests opening of QFileDialog
        QtTest.QTest.mouseClick(self.window.btSelectFile, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert mockopen.call_count == 1

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_select_file(self, mockbox):
        """
        Test All geometries and styles are being parsed without crashing
        """
        index = 0
        assert self.window.listWidget.count() == 0
        for sample in [
                "folder.kml", "line.kml", "color.kml", "style.kml",
                "features.kml", "geometry_collection.kml",
                "Multilinestrings.kml", "polygon_inner.kml", "World_Map.kml"
        ]:
            path = self.select_file(sample)
            QtTest.QTest.qWait(250)
            assert self.window.listWidget.item(
                index).checkState() == QtCore.Qt.Checked
            index = index + 1
        assert self.window.directory_location == path
        assert mockbox.critical.call_count == 0
        assert self.window.listWidget.count() == index
        assert len(self.window.dict_files) == index
        assert self.window.patch is not None
        self.window.select_all()
        self.window.remove_file()

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    def test_select_file_error(self, mockbox):
        """
        Test that program mitigates loading a non-existing file
        """
        # load a non existing path
        self.window.select_all()
        self.window.remove_file()
        path = fs.path.join(sample_path, "satellite_tracks",
                            "satellite_predictor.txt")
        filename = (path, )  # converted to tuple
        self.window.select_file(filename)
        QtWidgets.QApplication.processEvents()
        assert mockbox.critical.call_count == 1
        self.window.listWidget.clear()
        self.window.dict_files = {}

    def test_remove_file(self):
        """
        Test removing all files except one
        """
        self.select_files()
        QtWidgets.QApplication.processEvents()
        self.window.listWidget.item(0).setCheckState(QtCore.Qt.Unchecked)
        QtTest.QTest.mouseClick(self.window.pushButton_remove,
                                QtCore.Qt.LeftButton)
        assert self.window.listWidget.count() == 1
        assert len(self.window.dict_files) == 1
        self.window.select_all()
        self.window.remove_file()

    def test_remove_all_files(self):
        """
        Test removing all files
        """
        self.select_files()
        QtWidgets.QApplication.processEvents()
        assert self.window.listWidget.count() == 5
        QtTest.QTest.mouseClick(self.window.pushButton_remove,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert self.window.listWidget.count() == 0  # No items in list
        assert self.window.dict_files == {}  # Dictionary should be empty
        assert self.window.patch is None  # Patch should be None

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QMessageBox")
    @mock.patch("mslib.msui.kmloverlay_dockwidget.get_save_filename",
                return_value=save_kml)
    def test_merge_file(self, mocksave, mockbox):
        """
        Test merging files into a single file without crashing
        """
        self.select_files()
        QtWidgets.QApplication.processEvents()
        QtTest.QTest.mouseClick(self.window.pushButton_merge,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert mocksave.call_count == 1
        assert os.path.exists(save_kml)

    @mock.patch("mslib.msui.mss_qt.QtWidgets.QColorDialog.getColor",
                return_value=QtGui.QColor())
    def test_customize_kml(self, mock_colour_dialog):
        """
        Test opening Customize KML Dialogue and checking specific file gets
        desired linewidth and colour
        """
        path = self.select_file("line.kml")  # selects file and returns path
        assert self.window.listWidget.count() == 1
        item = self.window.listWidget.item(0)
        rect = self.window.listWidget.visualItemRect(item)
        # in testing, need to add mouseclick before double click
        QtTest.QTest.mouseClick(self.window.listWidget.viewport(),
                                QtCore.Qt.LeftButton,
                                pos=rect.center())
        QtWidgets.QApplication.processEvents()
        # Double click feature
        QtTest.QTest.mouseDClick(self.window.listWidget.viewport(),
                                 QtCore.Qt.LeftButton,
                                 pos=rect.center())
        QtWidgets.QApplication.processEvents()

        # Clicking on Push Button Colour
        QtTest.QTest.mouseClick(self.window.dialog.pushButton_colour,
                                QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()
        assert mock_colour_dialog.call_count == 1

        # Testing the Double Spin Box
        self.window.dialog.dsb_linewidth.setValue(3)
        assert self.window.dialog.dsb_linewidth.value() == 3

        # clicking on OK Button
        okWidget = self.window.dialog.buttonBox.button(
            self.window.dialog.buttonBox.Ok)
        QtTest.QTest.mouseClick(okWidget, QtCore.Qt.LeftButton)
        QtWidgets.QApplication.processEvents()

        assert self.window.dict_files[path]["color"] == self.window.get_color()
        assert self.window.dict_files[path]["linewidth"] == 3

        self.window.remove_file()
        assert self.window.listWidget.count() == 0

    def test_check_uncheck(self):
        """
        Tests 'Displays plot on map when file is checked' and vice versa
        """
        self.select_file("line.kml")
        assert self.window.listWidget.item(0).checkState() == QtCore.Qt.Checked
        assert len(self.window.patch.patches) == 1
        self.window.listWidget.item(0).setCheckState(QtCore.Qt.Unchecked)
        assert self.window.listWidget.item(
            0).checkState() == QtCore.Qt.Unchecked
        assert len(self.window.patch.patches) == 0
        self.window.select_all()
        self.window.remove_file()

    # Matplotlib Plots Testing
    def test_kml_patches(self):
        """
        Tests the type of patches plotted by each Test Sample File
        """
        self.select_file("line.kml")
        assert len(
            self.window.patch.patches) == 1  # 1 LineString Geometry Patch
        self.window.remove_file()

        self.select_file("folder.kml")
        assert len(
            self.window.patch.patches) == 3  # 1 Point, 1 Polygon, 1 Text Patch
        self.window.remove_file()

        self.select_file("color.kml")
        assert len(self.window.patch.patches) == 1  # 1 Polygon Patch
        self.window.remove_file()

        self.select_file("style.kml")
        assert len(self.window.patch.patches
                   ) == 4  # 1 Point, 1 Text, 1 Polygon, 1 LineString Patch
        self.window.remove_file()

        self.select_file("features.kml")
        assert len(self.window.patch.patches
                   ) == 17  # 3 Points, 11 LineStrings, 3 Polygons Patch
        self.window.remove_file()

        self.select_file("polygon_inner.kml")
        assert len(self.window.patch.patches) == 5  # 5 Polygons Patch
        self.window.remove_file()

        self.select_file("Multilinestrings.kml")
        assert len(self.window.patch.patches) == 10  # 10 LineStrings Patch
        self.window.remove_file()

        self.select_file("geometry_collection.kml")
        assert len(
            self.window.patch.patches) == 3  # 1 Point, 1 Text, 1 Polygon Patch
        self.window.remove_file()

        self.select_file("World_Map.kml")
        assert len(self.window.patch.patches) == 292  # 292 Polygons Patch
        self.window.remove_file()
Пример #28
0
    def __init__(self, parent=None, settings_dict=None):
        """
        Arguments:
        parent -- Qt widget that is parent to this widget.
        settings_dict -- dictionary containing sideview options.
        """
        _translate = QtCore.QCoreApplication.translate
        super(MSS_SV_OptionsDialog, self).__init__(parent)
        self.setupUi(self)

        default_settings_dict = {
            "vertical_extent": (1050, 180),
            "vertical_axis": "pressure",
            "flightlevels": [300, 320, 340],
            "draw_flightlevels": True,
            "draw_flighttrack": True,
            "fill_flighttrack": True,
            "label_flighttrack": True,
            "colour_ft_vertices": (0, 0, 0, 0),
            "colour_ft_waypoints": (0, 0, 0, 0),
            "colour_ft_fill": (0, 0, 0, 0),
            "draw_ceiling": True,
            "colour_ceiling": (0.1, 0.5, 0.1, 0),
        }
        suffixes = [' hpa', ' km', ' hft']
        if settings_dict is not None:
            default_settings_dict.update(settings_dict)
        settings_dict = default_settings_dict

        self.setBotTopLimits(settings_dict["vertical_axis"])
        self.sbPbot.setValue(settings_dict["vertical_extent"][0])
        self.sbPtop.setValue(settings_dict["vertical_extent"][1])

        flightlevels = settings_dict["flightlevels"]
        self.tableWidget.setRowCount(len(flightlevels))
        flightlevels.sort()
        for i, level in enumerate(flightlevels):
            tableitem = QtWidgets.QTableWidgetItem(str(int(level)))
            self.tableWidget.setItem(i, 0, tableitem)

        for i in range(self.cbVerticalAxis.count()):
            if self.cbVerticalAxis.itemText(i) == settings_dict["vertical_axis"]:
                self.cbVerticalAxis.setCurrentIndex(i)
                self.sbPbot.setSuffix(_translate("SideViewOptionsDialog", suffixes[i]))
                self.sbPtop.setSuffix(_translate("SideViewOptionsDialog", suffixes[i]))

        self.cbDrawFlightLevels.setChecked(settings_dict["draw_flightlevels"])
        self.cbDrawFlightTrack.setChecked(settings_dict["draw_flighttrack"])
        self.cbFillFlightTrack.setChecked(settings_dict["fill_flighttrack"])
        self.cbLabelFlightTrack.setChecked(settings_dict["label_flighttrack"])
        self.cbDrawCeiling.setChecked(settings_dict["draw_ceiling"])

        for button, ids in [(self.btFillColour, "colour_ft_fill"),
                            (self.btWaypointsColour, "colour_ft_waypoints"),
                            (self.btVerticesColour, "colour_ft_vertices"),
                            (self.btCeilingColour, "colour_ceiling")]:
            palette = QtGui.QPalette(button.palette())
            colour = QtGui.QColor()
            colour.setRgbF(*settings_dict[ids])
            palette.setColor(QtGui.QPalette.Button, colour)
            button.setPalette(palette)

        # Connect colour button signals.
        self.cbVerticalAxis.view().pressed.connect(self.verticalunitsclicked)
        self.btFillColour.clicked.connect(functools.partial(self.setColour, "ft_fill"))
        self.btWaypointsColour.clicked.connect(functools.partial(self.setColour, "ft_waypoints"))
        self.btVerticesColour.clicked.connect(functools.partial(self.setColour, "ft_vertices"))
        self.btCeilingColour.clicked.connect(functools.partial(self.setColour, "ceiling"))

        self.btAdd.clicked.connect(self.addItem)
        self.btDelete.clicked.connect(self.deleteSelected)

        self.tableWidget.itemChanged.connect(self.itemChanged)
Пример #29
0
    def __init__(self, parent=None, view=None):
        super(KMLOverlayControlWidget, self).__init__(parent)
        self.setupUi(self)
        self.view = view  # canvas
        self.kml = None
        self.patch = None  # patch refers to plottings on the map
        self.dict_files = {
        }  # Dictionary of files added; key : patch , color , linewidth

        # Connect slots and signals.
        self.btSelectFile.clicked.connect(self.get_file)
        self.pushButton_remove.clicked.connect(self.remove_file)
        self.pushButton_select_all.clicked.connect(self.select_all)
        self.pushButton_unselect_all.clicked.connect(self.unselect_all)
        self.pushButton_merge.clicked.connect(self.merge_file)
        self.labelStatusBar.setText(
            "Status: Click on Add KML Files to get started.")

        self.dialog = CustomizeKMLWidget(
            self)  # create object of dialog UI Box
        self.listWidget.itemDoubleClicked.connect(
            self.open_customize_kml_dialog)
        self.dialog.pushButton_colour.clicked.connect(self.select_color)

        self.listWidget.itemChanged.connect(
            self.load_file)  # list of files in ListWidget

        self.settings_tag = "kmldock"
        settings = load_settings_qsettings(
            self.settings_tag, {
                "filename": "",
                "linewidth": 5,
                "colour": (0, 0, 0, 1),
                "saved_files": {}
            })  # initial settings

        self.directory_location = settings["filename"]
        self.dialog.dsb_linewidth.setValue(settings["linewidth"])

        # Restore previously opened files
        if settings["saved_files"] is not None:
            delete_files = []  # list to store non-existing files
            self.dict_files = settings["saved_files"]
            for file in self.dict_files:
                if os.path.isfile(file) is True:
                    self.create_list_item(file)
                else:
                    delete_files.append(file)  # add non-existent files to list
                    logging.info(file +
                                 " does not exist in the directory anymore")
            for file in delete_files:
                del self.dict_files[
                    file]  # remove non-existent files from dictionary
            self.load_file()

        palette = QtGui.QPalette(self.dialog.pushButton_colour.palette())
        colour = QtGui.QColor()
        colour.setRgbF(*settings["colour"])
        palette.setColor(QtGui.QPalette.Button, colour)
        self.dialog.pushButton_colour.setPalette(
            palette)  # sets the last colour before closing KML Overlay
        self.dialog.dsb_linewidth.valueChanged.connect(self.select_linewidth)
Пример #30
0
def main():
    try:
        prefix = os.environ["CONDA_DEFAULT_ENV"]
    except KeyError:
        prefix = ""
    app_prefix = prefix
    if prefix:
        app_prefix = "-{}".format(prefix)
    icon_hash = hashlib.md5('.'.join([__version__, app_prefix]).encode('utf-8')).hexdigest()

    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--version", help="show version", action="store_true", default=False)
    parser.add_argument("--debug", help="show debugging log messages on console", action="store_true", default=False)
    parser.add_argument("--logfile", help="Specify logfile location. Set to empty string to disable.", action="store",
                        default=os.path.join(constants.MSS_CONFIG_PATH, "mss_pyui.log"))
    parser.add_argument("-m", "--menu", help="adds mss to menu", action="store_true", default=False)
    parser.add_argument("-d", "--deinstall", help="removes mss from menu", action="store_true", default=False)

    args = parser.parse_args()

    if args.version:
        print("***********************************************************************")
        print("\n            Mission Support System (mss)\n")
        print("***********************************************************************")
        print("Documentation: http://mss.rtfd.io")
        print("Version:", __version__)
        sys.exit()

    setup_logging(args)

    if args.menu:
        # Experimental feature to get mss into application menu
        if platform.system() == "Linux":
            icon_size = '48x48'
            src_icon_path = icons(icon_size)
            icon_destination = constants.POSIX["icon_destination"].format(icon_size, icon_hash)
            dirname = os.path.dirname(icon_destination)
            if not os.path.exists(dirname):
                os.makedirs(dirname)
            shutil.copyfile(src_icon_path, icon_destination)
            desktop = constants.POSIX["desktop"]
            application_destination = constants.POSIX["application_destination"].format(app_prefix)
            dirname = os.path.dirname(application_destination)
            if not os.path.exists(dirname):
                os.makedirs(dirname)
            if prefix:
                prefix = "({})".format(prefix)
            desktop = desktop.format(prefix,
                                     os.path.join(sys.prefix, "bin", "mss"),
                                     icon_destination)
            with open(application_destination, 'w') as f:
                f.write(desktop)
            logging.info("menu entry created")
        sys.exit()
    if args.deinstall:
        application_destination = constants.POSIX["application_destination"].format(app_prefix)
        if os.path.exists(application_destination):
            os.remove(application_destination)
        icon_size = '48x48'
        icon_destination = constants.POSIX["icon_destination"].format(icon_size, icon_hash)
        if os.path.exists(icon_destination):
            os.remove(icon_destination)
        logging.info("menu entry removed")
        sys.exit()

    logging.info("MSS Version: %s", __version__)
    logging.info("Python Version: %s", sys.version)
    logging.info("Platform: %s (%s)", platform.platform(), platform.architecture())
    logging.info("Launching user interface...")

    application = QtWidgets.QApplication(sys.argv)
    application.setWindowIcon(QtGui.QIcon(icons('128x128')))
    application.setApplicationDisplayName("MSS")
    mainwindow = MSSMainWindow()
    mainwindow.create_new_flight_track()
    mainwindow.show()
    sys.exit(application.exec_())