Example #1
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)
Example #2
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"))
Example #3
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()
Example #4
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()
Example #5
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
Example #6
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)
Example #7
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)
Example #8
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()