From b6e1579c905327daa4171d1d09a152bf80c88b9a Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Fri, 2 Sep 2022 14:46:03 +0530 Subject: [PATCH 01/33] updated_multiple_flightpath_dockwidget --- mslib/msui/multiple_flightpath_dockwidget.py | 265 ++++++++---------- .../qt5/ui_multiple_flightpath_dockwidget.py | 19 +- .../ui/ui_multiple_flightpath_dockwidget.ui | 39 +-- 3 files changed, 112 insertions(+), 211 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index bdd0ddf54..ec090e7b4 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -25,15 +25,11 @@ limitations under the License. """ import logging -import os -from PyQt5 import QtWidgets, QtCore + +from PyQt5 import QtWidgets, QtGui, QtCore, Qt from mslib.msui.qt5 import ui_multiple_flightpath_dockwidget as ui -from mslib.utils.qt import get_open_filenames -from mslib.utils.config import load_settings_qsettings, save_settings_qsettings -from fs import open_fs -import mslib.msui.flighttrack as ft from mslib.msui import msui -import xml +import threading class MultipleFlightpath(object): @@ -64,6 +60,10 @@ def get_lonlat(self): lon.append(self.waypoints[i][1]) return lat, lon + def update(self): + self.remove() + self.draw() + def draw(self): lat, lon = self.get_lonlat() x, y = self.compute_xy(lon, lat) @@ -92,177 +92,132 @@ def __init__(self, parent=None, view=None, listView=None, activeFlightTrack=None self.view = view # canvas self.flight_path = None # flightpath object self.dict_files = {} # Dictionary of files added; key: patch, waypoints - self.waypoint_list = [] # List of waypoints parsed from FTML file - self.directory_location = None - self.waypoints_modelList = [] - self.active_flight_track = None - self.inactiveTrackPatches = [] + self.active_flight_track = activeFlightTrack # Connect Signals and Slots - self.bt_addFile.clicked.connect(self.get_file) - self.btRemove_file.clicked.connect(self.remove_item) - self.listView.itemChanged.connect(self.syncListViews) - self.listView.itemChanged.connect(self.drawInactiveFlighttracks) - self.listView.itemActivated.connect(self.get_active_flighttrack) + self.list_flighttrack.itemChanged.connect(self.wait2) + self.listView.model().rowsInserted.connect(self.wait) + self.listView.model().rowsRemoved.connect(self.flighttrackRemoved) + self.listView.itemActivated.connect(self.activate_flighttrack) + # Set flags + self.flag = 0 + self.flag1 = 0 + + # Load default flighttrack. + for index in range(self.listView.count()): + wp_model = self.listView.item(index).flighttrack_model + listItem = self.create_list_item(wp_model) - self.view.plot_multiple_flightpath(self) + self.save_waypoint_model_data(wp_model) - # Update Flighttrack list from MSUI list - self.syncListViews() + self.activate_flighttrack(listItem) - def syncListViews(self): - self.list_flighttrack.clear() - for index in range(self.listView.count()): - wp_model = self.listView.item(index).flighttrack_model - msui.QFlightTrackListWidgetItem(wp_model, self.list_flighttrack) + def update(self): + for entry in self.dict_files.values(): + entry["patch"].update() + + def remove(self): + for entry in self.dict_files.values(): + entry["patch"].remove() + + def wait(self, parent, start, end): + t1 = threading.Timer(1.0, self.flighttrackAdded, [parent, start, end]) + t1.start() + + def wait2(self): + t2 = threading.Timer(2.0, self.flagop) + t2.start() + + def flagop(self): + if self.flag == 1: # New flighttrack added + self.flag = 0 + elif self.flag1 == 1: # Flighttrack activated + self.flag1 = 0 + else: + self.drawInactiveFlighttracks() - def get_file(self): + def flighttrackAdded(self, parent, start, end): """ - Slot that open a file dialog to choose FTML file. + Slot to add flighttrack. """ - filenames = get_open_filenames( - self, "Open FTML File", os.path.dirname(str(self.directory_location)), "FTML Files(*.ftml)") - if not filenames: - return - self.select_file(filenames) + self.flag = 1 + wp_model = self.listView.item(start).flighttrack_model + listItem = self.create_list_item(wp_model) + self.save_waypoint_model_data(wp_model) - def select_file(self, filenames): + self.drawInactiveFlighttracks() + self.activate_flighttrack(listItem) + + def save_waypoint_model_data(self, wp_model): + lst = [] + for wp in wp_model.all_waypoint_data(): + lst.append((wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments)) + self.dict_files[wp_model]["wp_data"] = lst + + def create_list_item(self, wp_model): """ - Initializes selected file. + PyQt5 method : Add items in list and add checkbox functionality """ - for filename in filenames: - if filename is None: - return - text = filename - if text not in self.dict_files: - self.dict_files[text] = {} - self.dict_files[text]["track"] = None - self.create_list_item(filename) - else: - logging.info("%s file already added", text) - self.labelStatus.setText("Status: Files added successfully.") + self.active_flight_track = wp_model + listItem = msui.QFlightTrackListWidgetItem(wp_model, self.list_flighttrack) + listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) + listItem.setCheckState(QtCore.Qt.Unchecked) + + # Create new key in dict + self.dict_files[wp_model] = {} + self.dict_files[wp_model]["patch"] = None + self.dict_files[wp_model]["wp_data"] = [] + + return listItem - def parse_ftml(self, filename): + def flighttrackRemoved(self, parent, start, end): """ - Load a flight track from an XML file at . + Slot to remove flighttrack. """ - _dirname, _name = os.path.split(filename) - _fs = open_fs(_dirname) - datasource = _fs.open(_name) - try: - doc = xml.dom.minidom.parse(datasource) - except xml.parsers.expat.ExpatError as ex: - raise SyntaxError(str(ex)) - - ft_el = doc.getElementsByTagName("FlightTrack")[0] - - waypoints_list = [] - for wp_el in ft_el.getElementsByTagName("Waypoint"): - - location = wp_el.getAttribute("location") - lat = float(wp_el.getAttribute("lat")) - lon = float(wp_el.getAttribute("lon")) - flightlevel = float(wp_el.getAttribute("flightlevel")) - comments = wp_el.getElementsByTagName("Comments")[0] - # If num of comments is 0(null comment), then return '' - if len(comments.childNodes): - comments = comments.childNodes[0].data.strip() - else: - comments = '' - waypoints_list.append((lat, lon, flightlevel, location, comments)) - return waypoints_list + self.dict_files[self.list_flighttrack.item(start).flighttrack_model]["patch"].remove() + del self.dict_files[self.list_flighttrack.item(start).flighttrack_model] + self.list_flighttrack.takeItem(start) - def save_settings(self): + def activate_flighttrack(self, item): """ - Save Flighttrack settings after closing of view. + Activate flighttrack """ - for entry in self.dict_files.values(): - entry["track"] = None - settings = { - "saved_files": self.dict_files - } - save_settings_qsettings(self.settings_tag, settings) + if self.flag != 1: + self.flag1 = 1 + self.save_waypoint_model_data(self.active_flight_track) # Before activating new flighttrack, update waypoints of previous flighttrack + self.active_flight_track = item.flighttrack_model + + font = QtGui.QFont() + + for i in range(self.list_flighttrack.count()): + if self.dict_files[self.list_flighttrack.item(i).flighttrack_model]["patch"] is not None: + self.dict_files[self.list_flighttrack.item(i).flighttrack_model]["patch"].remove() + self.list_flighttrack.item(i).setCheckState(QtCore.Qt.Unchecked) + if self.active_flight_track == self.list_flighttrack.item(i).flighttrack_model: + font.setBold(True) + # self.list_flighttrack.item(i).setCheckState(QtCore.Qt.Unchecked) + else: + font.setBold(False) + self.list_flighttrack.item(i).setFont(font) - def load_flighttrack(self): + def drawInactiveFlighttracks(self): """ - Load Multiple Flighttracks simultaneously and construct corresponding - flight patches on topview. + Draw inactive flighttracks """ - for entry in self.dict_files.values(): # removes all patches from map, but not from dict files - if entry["track"] is not None: # since newly initialized files will have patch:None - entry["track"].remove() + for entry in self.dict_files.values(): + if entry["patch"] is not None: + entry["patch"].remove() for index in range(self.list_flighttrack.count()): if hasattr(self.list_flighttrack.item(index), "checkState") and ( self.list_flighttrack.item(index).checkState() == QtCore.Qt.Checked): - if self.list_flighttrack.item(index).text() in self.dict_files: - # if self.dict_files[self.list_flighttrack.item(index).text()]["track"] is None - # ToDO: Don't create new patch object if flighttrack patch object is Not None - self.directory_location = str(self.list_flighttrack.item(index).text()) - self.waypoint_list = self.parse_ftml(self.directory_location) - patch = MultipleFlightpath(self.view.map, self.waypoint_list) - self.dict_files[self.list_flighttrack.item(index).text()]["track"] = patch - - def get_active_flighttrack(self, item): - self.active_flight_track = item.flighttrack_model + listItem = self.list_flighttrack.item(index) + if listItem.flighttrack_model != self.active_flight_track: - def remove_item(self): - """ - Remove FTML file from list widget. - """ - flag = 0 # used to set label, if not file is selected - for index in range(self.list_flighttrack.count()): - if hasattr(self.list_flighttrack.item(index), "checkState") and \ - (self.list_flighttrack.item(index).checkState() == QtCore.Qt.Checked): # If item is checked - if self.dict_files[self.list_flighttrack.item(index).text()]['track'] is not None: - self.dict_files[self.list_flighttrack.item(index).text()]['track'].remove() - del self.dict_files[self.list_flighttrack.item(index).text()] - self.list_flighttrack.takeItem(index) - self.remove_item() - flag = 1 - self.labelStatus.setText("Status: FTML File is Removed") - if not flag: - self.labelStatus.setText("Status: Select FTML File to Delete") - - def create_list_item(self, filename): - """ - Add flighttracks to list widget - """ - wp_model = ft.WaypointsTableModel(filename=filename) - for count in range(self.listView.count()): - if str(self.listView.item(count).flighttrack_model) == str(wp_model): - break - else: - listItem = msui.QFlightTrackListWidgetItem(wp_model, self.listView) - msui.QFlightTrackListWidgetItem(wp_model, self.list_flighttrack) + patch = MultipleFlightpath(self.view.map, + self.dict_files[listItem.flighttrack_model][ + "wp_data"]) - def drawInactiveFlighttracks(self): - """ - """ - dict = {} # Dictionary of waypointTableModel objects and their waypoints - - if len(self.inactiveTrackPatches) > 0: - self.removen() - - for index in range(self.listView.count()): # Make list of all flighttrack models - item = self.listView.item(index).flighttrack_model - self.waypoints_modelList.append(item) - - for count in range(len(self.waypoints_modelList)): - waypoints_list = [] - dict[str(self.waypoints_modelList[count])] = {} - for wp in self.waypoints_modelList[count].all_waypoint_data(): - waypoints_list.append((wp.lat, wp.lon, - wp.flightlevel, wp.location, wp.comments)) - dict[str(self.waypoints_modelList[count])]["waypoints_list"] = waypoints_list - - for key in dict: # Draw inactive flighttracks - if str(key) != str(self.active_flight_track): - patch = MultipleFlightpath(self.view.map, dict[key]["waypoints_list"]) - self.inactiveTrackPatches.append(patch) - - def removen(self): - for pp in range(len(self.inactiveTrackPatches)): - if self.inactiveTrackPatches[pp] is not None: - self.inactiveTrackPatches[pp].remove() - self.inactiveTrackPatches = [] + self.dict_files[listItem.flighttrack_model]["patch"] = patch + else: + pass diff --git a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py index 6bd2de415..4d42560ab 100644 --- a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py +++ b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py @@ -13,7 +13,7 @@ class Ui_MultipleViewWidget(object): def setupUi(self, MultipleViewWidget): MultipleViewWidget.setObjectName("MultipleViewWidget") - MultipleViewWidget.resize(544, 243) + MultipleViewWidget.resize(544, 235) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -34,22 +34,7 @@ def setupUi(self, MultipleViewWidget): self.list_flighttrack.setObjectName("list_flighttrack") self.horizontalLayout_2.addWidget(self.list_flighttrack) self.horizontalLayout.addLayout(self.horizontalLayout_2) - self.verticalLayout_3 = QtWidgets.QVBoxLayout() - self.verticalLayout_3.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize) - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.bt_addFile = QtWidgets.QPushButton(MultipleViewWidget) - self.bt_addFile.setObjectName("bt_addFile") - self.verticalLayout_3.addWidget(self.bt_addFile) - self.btRemove_file = QtWidgets.QPushButton(MultipleViewWidget) - self.btRemove_file.setObjectName("btRemove_file") - self.verticalLayout_3.addWidget(self.btRemove_file) - spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) - self.verticalLayout_3.addItem(spacerItem) - self.horizontalLayout.addLayout(self.verticalLayout_3) self.verticalLayout_2.addLayout(self.horizontalLayout) - self.horizontalLayout_4 = QtWidgets.QHBoxLayout() - self.horizontalLayout_4.setObjectName("horizontalLayout_4") - self.verticalLayout_2.addLayout(self.horizontalLayout_4) self.labelStatus = QtWidgets.QLabel(MultipleViewWidget) self.labelStatus.setObjectName("labelStatus") self.verticalLayout_2.addWidget(self.labelStatus) @@ -60,6 +45,4 @@ def setupUi(self, MultipleViewWidget): def retranslateUi(self, MultipleViewWidget): _translate = QtCore.QCoreApplication.translate MultipleViewWidget.setWindowTitle(_translate("MultipleViewWidget", "Form")) - self.bt_addFile.setText(_translate("MultipleViewWidget", "Add FTML Files")) - self.btRemove_file.setText(_translate("MultipleViewWidget", "Remove Flighttrack")) self.labelStatus.setText(_translate("MultipleViewWidget", "Status: ")) diff --git a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui index 61caa6135..0e0edc6c4 100644 --- a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui +++ b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui @@ -7,7 +7,7 @@ 0 0 544 - 243 + 235 @@ -36,45 +36,8 @@ - - - - QLayout::SetMinimumSize - - - - - Add FTML Files - - - - - - - Remove Flighttrack - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - From 78bba4bcfeb84f5bd61a5d8453704de500458042 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Mon, 5 Sep 2022 18:14:09 +0530 Subject: [PATCH 02/33] set_activated_track_as_uncheckable --- mslib/msui/multiple_flightpath_dockwidget.py | 30 +++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index ec090e7b4..3942cadd7 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -24,9 +24,7 @@ See the License for the specific language governing permissions and limitations under the License. """ -import logging - -from PyQt5 import QtWidgets, QtGui, QtCore, Qt +from PyQt5 import QtWidgets, QtGui, QtCore from mslib.msui.qt5 import ui_multiple_flightpath_dockwidget as ui from mslib.msui import msui import threading @@ -37,16 +35,17 @@ class MultipleFlightpath(object): Represent a Multiple FLightpath """ - def __init__(self, mapcanvas, wp): + def __init__(self, mapcanvas, wp, linewidth=2): self.map = mapcanvas self.flightlevel = None self.comments = '' self.patches = [] self.waypoints = wp + self.linewidth = linewidth self.draw() def draw_line(self, x, y): - self.patches.append(self.map.plot(x, y, color='blue', linewidth='2')) + self.patches.append(self.map.plot(x, y, color='blue', linewidth=self.linewidth)) def compute_xy(self, lon, lat): x, y = self.map.gcpoints_path(lon, lat) @@ -60,7 +59,9 @@ def get_lonlat(self): lon.append(self.waypoints[i][1]) return lat, lon - def update(self): + def update(self, linewidth=None): + if linewidth is not None: + self.linewidth = linewidth self.remove() self.draw() @@ -190,15 +191,22 @@ def activate_flighttrack(self, item): font = QtGui.QFont() for i in range(self.list_flighttrack.count()): - if self.dict_files[self.list_flighttrack.item(i).flighttrack_model]["patch"] is not None: - self.dict_files[self.list_flighttrack.item(i).flighttrack_model]["patch"].remove() - self.list_flighttrack.item(i).setCheckState(QtCore.Qt.Unchecked) + listItem = self.list_flighttrack.item(i) if self.active_flight_track == self.list_flighttrack.item(i).flighttrack_model: font.setBold(True) - # self.list_flighttrack.item(i).setCheckState(QtCore.Qt.Unchecked) + if self.dict_files[listItem.flighttrack_model]["patch"] is not None: + self.dict_files[listItem.flighttrack_model]["patch"].remove() + listItem.setCheckState(QtCore.Qt.Unchecked) + listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: font.setBold(False) - self.list_flighttrack.item(i).setFont(font) + listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) + listItem.setFont(font) + + def set_linewidth(self): + """ + """ + pass def drawInactiveFlighttracks(self): """ From 8b8ba98c86e275dfe265d447ef89d6612ed1cc62 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:42:12 +0530 Subject: [PATCH 03/33] changed_flags_naming --- mslib/msui/multiple_flightpath_dockwidget.py | 23 ++++++++++---------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 3942cadd7..82fc8ac10 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -35,17 +35,18 @@ class MultipleFlightpath(object): Represent a Multiple FLightpath """ - def __init__(self, mapcanvas, wp, linewidth=2): + def __init__(self, mapcanvas, wp, linewidth=2, color='blue'): self.map = mapcanvas self.flightlevel = None self.comments = '' self.patches = [] self.waypoints = wp self.linewidth = linewidth + self.color = color self.draw() def draw_line(self, x, y): - self.patches.append(self.map.plot(x, y, color='blue', linewidth=self.linewidth)) + self.patches.append(self.map.plot(x, y, color=self.color, linewidth=self.linewidth)) def compute_xy(self, lon, lat): x, y = self.map.gcpoints_path(lon, lat) @@ -101,8 +102,8 @@ def __init__(self, parent=None, view=None, listView=None, activeFlightTrack=None self.listView.model().rowsRemoved.connect(self.flighttrackRemoved) self.listView.itemActivated.connect(self.activate_flighttrack) # Set flags - self.flag = 0 - self.flag1 = 0 + self.flighttrack_added = False + self.flighttrack_activated = False # Load default flighttrack. for index in range(self.listView.count()): @@ -130,10 +131,10 @@ def wait2(self): t2.start() def flagop(self): - if self.flag == 1: # New flighttrack added - self.flag = 0 - elif self.flag1 == 1: # Flighttrack activated - self.flag1 = 0 + if self.flighttrack_added: + self.flighttrack_added = False + elif self.flighttrack_activated: + self.flighttrack_activated = False else: self.drawInactiveFlighttracks() @@ -141,7 +142,7 @@ def flighttrackAdded(self, parent, start, end): """ Slot to add flighttrack. """ - self.flag = 1 + self.flighttrack_added = True wp_model = self.listView.item(start).flighttrack_model listItem = self.create_list_item(wp_model) self.save_waypoint_model_data(wp_model) @@ -183,8 +184,8 @@ def activate_flighttrack(self, item): """ Activate flighttrack """ - if self.flag != 1: - self.flag1 = 1 + if not self.flighttrack_added: + self.flighttrack_activated = True self.save_waypoint_model_data(self.active_flight_track) # Before activating new flighttrack, update waypoints of previous flighttrack self.active_flight_track = item.flighttrack_model From 74e08aeeed94aa800dc300055257c09b4f641a9a Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Mon, 5 Sep 2022 21:50:06 +0530 Subject: [PATCH 04/33] improved_list_naming --- mslib/msui/multiple_flightpath_dockwidget.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 82fc8ac10..0b4259ef8 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -151,10 +151,8 @@ def flighttrackAdded(self, parent, start, end): self.activate_flighttrack(listItem) def save_waypoint_model_data(self, wp_model): - lst = [] - for wp in wp_model.all_waypoint_data(): - lst.append((wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments)) - self.dict_files[wp_model]["wp_data"] = lst + wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] + self.dict_files[wp_model]["wp_data"] = wp_data def create_list_item(self, wp_model): """ From cf4fd848a8901f957cd156495570868be1163363 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sat, 15 Oct 2022 16:02:36 +0530 Subject: [PATCH 05/33] flickering_topview_solved --- mslib/msui/msui.py | 2 + mslib/msui/multiple_flightpath_dockwidget.py | 72 ++++++++++--------- .../qt5/ui_multiple_flightpath_dockwidget.py | 1 + mslib/msui/topview.py | 19 ++++- .../ui/ui_multiple_flightpath_dockwidget.ui | 44 ++++++++++++ mslib/utils/qt.py | 2 +- 6 files changed, 104 insertions(+), 36 deletions(-) diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index 4de5bbc68..f11ee0566 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -336,6 +336,7 @@ class MSUIMainWindow(QtWidgets.QMainWindow, ui.Ui_MSUIMainWindow): """ viewsChanged = QtCore.pyqtSignal(name="viewsChanged") + signal_activate_flighttrack = QtCore.Signal(ft.WaypointsTableModel, name="signal_activate_flighttrack") def __init__(self, mscolab_data_dir=None, *args): super(MSUIMainWindow, self).__init__(*args) @@ -705,6 +706,7 @@ def activate_flight_track(self, item): font.setBold(True) item.setFont(font) self.menu_handler() + self.signal_activate_flighttrack.emit(self.active_flight_track) def update_active_flight_track(self, old_flight_track_name=None): for i in range(self.listViews.count()): diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 0b4259ef8..e48e9f825 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -24,8 +24,10 @@ See the License for the specific language governing permissions and limitations under the License. """ +import logging from PyQt5 import QtWidgets, QtGui, QtCore from mslib.msui.qt5 import ui_multiple_flightpath_dockwidget as ui +from mslib.msui import flighttrack as ft from mslib.msui import msui import threading @@ -96,23 +98,24 @@ def __init__(self, parent=None, view=None, listView=None, activeFlightTrack=None self.dict_files = {} # Dictionary of files added; key: patch, waypoints self.active_flight_track = activeFlightTrack - # Connect Signals and Slots - self.list_flighttrack.itemChanged.connect(self.wait2) - self.listView.model().rowsInserted.connect(self.wait) - self.listView.model().rowsRemoved.connect(self.flighttrackRemoved) - self.listView.itemActivated.connect(self.activate_flighttrack) # Set flags self.flighttrack_added = False self.flighttrack_activated = False - # Load default flighttrack. + # Connect Signals and Slots + self.listView.model().rowsInserted.connect(self.wait) + self.listView.model().rowsRemoved.connect(self.flighttrackRemoved) + self.ui.signal_activate_flighttrack1.connect(self.get_active) + self.list_flighttrack.itemChanged.connect(self.flagop) + + # Load flighttracks for index in range(self.listView.count()): wp_model = self.listView.item(index).flighttrack_model listItem = self.create_list_item(wp_model) - self.save_waypoint_model_data(wp_model) + self.activate_flighttrack(self.active_flight_track) - self.activate_flighttrack(listItem) + # self.view.plot_multiple_flightpath(self) def update(self): for entry in self.dict_files.values(): @@ -123,13 +126,10 @@ def remove(self): entry["patch"].remove() def wait(self, parent, start, end): - t1 = threading.Timer(1.0, self.flighttrackAdded, [parent, start, end]) + self.flighttrack_added = True + t1 = threading.Timer(0.5, self.flighttrackAdded, [parent, start, end]) t1.start() - def wait2(self): - t2 = threading.Timer(2.0, self.flagop) - t2.start() - def flagop(self): if self.flighttrack_added: self.flighttrack_added = False @@ -142,53 +142,57 @@ def flighttrackAdded(self, parent, start, end): """ Slot to add flighttrack. """ - self.flighttrack_added = True wp_model = self.listView.item(start).flighttrack_model listItem = self.create_list_item(wp_model) - self.save_waypoint_model_data(wp_model) - - self.drawInactiveFlighttracks() self.activate_flighttrack(listItem) def save_waypoint_model_data(self, wp_model): wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] + if self.dict_files[wp_model] is None: + self.create_list_item(wp_model) self.dict_files[wp_model]["wp_data"] = wp_data def create_list_item(self, wp_model): """ PyQt5 method : Add items in list and add checkbox functionality """ - self.active_flight_track = wp_model - listItem = msui.QFlightTrackListWidgetItem(wp_model, self.list_flighttrack) - listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) - listItem.setCheckState(QtCore.Qt.Unchecked) - # Create new key in dict self.dict_files[wp_model] = {} self.dict_files[wp_model]["patch"] = None self.dict_files[wp_model]["wp_data"] = [] + self.save_waypoint_model_data(wp_model) + + listItem = msui.QFlightTrackListWidgetItem(wp_model, self.list_flighttrack) + listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) + listItem.setCheckState(QtCore.Qt.Unchecked) + return listItem def flighttrackRemoved(self, parent, start, end): """ Slot to remove flighttrack. """ + # ToDo: Add try..catch block self.dict_files[self.list_flighttrack.item(start).flighttrack_model]["patch"].remove() - del self.dict_files[self.list_flighttrack.item(start).flighttrack_model] + # del self.dict_files[self.list_flighttrack.item(start).flighttrack_model] self.list_flighttrack.takeItem(start) - def activate_flighttrack(self, item): + @QtCore.Slot(ft.WaypointsTableModel) + def get_active(self, active_flighttrack): + self.active_flight_track = active_flighttrack + self.activate_flighttrack() + + def activate_flighttrack(self, item=None): """ Activate flighttrack """ if not self.flighttrack_added: self.flighttrack_activated = True - self.save_waypoint_model_data(self.active_flight_track) # Before activating new flighttrack, update waypoints of previous flighttrack - self.active_flight_track = item.flighttrack_model + # self.save_waypoint_model_data( + # self.active_flight_track) # Before activating new flighttrack, update waypoints of previous flighttrack font = QtGui.QFont() - for i in range(self.list_flighttrack.count()): listItem = self.list_flighttrack.item(i) if self.active_flight_track == self.list_flighttrack.item(i).flighttrack_model: @@ -196,17 +200,12 @@ def activate_flighttrack(self, item): if self.dict_files[listItem.flighttrack_model]["patch"] is not None: self.dict_files[listItem.flighttrack_model]["patch"].remove() listItem.setCheckState(QtCore.Qt.Unchecked) - listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable + listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: font.setBold(False) listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) listItem.setFont(font) - def set_linewidth(self): - """ - """ - pass - def drawInactiveFlighttracks(self): """ Draw inactive flighttracks @@ -215,12 +214,17 @@ def drawInactiveFlighttracks(self): if entry["patch"] is not None: entry["patch"].remove() + for i in range(self.list_flighttrack.count()): + listItem = self.list_flighttrack.item(i) + if self.active_flight_track == self.list_flighttrack.item(i).flighttrack_model: + if self.dict_files[listItem.flighttrack_model]["patch"] is not None: + self.dict_files[listItem.flighttrack_model]["patch"].remove() + for index in range(self.list_flighttrack.count()): if hasattr(self.list_flighttrack.item(index), "checkState") and ( self.list_flighttrack.item(index).checkState() == QtCore.Qt.Checked): listItem = self.list_flighttrack.item(index) if listItem.flighttrack_model != self.active_flight_track: - patch = MultipleFlightpath(self.view.map, self.dict_files[listItem.flighttrack_model][ "wp_data"]) diff --git a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py index 4d42560ab..7a93b26dd 100644 --- a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py +++ b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py @@ -31,6 +31,7 @@ def setupUi(self, MultipleViewWidget): sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.list_flighttrack.sizePolicy().hasHeightForWidth()) self.list_flighttrack.setSizePolicy(sizePolicy) + self.list_flighttrack.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) self.list_flighttrack.setObjectName("list_flighttrack") self.horizontalLayout_2.addWidget(self.list_flighttrack) self.horizontalLayout.addLayout(self.horizontalLayout_2) diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index 6dc385a4e..d9c02b08c 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -42,6 +42,7 @@ from mslib.msui import kmloverlay_dockwidget as kml from mslib.msui import airdata_dockwidget as ad from mslib.msui import multiple_flightpath_dockwidget as mf +from mslib.msui import flighttrack as ft from mslib.msui.icons import icons from mslib.msui.flighttrack import Waypoint @@ -186,6 +187,8 @@ class MSUITopViewWindow(MSUIMplViewWindow, ui.Ui_TopViewWindow): """ name = "Top View" + signal_activate_flighttrack1 = QtCore.Signal(ft.WaypointsTableModel) + def __init__(self, parent=None, model=None, _id=None): """ Set up user interface, connect signal/slots. @@ -208,6 +211,9 @@ def __init__(self, parent=None, model=None, _id=None): # Boolean to store active wms connection self.wms_connected = False + # Store active flighttrack waypoint model + self.active_flighttrack = None + # Connect slots and signals. # ========================== @@ -224,9 +230,20 @@ def __init__(self, parent=None, model=None, _id=None): # Tool opener. self.cbTools.currentIndexChanged.connect(self.openTool) + # Update flighttrack + self.ui.signal_activate_flighttrack.connect(self.update_active_flighttrack) + def __del__(self): del self.mpl.canvas.waypoints_interactor + @QtCore.Slot(ft.WaypointsTableModel) + def update_active_flighttrack(self, active_flighttrack): + """ + Slot that handles updation of active flighttrack variable. + """ + self.active_flighttrack = active_flighttrack + self.signal_activate_flighttrack1.emit(active_flighttrack) + def setup_top_view(self): """ Initialise GUI elements. (This method is called before signals/slots @@ -297,7 +314,7 @@ def openTool(self, index): title = "Multiple Flightpath" widget = mf.MultipleFlightpathControlWidget(parent=self, view=self.mpl.canvas, listView=self.ui.listFlightTracks, - activeFlightTrack=self.ui.active_flight_track) + activeFlightTrack=self.active_flighttrack) else: raise IndexError("invalid control index") diff --git a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui index 0e0edc6c4..475b007c1 100644 --- a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui +++ b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui @@ -34,6 +34,50 @@ + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 0 + 0 + + + + Change Color + + + + + + + + 0 + 0 + + + + Qt::AlignCenter + + + + + + diff --git a/mslib/utils/qt.py b/mslib/utils/qt.py index ccfaab598..88d3c1cc1 100644 --- a/mslib/utils/qt.py +++ b/mslib/utils/qt.py @@ -372,7 +372,7 @@ class Worker(QtCore.QThread): Can be used to run a function through a QThread without much struggle, and receive the return value or exception through signals. Beware not to modify the parents connections through the function. - You may change the GUI but it may sometimes not update until the Worker is done. + You may change the GUI, but it may sometimes not update until the Worker is done. """ # Static set of all workers to avoid segfaults workers = set() From 1f2885376dd10ad7d73fa14373725389dc6d7395 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sun, 16 Oct 2022 14:40:42 +0530 Subject: [PATCH 06/33] change_color_of_selected_flightpath --- mslib/msui/multiple_flightpath_dockwidget.py | 45 +++++++++++++++---- .../qt5/ui_multiple_flightpath_dockwidget.py | 39 ++++++++++++++++ mslib/msui/topview.py | 3 +- .../ui/ui_multiple_flightpath_dockwidget.ui | 16 +++++++ 4 files changed, 93 insertions(+), 10 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index e48e9f825..8596ef1e0 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -88,13 +88,16 @@ class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidge on the TopView canvas. """ - def __init__(self, parent=None, view=None, listView=None, activeFlightTrack=None): + def __init__(self, parent=None, view=None, listView=None, + listOperationsMSC=None, activeFlightTrack=None): super(MultipleFlightpathControlWidget, self).__init__(parent) + self.listOperationsMSC = listOperationsMSC self.listView = listView self.ui = parent self.setupUi(self) self.view = view # canvas self.flight_path = None # flightpath object + self.colour = None self.dict_files = {} # Dictionary of files added; key: patch, waypoints self.active_flight_track = activeFlightTrack @@ -107,11 +110,17 @@ def __init__(self, parent=None, view=None, listView=None, activeFlightTrack=None self.listView.model().rowsRemoved.connect(self.flighttrackRemoved) self.ui.signal_activate_flighttrack1.connect(self.get_active) self.list_flighttrack.itemChanged.connect(self.flagop) + self.pushButton_color.clicked.connect(self.select_color) # Load flighttracks for index in range(self.listView.count()): wp_model = self.listView.item(index).flighttrack_model - listItem = self.create_list_item(wp_model) + listItem = self.create_list_item(wp_model, self.list_flighttrack) + + for index in range(self.listOperationsMSC.count()): + # wp_model = self.listOperationsMSC.item(index).waypoints_model + logging.info(self.listOperationsMSC.item(index).waypoint_model) + # listItem = self.create_list_item(wp_model, self.listOperationsMSC) self.activate_flighttrack(self.active_flight_track) @@ -143,32 +152,50 @@ def flighttrackAdded(self, parent, start, end): Slot to add flighttrack. """ wp_model = self.listView.item(start).flighttrack_model - listItem = self.create_list_item(wp_model) + listItem = self.create_list_item(wp_model, self.list_flighttrack) self.activate_flighttrack(listItem) - def save_waypoint_model_data(self, wp_model): + def save_waypoint_model_data(self, wp_model, listWidget): wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] if self.dict_files[wp_model] is None: - self.create_list_item(wp_model) + self.create_list_item(wp_model, self.list_flighttrack) self.dict_files[wp_model]["wp_data"] = wp_data - def create_list_item(self, wp_model): + def create_list_item(self, wp_model, listWidget): """ PyQt5 method : Add items in list and add checkbox functionality """ # Create new key in dict self.dict_files[wp_model] = {} self.dict_files[wp_model]["patch"] = None + self.dict_files[wp_model]["color"] = 'blue' self.dict_files[wp_model]["wp_data"] = [] - self.save_waypoint_model_data(wp_model) + self.save_waypoint_model_data(wp_model, listWidget) - listItem = msui.QFlightTrackListWidgetItem(wp_model, self.list_flighttrack) + listItem = msui.QFlightTrackListWidgetItem(wp_model, listWidget) listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) listItem.setCheckState(QtCore.Qt.Unchecked) return listItem + def select_color(self): + """ + Sets the color of selected flighttrack when Change Color is clicked. + """ + if self.list_flighttrack.currentItem() is not None: + if hasattr(self.list_flighttrack.currentItem(), "checkState") and ( + self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): + wp_model = self.list_flighttrack.currentItem().flighttrack_model + color = QtWidgets.QColorDialog.getColor() + if color.isValid(): + self.dict_files[wp_model]["color"] = color.getRgbF() + self.drawInactiveFlighttracks() + else: + self.labelStatus.setText("Select Flighttrack") + else: + self.labelStatus.setText("Select Flighttrack") + def flighttrackRemoved(self, parent, start, end): """ Slot to remove flighttrack. @@ -227,7 +254,7 @@ def drawInactiveFlighttracks(self): if listItem.flighttrack_model != self.active_flight_track: patch = MultipleFlightpath(self.view.map, self.dict_files[listItem.flighttrack_model][ - "wp_data"]) + "wp_data"], color=self.dict_files[listItem.flighttrack_model]['color']) self.dict_files[listItem.flighttrack_model]["patch"] = patch else: diff --git a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py index 7a93b26dd..7608236d9 100644 --- a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py +++ b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py @@ -34,6 +34,44 @@ def setupUi(self, MultipleViewWidget): self.list_flighttrack.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) self.list_flighttrack.setObjectName("list_flighttrack") self.horizontalLayout_2.addWidget(self.list_flighttrack) + self.list_operation_track = QtWidgets.QListWidget(MultipleViewWidget) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.MinimumExpanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.list_operation_track.sizePolicy().hasHeightForWidth()) + self.list_operation_track.setSizePolicy(sizePolicy) + self.list_operation_track.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents) + self.list_operation_track.setObjectName("list_operation_track") + self.horizontalLayout_2.addWidget(self.list_operation_track) + self.frame = QtWidgets.QFrame(MultipleViewWidget) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth()) + self.frame.setSizePolicy(sizePolicy) + self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame.setObjectName("frame") + self.verticalLayout = QtWidgets.QVBoxLayout(self.frame) + self.verticalLayout.setObjectName("verticalLayout") + self.pushButton_color = QtWidgets.QPushButton(self.frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.pushButton_color.sizePolicy().hasHeightForWidth()) + self.pushButton_color.setSizePolicy(sizePolicy) + self.pushButton_color.setObjectName("pushButton_color") + self.verticalLayout.addWidget(self.pushButton_color) + self.dsbx_linewidth = QtWidgets.QDoubleSpinBox(self.frame) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.dsbx_linewidth.sizePolicy().hasHeightForWidth()) + self.dsbx_linewidth.setSizePolicy(sizePolicy) + self.dsbx_linewidth.setAlignment(QtCore.Qt.AlignCenter) + self.dsbx_linewidth.setObjectName("dsbx_linewidth") + self.verticalLayout.addWidget(self.dsbx_linewidth) + self.horizontalLayout_2.addWidget(self.frame) self.horizontalLayout.addLayout(self.horizontalLayout_2) self.verticalLayout_2.addLayout(self.horizontalLayout) self.labelStatus = QtWidgets.QLabel(MultipleViewWidget) @@ -46,4 +84,5 @@ def setupUi(self, MultipleViewWidget): def retranslateUi(self, MultipleViewWidget): _translate = QtCore.QCoreApplication.translate MultipleViewWidget.setWindowTitle(_translate("MultipleViewWidget", "Form")) + self.pushButton_color.setText(_translate("MultipleViewWidget", "Change Color")) self.labelStatus.setText(_translate("MultipleViewWidget", "Status: ")) diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index d9c02b08c..6ee2eaab7 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -239,7 +239,7 @@ def __del__(self): @QtCore.Slot(ft.WaypointsTableModel) def update_active_flighttrack(self, active_flighttrack): """ - Slot that handles updation of active flighttrack variable. + Slot that handles update of active flighttrack variable. """ self.active_flighttrack = active_flighttrack self.signal_activate_flighttrack1.emit(active_flighttrack) @@ -314,6 +314,7 @@ def openTool(self, index): title = "Multiple Flightpath" widget = mf.MultipleFlightpathControlWidget(parent=self, view=self.mpl.canvas, listView=self.ui.listFlightTracks, + listOperationsMSC=self.ui.listOperationsMSC, activeFlightTrack=self.active_flighttrack) else: raise IndexError("invalid control index") diff --git a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui index 475b007c1..7ab828579 100644 --- a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui +++ b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui @@ -32,6 +32,22 @@ 0 + + QAbstractScrollArea::AdjustToContents + + + + + + + + 0 + 0 + + + + QAbstractScrollArea::AdjustToContents + From 1f414bc2a8e746bab121bfce09401e03549cbfca Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sun, 16 Oct 2022 16:37:13 +0530 Subject: [PATCH 07/33] show_color_icon --- mslib/msui/multiple_flightpath_dockwidget.py | 50 +++++++++++++++----- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 8596ef1e0..14a3e269f 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -62,9 +62,11 @@ def get_lonlat(self): lon.append(self.waypoints[i][1]) return lat, lon - def update(self, linewidth=None): + def update(self, linewidth=None, color=None): if linewidth is not None: self.linewidth = linewidth + if color is not None: + self.color = color self.remove() self.draw() @@ -104,6 +106,7 @@ def __init__(self, parent=None, view=None, listView=None, # Set flags self.flighttrack_added = False self.flighttrack_activated = False + self.color_change = None # Connect Signals and Slots self.listView.model().rowsInserted.connect(self.wait) @@ -117,10 +120,9 @@ def __init__(self, parent=None, view=None, listView=None, wp_model = self.listView.item(index).flighttrack_model listItem = self.create_list_item(wp_model, self.list_flighttrack) - for index in range(self.listOperationsMSC.count()): - # wp_model = self.listOperationsMSC.item(index).waypoints_model - logging.info(self.listOperationsMSC.item(index).waypoint_model) - # listItem = self.create_list_item(wp_model, self.listOperationsMSC) + # for index in range(self.listOperationsMSC.count()): + # wp_model = self.listOperationsMSC.item(index).waypoints_model + # listItem = self.create_list_item(wp_model, self.listOperationsMSC) self.activate_flighttrack(self.active_flight_track) @@ -144,6 +146,8 @@ def flagop(self): self.flighttrack_added = False elif self.flighttrack_activated: self.flighttrack_activated = False + elif self.color_change: + self.color_change = False else: self.drawInactiveFlighttracks() @@ -173,6 +177,8 @@ def create_list_item(self, wp_model, listWidget): self.save_waypoint_model_data(wp_model, listWidget) + if not self.flighttrack_added: + self.flighttrack_added = True listItem = msui.QFlightTrackListWidgetItem(wp_model, listWidget) listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) listItem.setCheckState(QtCore.Qt.Unchecked) @@ -184,17 +190,38 @@ def select_color(self): Sets the color of selected flighttrack when Change Color is clicked. """ if self.list_flighttrack.currentItem() is not None: - if hasattr(self.list_flighttrack.currentItem(), "checkState") and ( - self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): + if hasattr(self.list_flighttrack.currentItem(), "checkState"): wp_model = self.list_flighttrack.currentItem().flighttrack_model color = QtWidgets.QColorDialog.getColor() if color.isValid(): self.dict_files[wp_model]["color"] = color.getRgbF() - self.drawInactiveFlighttracks() + self.color_change = True + self.list_flighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) + self.dict_files[wp_model]["patch"].update(color= + self.dict_files[wp_model]["color"]) else: - self.labelStatus.setText("Select Flighttrack") + self.labelStatus.setText("Status: No flight track selected") else: - self.labelStatus.setText("Select Flighttrack") + self.labelStatus.setText("Status: No flight track selected") + + def get_color(self, wp_model): + """ + Returns color of respective flighttrack. + """ + return self.dict_files[wp_model]["color"] + + def show_color_icon(self, clr): + """ + Creating object of QPixmap for displaying icon inside the listWidget. + """ + pixmap = QtGui.QPixmap(20, 10) + pixmap.fill(QtGui.QColor(int(clr[0] * 255), int(clr[1] * 255), int(clr[2] * 255))) + return QtGui.QIcon(pixmap) + + # def select_linewidth(self): + # """ + # Change the line width of selected flighttrack. + # """ def flighttrackRemoved(self, parent, start, end): """ @@ -254,7 +281,8 @@ def drawInactiveFlighttracks(self): if listItem.flighttrack_model != self.active_flight_track: patch = MultipleFlightpath(self.view.map, self.dict_files[listItem.flighttrack_model][ - "wp_data"], color=self.dict_files[listItem.flighttrack_model]['color']) + "wp_data"], + color=self.dict_files[listItem.flighttrack_model]['color']) self.dict_files[listItem.flighttrack_model]["patch"] = patch else: From 012cc6fdd90fd763f6157d62974a87916bd22299 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Wed, 19 Oct 2022 00:14:01 +0530 Subject: [PATCH 08/33] update_previously_activated_flighttrack_wp_model_in_dict --- mslib/msui/kmloverlay_dockwidget.py | 4 +- mslib/msui/msui.py | 2 +- mslib/msui/multiple_flightpath_dockwidget.py | 87 +++++++++++-------- .../qt5/ui_multiple_flightpath_dockwidget.py | 4 + mslib/msui/topview.py | 4 +- .../ui/ui_multiple_flightpath_dockwidget.ui | 8 ++ 6 files changed, 66 insertions(+), 43 deletions(-) diff --git a/mslib/msui/kmloverlay_dockwidget.py b/mslib/msui/kmloverlay_dockwidget.py index cc82876ee..1bed38550 100644 --- a/mslib/msui/kmloverlay_dockwidget.py +++ b/mslib/msui/kmloverlay_dockwidget.py @@ -478,7 +478,7 @@ def select_file(self, filenames): return text = filename if text not in self.dict_files: # prevents same file being added twice - # initializing the nested dictionary dict_files + # initializing the nested dictionary dict_flighttrack self.dict_files[text] = {} self.dict_files[text]["patch"] = None self.dict_files[text]["color"] = (0, 0, 0, 1) @@ -536,7 +536,7 @@ def load_file(self): Loads multiple KML Files simultaneously and constructs the corresponding patches. """ - for entry in self.dict_files.values(): # removes all patches from map, but not from dict_files + for entry in self.dict_files.values(): # removes all patches from map, but not from dict_flighttrack if entry["patch"] is not None: # since newly initialized files will have patch:None entry["patch"].remove() diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index f11ee0566..41b42fdae 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -811,7 +811,7 @@ def create_view(self, _type, model): view_window = None if _type == "topview": # Top view. - view_window = topview.MSUITopViewWindow(parent=self, model=model) + view_window = topview.MSUITopViewWindow(parent=self, model=model, active_flighttrack=self.active_flight_track) view_window.mpl.resize(layout['topview'][0], layout['topview'][1]) if layout["immutable"]: view_window.mpl.setFixedSize(layout['topview'][0], layout['topview'][1]) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 14a3e269f..374c23e15 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -24,6 +24,7 @@ See the License for the specific language governing permissions and limitations under the License. """ +import copy import logging from PyQt5 import QtWidgets, QtGui, QtCore from mslib.msui.qt5 import ui_multiple_flightpath_dockwidget as ui @@ -99,8 +100,7 @@ def __init__(self, parent=None, view=None, listView=None, self.setupUi(self) self.view = view # canvas self.flight_path = None # flightpath object - self.colour = None - self.dict_files = {} # Dictionary of files added; key: patch, waypoints + self.dict_flighttrack = {} # Dictionary of flighttrack data: patch,color,wp_model self.active_flight_track = activeFlightTrack # Set flags @@ -129,11 +129,11 @@ def __init__(self, parent=None, view=None, listView=None, # self.view.plot_multiple_flightpath(self) def update(self): - for entry in self.dict_files.values(): + for entry in self.dict_flighttrack.values(): entry["patch"].update() def remove(self): - for entry in self.dict_files.values(): + for entry in self.dict_flighttrack.values(): entry["patch"].remove() def wait(self, parent, start, end): @@ -161,27 +161,29 @@ def flighttrackAdded(self, parent, start, end): def save_waypoint_model_data(self, wp_model, listWidget): wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] - if self.dict_files[wp_model] is None: - self.create_list_item(wp_model, self.list_flighttrack) - self.dict_files[wp_model]["wp_data"] = wp_data + if self.dict_flighttrack[wp_model] is None: + self.create_list_item(wp_model, listWidget) + self.dict_flighttrack[wp_model]["wp_data"] = wp_data def create_list_item(self, wp_model, listWidget): """ PyQt5 method : Add items in list and add checkbox functionality """ # Create new key in dict - self.dict_files[wp_model] = {} - self.dict_files[wp_model]["patch"] = None - self.dict_files[wp_model]["color"] = 'blue' - self.dict_files[wp_model]["wp_data"] = [] + self.dict_flighttrack[wp_model] = {} + self.dict_flighttrack[wp_model]["patch"] = None + self.dict_flighttrack[wp_model]["color"] = 'blue' + self.dict_flighttrack[wp_model]["wp_data"] = [] self.save_waypoint_model_data(wp_model, listWidget) - if not self.flighttrack_added: - self.flighttrack_added = True listItem = msui.QFlightTrackListWidgetItem(wp_model, listWidget) listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) + if not self.flighttrack_added: + self.flighttrack_added = True listItem.setCheckState(QtCore.Qt.Unchecked) + if not self.flighttrack_added: + self.flighttrack_added = True return listItem @@ -190,15 +192,16 @@ def select_color(self): Sets the color of selected flighttrack when Change Color is clicked. """ if self.list_flighttrack.currentItem() is not None: - if hasattr(self.list_flighttrack.currentItem(), "checkState"): + if hasattr(self.list_flighttrack.currentItem(), "checkState" and ( + self.list_flighttrack.currentItem.checkState() == QtCore.Qt.Checked)): wp_model = self.list_flighttrack.currentItem().flighttrack_model color = QtWidgets.QColorDialog.getColor() if color.isValid(): - self.dict_files[wp_model]["color"] = color.getRgbF() + self.dict_flighttrack[wp_model]["color"] = color.getRgbF() self.color_change = True self.list_flighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) - self.dict_files[wp_model]["patch"].update(color= - self.dict_files[wp_model]["color"]) + self.dict_flighttrack[wp_model]["patch"].update(color= + self.dict_flighttrack[wp_model]["color"]) else: self.labelStatus.setText("Status: No flight track selected") else: @@ -208,7 +211,7 @@ def get_color(self, wp_model): """ Returns color of respective flighttrack. """ - return self.dict_files[wp_model]["color"] + return self.dict_flighttrack[wp_model]["color"] def show_color_icon(self, clr): """ @@ -228,62 +231,70 @@ def flighttrackRemoved(self, parent, start, end): Slot to remove flighttrack. """ # ToDo: Add try..catch block - self.dict_files[self.list_flighttrack.item(start).flighttrack_model]["patch"].remove() - # del self.dict_files[self.list_flighttrack.item(start).flighttrack_model] + if self.dict_flighttrack[self.list_flighttrack.item(start).flighttrack_model]["patch"] is None: + del self.dict_flighttrack[self.list_flighttrack.item(start).flighttrack_model] + else: + self.dict_flighttrack[self.list_flighttrack.item(start).flighttrack_model]["patch"].remove() self.list_flighttrack.takeItem(start) @QtCore.Slot(ft.WaypointsTableModel) def get_active(self, active_flighttrack): + self.update_last_flighttrack() self.active_flight_track = active_flighttrack self.activate_flighttrack() + def update_last_flighttrack(self): + """ + Update waypoint model for last activated flighttrack in dict_flighttrack. + """ + if self.active_flight_track is not None: + self.save_waypoint_model_data( + self.active_flight_track, + self.list_flighttrack) # Before activating new flighttrack, update waypoints of previous flighttrack + def activate_flighttrack(self, item=None): """ Activate flighttrack """ - if not self.flighttrack_added: - self.flighttrack_activated = True - # self.save_waypoint_model_data( - # self.active_flight_track) # Before activating new flighttrack, update waypoints of previous flighttrack - font = QtGui.QFont() for i in range(self.list_flighttrack.count()): listItem = self.list_flighttrack.item(i) - if self.active_flight_track == self.list_flighttrack.item(i).flighttrack_model: + if self.active_flight_track == self.list_flighttrack.item(i).flighttrack_model: # active flighttrack font.setBold(True) - if self.dict_files[listItem.flighttrack_model]["patch"] is not None: - self.dict_files[listItem.flighttrack_model]["patch"].remove() + if self.dict_flighttrack[listItem.flighttrack_model]["patch"] is not None: + self.dict_flighttrack[listItem.flighttrack_model]["patch"].remove() listItem.setCheckState(QtCore.Qt.Unchecked) + self.set_activate_flag() listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: font.setBold(False) listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) + self.set_activate_flag() listItem.setFont(font) + self.set_activate_flag() def drawInactiveFlighttracks(self): """ Draw inactive flighttracks """ - for entry in self.dict_files.values(): + for entry in self.dict_flighttrack.values(): if entry["patch"] is not None: entry["patch"].remove() - for i in range(self.list_flighttrack.count()): - listItem = self.list_flighttrack.item(i) - if self.active_flight_track == self.list_flighttrack.item(i).flighttrack_model: - if self.dict_files[listItem.flighttrack_model]["patch"] is not None: - self.dict_files[listItem.flighttrack_model]["patch"].remove() - for index in range(self.list_flighttrack.count()): if hasattr(self.list_flighttrack.item(index), "checkState") and ( self.list_flighttrack.item(index).checkState() == QtCore.Qt.Checked): listItem = self.list_flighttrack.item(index) if listItem.flighttrack_model != self.active_flight_track: patch = MultipleFlightpath(self.view.map, - self.dict_files[listItem.flighttrack_model][ + self.dict_flighttrack[listItem.flighttrack_model][ "wp_data"], - color=self.dict_files[listItem.flighttrack_model]['color']) + color=self.dict_flighttrack[listItem.flighttrack_model]['color']) - self.dict_files[listItem.flighttrack_model]["patch"] = patch + self.dict_flighttrack[listItem.flighttrack_model]["patch"] = patch else: pass + + def set_activate_flag(self): + if not self.flighttrack_added: + self.flighttrack_activated = True diff --git a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py index 7608236d9..265fa6404 100644 --- a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py +++ b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py @@ -84,5 +84,9 @@ def setupUi(self, MultipleViewWidget): def retranslateUi(self, MultipleViewWidget): _translate = QtCore.QCoreApplication.translate MultipleViewWidget.setWindowTitle(_translate("MultipleViewWidget", "Form")) + self.list_flighttrack.setToolTip(_translate("MultipleViewWidget", "List of Open Flighttracks.\n" +"Check box to activate and display track on topview.")) + self.list_operation_track.setToolTip(_translate("MultipleViewWidget", "List of Mscolab Operations.\n" +"Check box to activate and display track on topview.")) self.pushButton_color.setText(_translate("MultipleViewWidget", "Change Color")) self.labelStatus.setText(_translate("MultipleViewWidget", "Status: ")) diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index 6ee2eaab7..b406bf327 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -189,7 +189,7 @@ class MSUITopViewWindow(MSUIMplViewWindow, ui.Ui_TopViewWindow): signal_activate_flighttrack1 = QtCore.Signal(ft.WaypointsTableModel) - def __init__(self, parent=None, model=None, _id=None): + def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None): """ Set up user interface, connect signal/slots. """ @@ -212,7 +212,7 @@ def __init__(self, parent=None, model=None, _id=None): self.wms_connected = False # Store active flighttrack waypoint model - self.active_flighttrack = None + self.active_flighttrack = active_flighttrack # Connect slots and signals. # ========================== diff --git a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui index 7ab828579..db7854483 100644 --- a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui +++ b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui @@ -32,6 +32,10 @@ 0 + + List of Open Flighttracks. +Check box to activate and display track on topview. + QAbstractScrollArea::AdjustToContents @@ -45,6 +49,10 @@ 0 + + List of Mscolab Operations. +Check box to activate and display track on topview. + QAbstractScrollArea::AdjustToContents From 8744701d2130515ef1f9157b49483ab4f68e06cf Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Thu, 20 Oct 2022 18:10:48 +0530 Subject: [PATCH 09/33] check_previously_activated_track --- mslib/msui/multiple_flightpath_dockwidget.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 374c23e15..f68d2505c 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -174,6 +174,7 @@ def create_list_item(self, wp_model, listWidget): self.dict_flighttrack[wp_model]["patch"] = None self.dict_flighttrack[wp_model]["color"] = 'blue' self.dict_flighttrack[wp_model]["wp_data"] = [] + self.dict_flighttrack[wp_model]["checkState"] = False self.save_waypoint_model_data(wp_model, listWidget) @@ -192,8 +193,8 @@ def select_color(self): Sets the color of selected flighttrack when Change Color is clicked. """ if self.list_flighttrack.currentItem() is not None: - if hasattr(self.list_flighttrack.currentItem(), "checkState" and ( - self.list_flighttrack.currentItem.checkState() == QtCore.Qt.Checked)): + if (hasattr(self.list_flighttrack.currentItem(), "checkState")) and ( + self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): wp_model = self.list_flighttrack.currentItem().flighttrack_model color = QtWidgets.QColorDialog.getColor() if color.isValid(): @@ -259,19 +260,20 @@ def activate_flighttrack(self, item=None): font = QtGui.QFont() for i in range(self.list_flighttrack.count()): listItem = self.list_flighttrack.item(i) - if self.active_flight_track == self.list_flighttrack.item(i).flighttrack_model: # active flighttrack + if self.active_flight_track == listItem.flighttrack_model: # active flighttrack font.setBold(True) if self.dict_flighttrack[listItem.flighttrack_model]["patch"] is not None: self.dict_flighttrack[listItem.flighttrack_model]["patch"].remove() - listItem.setCheckState(QtCore.Qt.Unchecked) + listItem.setCheckState(QtCore.Qt.Checked) self.set_activate_flag() listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: font.setBold(False) listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) + if self.dict_flighttrack[listItem.flighttrack_model]["checkState"]: + listItem.setCheckState(QtCore.Qt.Checked) self.set_activate_flag() listItem.setFont(font) - self.set_activate_flag() def drawInactiveFlighttracks(self): """ @@ -282,9 +284,9 @@ def drawInactiveFlighttracks(self): entry["patch"].remove() for index in range(self.list_flighttrack.count()): + listItem = self.list_flighttrack.item(index) if hasattr(self.list_flighttrack.item(index), "checkState") and ( self.list_flighttrack.item(index).checkState() == QtCore.Qt.Checked): - listItem = self.list_flighttrack.item(index) if listItem.flighttrack_model != self.active_flight_track: patch = MultipleFlightpath(self.view.map, self.dict_flighttrack[listItem.flighttrack_model][ @@ -292,8 +294,10 @@ def drawInactiveFlighttracks(self): color=self.dict_flighttrack[listItem.flighttrack_model]['color']) self.dict_flighttrack[listItem.flighttrack_model]["patch"] = patch + self.dict_flighttrack[listItem.flighttrack_model]["checkState"] = True else: - pass + # pass + self.dict_flighttrack[listItem.flighttrack_model]["checkState"] = False def set_activate_flag(self): if not self.flighttrack_added: From dc675fb96767f739774f967bffa63f43bc559944 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sat, 22 Oct 2022 09:50:39 +0530 Subject: [PATCH 10/33] change_linewidth --- mslib/msui/msui.py | 3 +- mslib/msui/multiple_flightpath_dockwidget.py | 36 +++++++++++++++----- 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index 41b42fdae..2ad48267f 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -740,7 +740,8 @@ def save_handler(self): self.save_as_handler() def save_as_handler(self): - """Slot for the 'Save Active Flight Track As' menu entry. + """ + Slot for the 'Save Active Flight Track As' menu entry. """ default_filename = os.path.join(self.last_save_directory, self.active_flight_track.name + ".ftml") file_type = ["Flight track (*.ftml)"] diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index f68d2505c..2daa54a71 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -24,8 +24,6 @@ See the License for the specific language governing permissions and limitations under the License. """ -import copy -import logging from PyQt5 import QtWidgets, QtGui, QtCore from mslib.msui.qt5 import ui_multiple_flightpath_dockwidget as ui from mslib.msui import flighttrack as ft @@ -106,14 +104,18 @@ def __init__(self, parent=None, view=None, listView=None, # Set flags self.flighttrack_added = False self.flighttrack_activated = False - self.color_change = None + self.color_change = False + self.change_linewidth = False + self.dsbx_linewidth.setValue(2.0) # Connect Signals and Slots self.listView.model().rowsInserted.connect(self.wait) self.listView.model().rowsRemoved.connect(self.flighttrackRemoved) self.ui.signal_activate_flighttrack1.connect(self.get_active) self.list_flighttrack.itemChanged.connect(self.flagop) + self.pushButton_color.clicked.connect(self.select_color) + self.dsbx_linewidth.valueChanged.connect(self.set_linewidth) # Load flighttracks for index in range(self.listView.count()): @@ -172,7 +174,8 @@ def create_list_item(self, wp_model, listWidget): # Create new key in dict self.dict_flighttrack[wp_model] = {} self.dict_flighttrack[wp_model]["patch"] = None - self.dict_flighttrack[wp_model]["color"] = 'blue' + self.dict_flighttrack[wp_model]["color"] = None + self.dict_flighttrack[wp_model]["linewidth"] = 2 self.dict_flighttrack[wp_model]["wp_data"] = [] self.dict_flighttrack[wp_model]["checkState"] = False @@ -222,10 +225,27 @@ def show_color_icon(self, clr): pixmap.fill(QtGui.QColor(int(clr[0] * 255), int(clr[1] * 255), int(clr[2] * 255))) return QtGui.QIcon(pixmap) - # def select_linewidth(self): - # """ - # Change the line width of selected flighttrack. - # """ + def set_linewidth(self): + """ + Change the line width of selected flighttrack. + """ + if self.list_flighttrack.currentItem() is not None: + if (hasattr(self.list_flighttrack.currentItem(), "checkState")) and ( + self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): + wp_model = self.list_flighttrack.currentItem().flighttrack_model + if self.dict_flighttrack[wp_model]["linewidth"] != self.dsbx_linewidth.value(): + self.dict_flighttrack[wp_model]["linewidth"] = self.dsbx_linewidth.value() + + self.dict_flighttrack[wp_model]["patch"].remove() + self.dict_flighttrack[wp_model]["patch"].update( + self.dict_flighttrack[wp_model]["linewidth"], self.dict_flighttrack[wp_model]["color"] + ) + self.change_linewidth = True + self.dsbx_linewidth.setValue(self.dict_flighttrack[wp_model]["linewidth"]) + else: + self.labelStatus.setText("Status: No flight track selected") + else: + self.labelStatus.setText("Status: No flight track selected") def flighttrackRemoved(self, parent, start, end): """ From 4d91dc972f08fc4eaa3e05d0529cafe2b22246fb Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Fri, 28 Oct 2022 18:24:56 +0530 Subject: [PATCH 11/33] plot_operations_topview --- mslib/msui/mscolab.py | 4 + mslib/msui/msui.py | 12 +- mslib/msui/multiple_flightpath_dockwidget.py | 209 +++++++++++++++++-- mslib/msui/topview.py | 15 +- 4 files changed, 220 insertions(+), 20 deletions(-) diff --git a/mslib/msui/mscolab.py b/mslib/msui/mscolab.py index 7f0585d37..339d6a912 100644 --- a/mslib/msui/mscolab.py +++ b/mslib/msui/mscolab.py @@ -414,6 +414,8 @@ class MSUIMscolab(QtCore.QObject): """ name = "Mscolab" + signal_activate_operation = QtCore.Signal(int, name="signal_activate_operation") + def __init__(self, parent=None, data_dir=None): super(MSUIMscolab, self).__init__(parent) self.ui = parent @@ -1526,6 +1528,8 @@ def set_active_op_id(self, item): self.active_operation_desc = item.active_operation_desc self.waypoints_model = None + self.signal_activate_operation.emit(self.active_op_id) + self.inactive_op_id = None font = QtGui.QFont() for i in range(self.ui.listOperationsMSC.count()): diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index 2ad48267f..5cff67f4e 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -337,6 +337,7 @@ class MSUIMainWindow(QtWidgets.QMainWindow, ui.Ui_MSUIMainWindow): viewsChanged = QtCore.pyqtSignal(name="viewsChanged") signal_activate_flighttrack = QtCore.Signal(ft.WaypointsTableModel, name="signal_activate_flighttrack") + signal_activate_operation = QtCore.Signal(int, name="signal_activate_operation") def __init__(self, mscolab_data_dir=None, *args): super(MSUIMainWindow, self).__init__(*args) @@ -427,6 +428,8 @@ def __init__(self, mscolab_data_dir=None, *args): self.listFlightTracks.itemClicked.connect(lambda: self.listOperationsMSC.setCurrentItem(None)) self.listOperationsMSC.itemClicked.connect(lambda: self.listFlightTracks.setCurrentItem(None)) + self.mscolab.signal_activate_operation.connect(self.ss) + # Don't start the updater during a test run of msui if "pytest" not in sys.modules: self.updater = UpdaterUI(self) @@ -491,6 +494,10 @@ def add_plugins(self): self.add_import_plugins(picker_default) self.add_export_plugins(picker_default) + @QtCore.Slot(int) + def ss(self, active_op_id): + self.signal_activate_operation.emit(active_op_id) + def add_plugin_submenu(self, name, extension, function, pickertype, plugin_type="Import"): if plugin_type == "Import": menu = self.menuImportFlightTrack @@ -812,7 +819,10 @@ def create_view(self, _type, model): view_window = None if _type == "topview": # Top view. - view_window = topview.MSUITopViewWindow(parent=self, model=model, active_flighttrack=self.active_flight_track) + view_window = topview.MSUITopViewWindow(parent=self, model=model, + active_flighttrack=self.active_flight_track, + mscolab_server_url=self.mscolab.mscolab_server_url, + token=self.mscolab.token) view_window.mpl.resize(layout['topview'][0], layout['topview'][1]) if layout["immutable"]: view_window.mpl.setFixedSize(layout['topview'][0], layout['topview'][1]) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 2daa54a71..b2771abd8 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -28,7 +28,10 @@ from mslib.msui.qt5 import ui_multiple_flightpath_dockwidget as ui from mslib.msui import flighttrack as ft from mslib.msui import msui +from mslib.utils.verify_user_token import verify_user_token import threading +import requests +import json class MultipleFlightpath(object): @@ -83,6 +86,17 @@ def remove(self): self.map.ax.figure.canvas.draw() +class QMscolabOperationsListWidgetItem(QtWidgets.QListWidgetItem): + def __init__(self, flighttrack_model, op_id: int, parent=None, type=QtWidgets.QListWidgetItem.UserType): + view_name = flighttrack_model.name + super(QMscolabOperationsListWidgetItem, self).__init__( + view_name, parent, type + ) + self.parent = parent + self.flighttrack_model = flighttrack_model + self.op_id = op_id + + class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidget): """ This class provides the interface for plotting Multiple Flighttracks @@ -90,7 +104,7 @@ class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidge """ def __init__(self, parent=None, view=None, listView=None, - listOperationsMSC=None, activeFlightTrack=None): + listOperationsMSC=None, activeFlightTrack=None, mscolab_server_url=None, token=None): super(MultipleFlightpathControlWidget, self).__init__(parent) self.listOperationsMSC = listOperationsMSC self.listView = listView @@ -114,6 +128,8 @@ def __init__(self, parent=None, view=None, listView=None, self.ui.signal_activate_flighttrack1.connect(self.get_active) self.list_flighttrack.itemChanged.connect(self.flagop) + # self.get_wps_from_server() + self.pushButton_color.clicked.connect(self.select_color) self.dsbx_linewidth.valueChanged.connect(self.set_linewidth) @@ -122,11 +138,14 @@ def __init__(self, parent=None, view=None, listView=None, wp_model = self.listView.item(index).flighttrack_model listItem = self.create_list_item(wp_model, self.list_flighttrack) - # for index in range(self.listOperationsMSC.count()): - # wp_model = self.listOperationsMSC.item(index).waypoints_model - # listItem = self.create_list_item(wp_model, self.listOperationsMSC) + if mscolab_server_url is not None: + self.operations = MultipleFlightpathOperations(mscolab_server_url, token, self.list_operation_track, self.view) - self.activate_flighttrack(self.active_flight_track) + # Signal emitted, on activation of operation from MSUI + self.ui.signal_activate_operation.connect(self.ss) + self.list_operation_track.itemChanged.connect(self.wait2) + + self.activate_flighttrack() # self.view.plot_multiple_flightpath(self) @@ -151,7 +170,7 @@ def flagop(self): elif self.color_change: self.color_change = False else: - self.drawInactiveFlighttracks() + self.drawInactiveFlighttracks(self.list_flighttrack) def flighttrackAdded(self, parent, start, end): """ @@ -159,7 +178,7 @@ def flighttrackAdded(self, parent, start, end): """ wp_model = self.listView.item(start).flighttrack_model listItem = self.create_list_item(wp_model, self.list_flighttrack) - self.activate_flighttrack(listItem) + self.activate_flighttrack() def save_waypoint_model_data(self, wp_model, listWidget): wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] @@ -273,7 +292,7 @@ def update_last_flighttrack(self): self.active_flight_track, self.list_flighttrack) # Before activating new flighttrack, update waypoints of previous flighttrack - def activate_flighttrack(self, item=None): + def activate_flighttrack(self): """ Activate flighttrack """ @@ -284,18 +303,19 @@ def activate_flighttrack(self, item=None): font.setBold(True) if self.dict_flighttrack[listItem.flighttrack_model]["patch"] is not None: self.dict_flighttrack[listItem.flighttrack_model]["patch"].remove() - listItem.setCheckState(QtCore.Qt.Checked) - self.set_activate_flag() + if listItem.checkState() == QtCore.Qt.Unchecked: + listItem.setCheckState(QtCore.Qt.Checked) + self.set_activate_flag() listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: font.setBold(False) listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) - if self.dict_flighttrack[listItem.flighttrack_model]["checkState"]: - listItem.setCheckState(QtCore.Qt.Checked) + # if self.dict_flighttrack[listItem.flighttrack_model]["checkState"]: + # listItem.setCheckState(QtCore.Qt.Checked) self.set_activate_flag() listItem.setFont(font) - def drawInactiveFlighttracks(self): + def drawInactiveFlighttracks(self, list_widget): """ Draw inactive flighttracks """ @@ -303,10 +323,10 @@ def drawInactiveFlighttracks(self): if entry["patch"] is not None: entry["patch"].remove() - for index in range(self.list_flighttrack.count()): - listItem = self.list_flighttrack.item(index) - if hasattr(self.list_flighttrack.item(index), "checkState") and ( - self.list_flighttrack.item(index).checkState() == QtCore.Qt.Checked): + for index in range(list_widget.count()): + listItem = list_widget.item(index) + if hasattr(list_widget.item(index), "checkState") and ( + list_widget.item(index).checkState() == QtCore.Qt.Checked): if listItem.flighttrack_model != self.active_flight_track: patch = MultipleFlightpath(self.view.map, self.dict_flighttrack[listItem.flighttrack_model][ @@ -319,6 +339,161 @@ def drawInactiveFlighttracks(self): # pass self.dict_flighttrack[listItem.flighttrack_model]["checkState"] = False + def wait2(self): + t2 = threading.Timer(2, self.operations.draw_inactive_operations) + t2.start() + def set_activate_flag(self): if not self.flighttrack_added: self.flighttrack_activated = True + + @QtCore.Slot(int) + def ss(self, op_id): + self.operations.get_op_id(op_id) + + +class MultipleFlightpathOperations: + """ + This class provides the functions for plotting Multiple Flighttracks from mscolab server + on the TopView canvas. + """ + + def __init__(self, mscolab_server_url, token, list_operation_track, view): + # Variables related to Mscolab Operations + self.active_op_id = None + self.mscolab_server_url = mscolab_server_url + self.token = token + self.dict_operations = {} + self.list_operation_track = list_operation_track + self.active_flight_track = None + self.view = view + + # Connect signals and slots + # # + + # Load operations from wps server + server_operations = self.get_wps_from_server() + + for operations in server_operations: + op_id = operations["op_id"] + xml_content = self.request_wps_from_server(op_id) + wp_model = ft.WaypointsTableModel(xml_content=xml_content) + wp_model.name = operations["path"] + self.create_operation(wp_model, op_id) + + def get_wps_from_server(self): + operations = {} + data = { + "token": self.token + } + r = requests.get(self.mscolab_server_url + "/operations", data=data) + if r.text != "False": + _json = json.loads(r.text) + operations = _json["operations"] + return operations + + def request_wps_from_server(self, op_id): + if verify_user_token(self.mscolab_server_url, self.token): + data = { + "token": self.token, + "op_id": op_id + } + r = requests.get(self.mscolab_server_url + '/get_operation_by_id', data=data) + if r.text != "False": + xml_content = json.loads(r.text)["content"] + return xml_content + + def load_wps_from_server(self, op_id): + xml_content = self.request_wps_from_server(op_id) + if xml_content is not None: + waypoints_model = ft.WaypointsTableModel(xml_content=xml_content) + return waypoints_model + + def save_operation_data(self, wp_model, op_id): + wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] + if self.dict_operations[wp_model] is None: + self.create_operation(wp_model, op_id) + self.dict_operations[wp_model]["wp_data"] = wp_data + self.dict_operations[wp_model]["op_id"] = op_id + + def create_operation(self, wp_model, op_id): + """ + """ + self.dict_operations[wp_model] = {} + self.dict_operations[wp_model]["patch"] = None + self.dict_operations[wp_model]["op_id"] = None + # self.sav + + self.save_operation_data(wp_model, op_id) + + listItem = QMscolabOperationsListWidgetItem(wp_model, op_id, self.list_operation_track) + listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) + listItem.setCheckState(QtCore.Qt.Unchecked) + + return listItem + + def activate_operation(self): + """ + Activate Mscolab Operation + """ + font = QtGui.QFont() + for i in range(self.list_operation_track.count()): + listItem = self.list_operation_track.item(i) + if self.active_op_id == listItem.op_id: # active operation + font.setBold(True) + if self.dict_operations[listItem.flighttrack_model]["patch"] is not None: + self.dict_operations[listItem.flighttrack_model]["patch"].remove() + if listItem.checkState() == QtCore.Qt.Unchecked: + listItem.setCheckState(QtCore.Qt.Checked) + # self.set_activate_flag() + listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable + else: + font.setBold(False) + listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) + # self.set_activate_flag() + listItem.setFont(font) + + def draw_inactive_operations(self): + """ + Draw flighttracks of inactive operations. + """ + for entry in self.dict_operations.values(): + if entry is not None: + if entry["patch"] is not None: + entry["patch"].remove() + + for index in range(self.list_operation_track.count()): + listItem = self.list_operation_track.item(index) + if hasattr(listItem, "checkState") and ( + listItem.checkState() == QtCore.Qt.Unchecked): + if listItem.flighttrack_model != self.active_flight_track: + patch = MultipleFlightpath(self.view.map, + self.dict_operations[listItem.flighttrack_model][ + "wp_data"]) + + self.dict_operations[listItem.flighttrack_model]["patch"] = patch + # self.dict_operations[listItem.flighttrack_model]["checkState"] = True + else: + pass + # self.dict_operations[listItem.flighttrack_model]["checkState"] = False + + def get_op_id(self, op_id): + self.active_op_id = op_id + + def operationsAdded(self, parent, start, end): + """ + Slot to add operation. + """ + wp_model = self.list_operation_track.item(start).flighttrack_model + listItem = self.create_operation(wp_model, self.list_operation_track) + self.activate_operation() + + def operationRemoved(self, parent, start, end): + """ + Slot to remove operation. + """ + if self.dict_operations[self.list_operation_track.item(start).flighttrack_model]["patch"] is None: + del self.dict_operations[self.list_operation_track.item(start).flighttrack_model] + else: + self.dict_operations[self.list_operation_track.item(start).flighttrack_model]["patch"].remove() + self.list_operation_track.takeItem(start) diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index b406bf327..09b737687 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -188,8 +188,10 @@ class MSUITopViewWindow(MSUIMplViewWindow, ui.Ui_TopViewWindow): name = "Top View" signal_activate_flighttrack1 = QtCore.Signal(ft.WaypointsTableModel) + signal_activate_operation = QtCore.Signal(int) - def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None): + def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, mscolab_server_url=None + , token=None): """ Set up user interface, connect signal/slots. """ @@ -213,6 +215,8 @@ def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None): # Store active flighttrack waypoint model self.active_flighttrack = active_flighttrack + self.mscolab_server_url = mscolab_server_url + self.token = token # Connect slots and signals. # ========================== @@ -232,6 +236,7 @@ def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None): # Update flighttrack self.ui.signal_activate_flighttrack.connect(self.update_active_flighttrack) + self.ui.signal_activate_operation.connect(self.update_active_operation) def __del__(self): del self.mpl.canvas.waypoints_interactor @@ -244,6 +249,10 @@ def update_active_flighttrack(self, active_flighttrack): self.active_flighttrack = active_flighttrack self.signal_activate_flighttrack1.emit(active_flighttrack) + @QtCore.Slot(int) + def update_active_operation(self, active_op_id): + self.signal_activate_operation.emit(active_op_id) + def setup_top_view(self): """ Initialise GUI elements. (This method is called before signals/slots @@ -315,7 +324,9 @@ def openTool(self, index): widget = mf.MultipleFlightpathControlWidget(parent=self, view=self.mpl.canvas, listView=self.ui.listFlightTracks, listOperationsMSC=self.ui.listOperationsMSC, - activeFlightTrack=self.active_flighttrack) + activeFlightTrack=self.active_flighttrack, + mscolab_server_url=self.mscolab_server_url, + token=self.token) else: raise IndexError("invalid control index") From 947f2b4d128dd762725c530e1b376d459588a65f Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Mon, 31 Oct 2022 20:02:00 +0530 Subject: [PATCH 12/33] bug_fixes --- mslib/msui/multiple_flightpath_dockwidget.py | 76 +++++++++++++------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index b2771abd8..a4e5f742a 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -34,6 +34,19 @@ import json +class QMscolabOperationsListWidgetItem(QtWidgets.QListWidgetItem): + """ + """ + def __init__(self, flighttrack_model, op_id: int, parent=None, type=QtWidgets.QListWidgetItem.UserType): + view_name = flighttrack_model.name + super(QMscolabOperationsListWidgetItem, self).__init__( + view_name, parent, type + ) + self.parent = parent + self.flighttrack_model = flighttrack_model + self.op_id = op_id + + class MultipleFlightpath(object): """ Represent a Multiple FLightpath @@ -86,17 +99,6 @@ def remove(self): self.map.ax.figure.canvas.draw() -class QMscolabOperationsListWidgetItem(QtWidgets.QListWidgetItem): - def __init__(self, flighttrack_model, op_id: int, parent=None, type=QtWidgets.QListWidgetItem.UserType): - view_name = flighttrack_model.name - super(QMscolabOperationsListWidgetItem, self).__init__( - view_name, parent, type - ) - self.parent = parent - self.flighttrack_model = flighttrack_model - self.op_id = op_id - - class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidget): """ This class provides the interface for plotting Multiple Flighttracks @@ -139,11 +141,11 @@ def __init__(self, parent=None, view=None, listView=None, listItem = self.create_list_item(wp_model, self.list_flighttrack) if mscolab_server_url is not None: - self.operations = MultipleFlightpathOperations(mscolab_server_url, token, self.list_operation_track, self.view) + self.operations = MultipleFlightpathOperations(mscolab_server_url, token, self.list_operation_track, + self.listOperationsMSC, self.view) # Signal emitted, on activation of operation from MSUI - self.ui.signal_activate_operation.connect(self.ss) - self.list_operation_track.itemChanged.connect(self.wait2) + self.ui.signal_activate_operation.connect(self.update_op_id) self.activate_flighttrack() @@ -339,16 +341,12 @@ def drawInactiveFlighttracks(self, list_widget): # pass self.dict_flighttrack[listItem.flighttrack_model]["checkState"] = False - def wait2(self): - t2 = threading.Timer(2, self.operations.draw_inactive_operations) - t2.start() - def set_activate_flag(self): if not self.flighttrack_added: self.flighttrack_activated = True @QtCore.Slot(int) - def ss(self, op_id): + def update_op_id(self, op_id): self.operations.get_op_id(op_id) @@ -358,18 +356,25 @@ class MultipleFlightpathOperations: on the TopView canvas. """ - def __init__(self, mscolab_server_url, token, list_operation_track, view): + def __init__(self, mscolab_server_url, token, list_operation_track, listOperationsMSC, view): # Variables related to Mscolab Operations self.active_op_id = None self.mscolab_server_url = mscolab_server_url self.token = token self.dict_operations = {} self.list_operation_track = list_operation_track + self.listOperationsMSC = listOperationsMSC self.active_flight_track = None self.view = view + self.operation_added = False + self.operation_removed = False + self.operation_activated = False + # Connect signals and slots - # # + self.list_operation_track.itemChanged.connect(self.set_flag) + self.listOperationsMSC.model().rowsInserted.connect(self.wait2) + self.listOperationsMSC.model().rowsRemoved.connect(self.operationRemoved) # Load operations from wps server server_operations = self.get_wps_from_server() @@ -381,6 +386,14 @@ def __init__(self, mscolab_server_url, token, list_operation_track, view): wp_model.name = operations["path"] self.create_operation(wp_model, op_id) + def set_flag(self): + if self.operation_added: + self.operation_added = False + elif self.operation_removed: + self.operation_removed = False + else: + self.draw_inactive_operations() + def get_wps_from_server(self): operations = {} data = { @@ -428,7 +441,12 @@ def create_operation(self, wp_model, op_id): listItem = QMscolabOperationsListWidgetItem(wp_model, op_id, self.list_operation_track) listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) + + if not self.operation_added: + self.operation_added = True listItem.setCheckState(QtCore.Qt.Unchecked) + if not self.operation_added: + self.operation_added = True return listItem @@ -445,12 +463,12 @@ def activate_operation(self): self.dict_operations[listItem.flighttrack_model]["patch"].remove() if listItem.checkState() == QtCore.Qt.Unchecked: listItem.setCheckState(QtCore.Qt.Checked) - # self.set_activate_flag() + self.set_activate_flag() listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: font.setBold(False) listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) - # self.set_activate_flag() + self.set_activate_flag() listItem.setFont(font) def draw_inactive_operations(self): @@ -465,7 +483,7 @@ def draw_inactive_operations(self): for index in range(self.list_operation_track.count()): listItem = self.list_operation_track.item(index) if hasattr(listItem, "checkState") and ( - listItem.checkState() == QtCore.Qt.Unchecked): + listItem.checkState() == QtCore.Qt.Checked): if listItem.flighttrack_model != self.active_flight_track: patch = MultipleFlightpath(self.view.map, self.dict_operations[listItem.flighttrack_model][ @@ -480,6 +498,11 @@ def draw_inactive_operations(self): def get_op_id(self, op_id): self.active_op_id = op_id + def wait2(self, parent, start, end): + self.operation_added = True + t2 = threading.Timer(0.5, self.operationsAdded, [parent, start, end]) + t2.start() + def operationsAdded(self, parent, start, end): """ Slot to add operation. @@ -492,8 +515,13 @@ def operationRemoved(self, parent, start, end): """ Slot to remove operation. """ + self.operation_removed = True if self.dict_operations[self.list_operation_track.item(start).flighttrack_model]["patch"] is None: del self.dict_operations[self.list_operation_track.item(start).flighttrack_model] else: self.dict_operations[self.list_operation_track.item(start).flighttrack_model]["patch"].remove() self.list_operation_track.takeItem(start) + + def set_activate_flag(self): + if not self.operation_activated: + self.operation_activated = True From 4e16c3704cdc84168c88af96bacf0804ee9f58d6 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Tue, 1 Nov 2022 10:46:13 +0530 Subject: [PATCH 13/33] checkmark_protection_behaviour_updated --- mslib/msui/msui.py | 4 +- mslib/msui/multiple_flightpath_dockwidget.py | 73 ++++++++++++++++---- mslib/msui/topview.py | 9 ++- 3 files changed, 69 insertions(+), 17 deletions(-) diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index 5cff67f4e..66f8d41cd 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -428,7 +428,7 @@ def __init__(self, mscolab_data_dir=None, *args): self.listFlightTracks.itemClicked.connect(lambda: self.listOperationsMSC.setCurrentItem(None)) self.listOperationsMSC.itemClicked.connect(lambda: self.listFlightTracks.setCurrentItem(None)) - self.mscolab.signal_activate_operation.connect(self.ss) + self.mscolab.signal_activate_operation.connect(self.activate_operation_slot) # Don't start the updater during a test run of msui if "pytest" not in sys.modules: @@ -495,7 +495,7 @@ def add_plugins(self): self.add_export_plugins(picker_default) @QtCore.Slot(int) - def ss(self, active_op_id): + def activate_operation_slot(self, active_op_id): self.signal_activate_operation.emit(active_op_id) def add_plugin_submenu(self, name, extension, function, pickertype, plugin_type="Import"): diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index a4e5f742a..e6bbdd416 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -105,17 +105,17 @@ class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidge on the TopView canvas. """ - def __init__(self, parent=None, view=None, listView=None, + def __init__(self, parent=None, view=None, listFlightTracks=None, listOperationsMSC=None, activeFlightTrack=None, mscolab_server_url=None, token=None): super(MultipleFlightpathControlWidget, self).__init__(parent) - self.listOperationsMSC = listOperationsMSC - self.listView = listView self.ui = parent self.setupUi(self) self.view = view # canvas self.flight_path = None # flightpath object self.dict_flighttrack = {} # Dictionary of flighttrack data: patch,color,wp_model self.active_flight_track = activeFlightTrack + self.listOperationsMSC = listOperationsMSC + self.listFlightTracks = listFlightTracks # Set flags self.flighttrack_added = False @@ -125,8 +125,8 @@ def __init__(self, parent=None, view=None, listView=None, self.dsbx_linewidth.setValue(2.0) # Connect Signals and Slots - self.listView.model().rowsInserted.connect(self.wait) - self.listView.model().rowsRemoved.connect(self.flighttrackRemoved) + self.listFlightTracks.model().rowsInserted.connect(self.wait) + self.listFlightTracks.model().rowsRemoved.connect(self.flighttrackRemoved) self.ui.signal_activate_flighttrack1.connect(self.get_active) self.list_flighttrack.itemChanged.connect(self.flagop) @@ -136,10 +136,13 @@ def __init__(self, parent=None, view=None, listView=None, self.dsbx_linewidth.valueChanged.connect(self.set_linewidth) # Load flighttracks - for index in range(self.listView.count()): - wp_model = self.listView.item(index).flighttrack_model + for index in range(self.listFlightTracks.count()): + wp_model = self.listFlightTracks.item(index).flighttrack_model listItem = self.create_list_item(wp_model, self.list_flighttrack) + self.activate_flighttrack() + + # Connect Mscolab Operations ListWidget if mscolab_server_url is not None: self.operations = MultipleFlightpathOperations(mscolab_server_url, token, self.list_operation_track, self.listOperationsMSC, self.view) @@ -147,7 +150,13 @@ def __init__(self, parent=None, view=None, listView=None, # Signal emitted, on activation of operation from MSUI self.ui.signal_activate_operation.connect(self.update_op_id) - self.activate_flighttrack() + # deactivate vice versa selection of Operation or Flight Track + self.listFlightTracks.itemClicked.connect(lambda: self.list_operation_track.setCurrentItem(None)) + self.listOperationsMSC.itemClicked.connect(lambda: self.list_flighttrack.setCurrentItem(None)) + + # deactivate operation or flighttrack + self.listOperationsMSC.itemDoubleClicked.connect(self.deactivate_all_flighttracks) + self.listFlightTracks.itemDoubleClicked.connect(self.operations.deactivate_all_operations) # self.view.plot_multiple_flightpath(self) @@ -178,7 +187,7 @@ def flighttrackAdded(self, parent, start, end): """ Slot to add flighttrack. """ - wp_model = self.listView.item(start).flighttrack_model + wp_model = self.listFlightTracks.item(start).flighttrack_model listItem = self.create_list_item(wp_model, self.list_flighttrack) self.activate_flighttrack() @@ -308,12 +317,10 @@ def activate_flighttrack(self): if listItem.checkState() == QtCore.Qt.Unchecked: listItem.setCheckState(QtCore.Qt.Checked) self.set_activate_flag() - listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable + listItem.setFlags(listItem.flags() & ~QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: font.setBold(False) listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) - # if self.dict_flighttrack[listItem.flighttrack_model]["checkState"]: - # listItem.setCheckState(QtCore.Qt.Checked) self.set_activate_flag() listItem.setFont(font) @@ -349,6 +356,24 @@ def set_activate_flag(self): def update_op_id(self, op_id): self.operations.get_op_id(op_id) + def deactivate_all_flighttracks(self): + """ + Remove all flighttrack patches from topview canvas and make flighttracks userCheckable. + """ + for index in range(self.list_flighttrack.count()): + listItem = self.list_flighttrack.item(index) + + if self.dict_flighttrack[listItem.flighttrack_model]["patch"] is not None: + self.dict_flighttrack[listItem.flighttrack_model]["patch"].remove() + + # Uncheck all flighttracks + self.set_activate_flag() + listItem.setCheckState(QtCore.Qt.Unchecked) + self.set_activate_flag() + listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) + + self.active_flight_track = None + class MultipleFlightpathOperations: """ @@ -386,6 +411,8 @@ def __init__(self, mscolab_server_url, token, list_operation_track, listOperatio wp_model.name = operations["path"] self.create_operation(wp_model, op_id) + self.activate_operation() + def set_flag(self): if self.operation_added: self.operation_added = False @@ -464,7 +491,7 @@ def activate_operation(self): if listItem.checkState() == QtCore.Qt.Unchecked: listItem.setCheckState(QtCore.Qt.Checked) self.set_activate_flag() - listItem.setFlags(listItem.flags() ^ QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable + listItem.setFlags(listItem.flags() & ~QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: font.setBold(False) listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) @@ -484,7 +511,7 @@ def draw_inactive_operations(self): listItem = self.list_operation_track.item(index) if hasattr(listItem, "checkState") and ( listItem.checkState() == QtCore.Qt.Checked): - if listItem.flighttrack_model != self.active_flight_track: + if listItem.op_id != self.active_op_id: patch = MultipleFlightpath(self.view.map, self.dict_operations[listItem.flighttrack_model][ "wp_data"]) @@ -497,6 +524,7 @@ def draw_inactive_operations(self): def get_op_id(self, op_id): self.active_op_id = op_id + self.activate_operation() def wait2(self, parent, start, end): self.operation_added = True @@ -525,3 +553,20 @@ def operationRemoved(self, parent, start, end): def set_activate_flag(self): if not self.operation_activated: self.operation_activated = True + + def deactivate_all_operations(self): + """ + Removes all operations patches from topview canvas and make flighttracks userCheckable + """ + for index in range(self.listOperationsMSC.count()): + listItem = self.list_operation_track.item(index) + + if self.dict_operations[listItem.flighttrack_model]["patch"] is not None: + self.dict_operations[listItem.flighttrack_model]["patch"].remove() + + # Uncheck all operations + self.set_activate_flag() + listItem.setCheckState(QtCore.Qt.Unchecked) + self.set_activate_flag() + listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) + self.active_op_id = None \ No newline at end of file diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index 09b737687..412c4adde 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -215,6 +215,11 @@ def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, m # Store active flighttrack waypoint model self.active_flighttrack = active_flighttrack + + # Stores active mscolab operation id + self.active_op_id = None + + # Mscolab Server Url and token self.mscolab_server_url = mscolab_server_url self.token = token @@ -251,6 +256,7 @@ def update_active_flighttrack(self, active_flighttrack): @QtCore.Slot(int) def update_active_operation(self, active_op_id): + self.active_op_id = active_op_id self.signal_activate_operation.emit(active_op_id) def setup_top_view(self): @@ -322,11 +328,12 @@ def openTool(self, index): elif index == MULTIPLEFLIGHTPATH: title = "Multiple Flightpath" widget = mf.MultipleFlightpathControlWidget(parent=self, view=self.mpl.canvas, - listView=self.ui.listFlightTracks, + listFlightTracks=self.ui.listFlightTracks, listOperationsMSC=self.ui.listOperationsMSC, activeFlightTrack=self.active_flighttrack, mscolab_server_url=self.mscolab_server_url, token=self.token) + self.signal_activate_operation.emit(self.active_op_id) else: raise IndexError("invalid control index") From 131cedbabfb9e117ae155515c4e0df5b4182b380 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Tue, 1 Nov 2022 13:29:39 +0530 Subject: [PATCH 14/33] show_flighttrack_color_icon --- mslib/msui/multiple_flightpath_dockwidget.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index e6bbdd416..a92156e89 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -204,7 +204,7 @@ def create_list_item(self, wp_model, listWidget): # Create new key in dict self.dict_flighttrack[wp_model] = {} self.dict_flighttrack[wp_model]["patch"] = None - self.dict_flighttrack[wp_model]["color"] = None + self.dict_flighttrack[wp_model]["color"] = (0.0, 0.3333333333333333, 1.0, 1.0) # (r,g,b,alpha) value for blue color self.dict_flighttrack[wp_model]["linewidth"] = 2 self.dict_flighttrack[wp_model]["wp_data"] = [] self.dict_flighttrack[wp_model]["checkState"] = False @@ -219,6 +219,9 @@ def create_list_item(self, wp_model, listWidget): if not self.flighttrack_added: self.flighttrack_added = True + # Show flighttrack color icon + listItem.setIcon(self.show_color_icon(self.get_color(wp_model))) + return listItem def select_color(self): From 8a080aebd6d33fc15789d30e36eb60c2779fb0b4 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Wed, 2 Nov 2022 21:03:30 +0530 Subject: [PATCH 15/33] defined_coloring_of_operation_flightpaths --- mslib/msui/multiple_flightpath_dockwidget.py | 115 ++++++++++++++----- 1 file changed, 89 insertions(+), 26 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index a92156e89..cc8125d65 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -117,6 +117,9 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, self.listOperationsMSC = listOperationsMSC self.listFlightTracks = listFlightTracks + self.operation_list = False + self.flighttrack_list = False + # Set flags self.flighttrack_added = False self.flighttrack_activated = False @@ -130,21 +133,19 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, self.ui.signal_activate_flighttrack1.connect(self.get_active) self.list_flighttrack.itemChanged.connect(self.flagop) - # self.get_wps_from_server() - self.pushButton_color.clicked.connect(self.select_color) self.dsbx_linewidth.valueChanged.connect(self.set_linewidth) # Load flighttracks for index in range(self.listFlightTracks.count()): wp_model = self.listFlightTracks.item(index).flighttrack_model - listItem = self.create_list_item(wp_model, self.list_flighttrack) + listItem = self.create_list_item(wp_model) self.activate_flighttrack() # Connect Mscolab Operations ListWidget if mscolab_server_url is not None: - self.operations = MultipleFlightpathOperations(mscolab_server_url, token, self.list_operation_track, + self.operations = MultipleFlightpathOperations(self, mscolab_server_url, token, self.list_operation_track, self.listOperationsMSC, self.view) # Signal emitted, on activation of operation from MSUI @@ -188,30 +189,31 @@ def flighttrackAdded(self, parent, start, end): Slot to add flighttrack. """ wp_model = self.listFlightTracks.item(start).flighttrack_model - listItem = self.create_list_item(wp_model, self.list_flighttrack) + listItem = self.create_list_item(wp_model) self.activate_flighttrack() def save_waypoint_model_data(self, wp_model, listWidget): wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] if self.dict_flighttrack[wp_model] is None: - self.create_list_item(wp_model, listWidget) + self.create_list_item(wp_model) self.dict_flighttrack[wp_model]["wp_data"] = wp_data - def create_list_item(self, wp_model, listWidget): + def create_list_item(self, wp_model): """ PyQt5 method : Add items in list and add checkbox functionality """ # Create new key in dict self.dict_flighttrack[wp_model] = {} self.dict_flighttrack[wp_model]["patch"] = None - self.dict_flighttrack[wp_model]["color"] = (0.0, 0.3333333333333333, 1.0, 1.0) # (r,g,b,alpha) value for blue color + self.dict_flighttrack[wp_model]["color"] = ( + 0.0, 0.3333333333333333, 1.0, 1.0) # (r,g,b,alpha) value for blue color self.dict_flighttrack[wp_model]["linewidth"] = 2 self.dict_flighttrack[wp_model]["wp_data"] = [] self.dict_flighttrack[wp_model]["checkState"] = False - self.save_waypoint_model_data(wp_model, listWidget) + self.save_waypoint_model_data(wp_model, self.list_flighttrack) - listItem = msui.QFlightTrackListWidgetItem(wp_model, listWidget) + listItem = msui.QFlightTrackListWidgetItem(wp_model, self.list_flighttrack) listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) if not self.flighttrack_added: self.flighttrack_added = True @@ -228,21 +230,23 @@ def select_color(self): """ Sets the color of selected flighttrack when Change Color is clicked. """ - if self.list_flighttrack.currentItem() is not None: - if (hasattr(self.list_flighttrack.currentItem(), "checkState")) and ( - self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): - wp_model = self.list_flighttrack.currentItem().flighttrack_model - color = QtWidgets.QColorDialog.getColor() - if color.isValid(): - self.dict_flighttrack[wp_model]["color"] = color.getRgbF() - self.color_change = True - self.list_flighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) - self.dict_flighttrack[wp_model]["patch"].update(color= - self.dict_flighttrack[wp_model]["color"]) + # ToDO: + if self.operation_list: + self.operations.select_color() + else: + if self.list_flighttrack.currentItem() is not None: + if (hasattr(self.list_flighttrack.currentItem(), "checkState")) and ( + self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): + wp_model = self.list_flighttrack.currentItem().flighttrack_model + color = QtWidgets.QColorDialog.getColor() + if color.isValid(): + self.dict_flighttrack[wp_model]["color"] = color.getRgbF() + self.color_change = True + self.list_flighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) + self.dict_flighttrack[wp_model]["patch"].update(color= + self.dict_flighttrack[wp_model]["color"]) else: self.labelStatus.setText("Status: No flight track selected") - else: - self.labelStatus.setText("Status: No flight track selected") def get_color(self, wp_model): """ @@ -369,14 +373,25 @@ def deactivate_all_flighttracks(self): if self.dict_flighttrack[listItem.flighttrack_model]["patch"] is not None: self.dict_flighttrack[listItem.flighttrack_model]["patch"].remove() + self.set_listControl(True, False) + # Uncheck all flighttracks self.set_activate_flag() listItem.setCheckState(QtCore.Qt.Unchecked) self.set_activate_flag() listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) + if listItem.flighttrack_model == self.active_flight_track: + font = QtGui.QFont() + font.setBold(False) + listItem.setFont(font) + self.active_flight_track = None + def set_listControl(self, operation, flighttrack): + self.operation_list = operation + self.flighttrack_list = flighttrack + class MultipleFlightpathOperations: """ @@ -384,8 +399,10 @@ class MultipleFlightpathOperations: on the TopView canvas. """ - def __init__(self, mscolab_server_url, token, list_operation_track, listOperationsMSC, view): + def __init__(self, parent, mscolab_server_url, token, list_operation_track, listOperationsMSC, view): + # super(MultipleFlightpathOperations, self).__init__(parent) # Variables related to Mscolab Operations + self.parent = parent self.active_op_id = None self.mscolab_server_url = mscolab_server_url self.token = token @@ -398,6 +415,7 @@ def __init__(self, mscolab_server_url, token, list_operation_track, listOperatio self.operation_added = False self.operation_removed = False self.operation_activated = False + self.color_change = False # Connect signals and slots self.list_operation_track.itemChanged.connect(self.set_flag) @@ -421,6 +439,8 @@ def set_flag(self): self.operation_added = False elif self.operation_removed: self.operation_removed = False + elif self.color_change: + self.color_change = False else: self.draw_inactive_operations() @@ -465,6 +485,7 @@ def create_operation(self, wp_model, op_id): self.dict_operations[wp_model] = {} self.dict_operations[wp_model]["patch"] = None self.dict_operations[wp_model]["op_id"] = None + self.dict_operations[wp_model]["color"] = (0.0, 0.3333333333333333, 1.0, 1.0) # (r,g,b,alpha) value for blue color # self.sav self.save_operation_data(wp_model, op_id) @@ -478,6 +499,9 @@ def create_operation(self, wp_model, op_id): if not self.operation_added: self.operation_added = True + # Show operations color icon + listItem.setIcon(self.show_color_icon(self.get_color(wp_model))) + return listItem def activate_operation(self): @@ -517,7 +541,8 @@ def draw_inactive_operations(self): if listItem.op_id != self.active_op_id: patch = MultipleFlightpath(self.view.map, self.dict_operations[listItem.flighttrack_model][ - "wp_data"]) + "wp_data"], + color=self.dict_operations[listItem.flighttrack_model]["color"]) self.dict_operations[listItem.flighttrack_model]["patch"] = patch # self.dict_operations[listItem.flighttrack_model]["checkState"] = True @@ -567,9 +592,47 @@ def deactivate_all_operations(self): if self.dict_operations[listItem.flighttrack_model]["patch"] is not None: self.dict_operations[listItem.flighttrack_model]["patch"].remove() + self.parent.set_listControl(False, True) + # Uncheck all operations self.set_activate_flag() listItem.setCheckState(QtCore.Qt.Unchecked) self.set_activate_flag() listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) - self.active_op_id = None \ No newline at end of file + + if listItem.op_id == self.active_op_id: + font = QtGui.QFont() + font.setBold(False) + listItem.setFont(font) + + self.active_op_id = None + + def select_color(self): + """ + Sets the color of selected operation when change Color is clicked. + """ + if self.list_operation_track.currentItem() is not None: + if (hasattr(self.list_operation_track.currentItem(), "checkState")) and ( + self.list_operation_track.currentItem().checkState() == QtCore.Qt.Checked): + wp_model = self.list_operation_track.currentItem().flighttrack_model + color = QtWidgets.QColorDialog.getColor() + if color.isValid(): + self.dict_operations[wp_model]["color"] = color.getRgbF() + self.color_change = True + self.list_operation_track.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) + self.dict_operations[wp_model]["patch"].update(color= + self.dict_operations[wp_model]["color"]) + + def get_color(self, wp_model): + """ + Returns color of respective operation. + """ + return self.dict_operations[wp_model]["color"] + + def show_color_icon(self, clr): + """ + Creating object of QPixmap for displaying icon inside the listWidget. + """ + pixmap = QtGui.QPixmap(20, 10) + pixmap.fill(QtGui.QColor(int(clr[0] * 255), int(clr[1] * 255), int(clr[2] * 255))) + return QtGui.QIcon(pixmap) From c3edd2963a47aee10d47fe69cab02027a5a2bda2 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Wed, 2 Nov 2022 21:10:17 +0530 Subject: [PATCH 16/33] add_todos --- mslib/msui/multiple_flightpath_dockwidget.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index cc8125d65..0f12aa6a6 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -100,6 +100,8 @@ def remove(self): class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidget): + # ToDO: Make a new parent class with all the functions in this class and inherit them + # in MultipleFlightpathControlWidget and MultipleFlightpathOperations classes. """ This class provides the interface for plotting Multiple Flighttracks on the TopView canvas. @@ -230,7 +232,11 @@ def select_color(self): """ Sets the color of selected flighttrack when Change Color is clicked. """ - # ToDO: + # ToDO: Use color defined in options for initial color of active flight path. + # afterwards deactivate the color change button in options and it needs also + # the check mark for enabled, but can't be changed (disabled). At the moment + # the dockingwidget is closed the button and checkmark has to become activated again. + if self.operation_list: self.operations.select_color() else: From 59ff1a54ce7facfe55d7c4f830bdf8da42817178 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Wed, 2 Nov 2022 21:20:53 +0530 Subject: [PATCH 17/33] add_comments --- mslib/msui/multiple_flightpath_dockwidget.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 0f12aa6a6..d996df11e 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -172,6 +172,10 @@ def remove(self): entry["patch"].remove() def wait(self, parent, start, end): + """ + Adding of flighttrack take time, to avoid emitting of rowInserted signal before that, a delay is inserted in + new thread(it avoid freezing of UI). + """ self.flighttrack_added = True t1 = threading.Timer(0.5, self.flighttrackAdded, [parent, start, end]) t1.start() @@ -309,7 +313,7 @@ def get_active(self, active_flighttrack): def update_last_flighttrack(self): """ - Update waypoint model for last activated flighttrack in dict_flighttrack. + Update waypoint model for most recently activated flighttrack in dict_flighttrack. """ if self.active_flight_track is not None: self.save_waypoint_model_data( From 6a9860d9c4bc2586d18db4f547e44b3c94eae744 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Fri, 4 Nov 2022 19:57:21 +0530 Subject: [PATCH 18/33] fixed_coloring_of_flighttracks --- mslib/msui/mscolab.py | 4 + mslib/msui/msui.py | 12 +++ mslib/msui/multiple_flightpath_dockwidget.py | 95 ++++++++++++-------- mslib/msui/topview.py | 32 ++++++- 4 files changed, 107 insertions(+), 36 deletions(-) diff --git a/mslib/msui/mscolab.py b/mslib/msui/mscolab.py index 339d6a912..6c6dde485 100644 --- a/mslib/msui/mscolab.py +++ b/mslib/msui/mscolab.py @@ -415,6 +415,8 @@ class MSUIMscolab(QtCore.QObject): name = "Mscolab" signal_activate_operation = QtCore.Signal(int, name="signal_activate_operation") + signal_operation_added = QtCore.Signal(int, str, name="signal_operation_added") + signal_operation_removed = QtCore.Signal(int, name="signal_operation_removed") def __init__(self, parent=None, data_dir=None): super(MSUIMscolab, self).__init__(parent) @@ -839,6 +841,7 @@ def add_operation(self): self.error_dialog.showMessage('Your operation was created successfully') op_id = self.get_recent_op_id() self.conn.handle_new_operation(op_id) + self.signal_operation_added.emit(op_id, path) else: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('The path already exists') @@ -1005,6 +1008,7 @@ def handle_delete_operation(self): res = requests.post(url, data=data) res.raise_for_status() self.reload_operations() + self.signal_operation_removed.emit(self.active_op_id) except requests.exceptions.RequestException as e: logging.debug(e) show_popup(self.ui, "Error", "Some error occurred! Could not delete operation.") diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index 66f8d41cd..c91b3f1c1 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -338,6 +338,8 @@ class MSUIMainWindow(QtWidgets.QMainWindow, ui.Ui_MSUIMainWindow): viewsChanged = QtCore.pyqtSignal(name="viewsChanged") signal_activate_flighttrack = QtCore.Signal(ft.WaypointsTableModel, name="signal_activate_flighttrack") signal_activate_operation = QtCore.Signal(int, name="signal_activate_operation") + signal_operation_added = QtCore.Signal(int, str, name="signal_operation_added") + signal_operation_removed = QtCore.Signal(int, name="signal_operation_removed") def __init__(self, mscolab_data_dir=None, *args): super(MSUIMainWindow, self).__init__(*args) @@ -429,6 +431,8 @@ def __init__(self, mscolab_data_dir=None, *args): self.listOperationsMSC.itemClicked.connect(lambda: self.listFlightTracks.setCurrentItem(None)) self.mscolab.signal_activate_operation.connect(self.activate_operation_slot) + self.mscolab.signal_operation_added.connect(self.add_operation_slot) + self.mscolab.signal_operation_removed.connect(self.remove_operation_slot) # Don't start the updater during a test run of msui if "pytest" not in sys.modules: @@ -498,6 +502,14 @@ def add_plugins(self): def activate_operation_slot(self, active_op_id): self.signal_activate_operation.emit(active_op_id) + @QtCore.Slot(int, str) + def add_operation_slot(self, op_id, path): + self.signal_operation_added.emit(op_id, path) + + @QtCore.Slot(int) + def remove_operation_slot(self, op_id): + self.signal_operation_removed.emit(op_id) + def add_plugin_submenu(self, name, extension, function, pickertype, plugin_type="Import"): if plugin_type == "Import": menu = self.menuImportFlightTrack diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index d996df11e..a8d6d4ca0 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -100,15 +100,17 @@ def remove(self): class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidget): - # ToDO: Make a new parent class with all the functions in this class and inherit them - # in MultipleFlightpathControlWidget and MultipleFlightpathOperations classes. """ This class provides the interface for plotting Multiple Flighttracks on the TopView canvas. """ + # ToDO: Make a new parent class with all the functions in this class and inherit them + # in MultipleFlightpathControlWidget and MultipleFlightpathOperations classes. + def __init__(self, parent=None, view=None, listFlightTracks=None, - listOperationsMSC=None, activeFlightTrack=None, mscolab_server_url=None, token=None): + listOperationsMSC=None, activeFlightTrack=None, mscolab_server_url=None, token=None, + color=None): super(MultipleFlightpathControlWidget, self).__init__(parent) self.ui = parent self.setupUi(self) @@ -118,6 +120,7 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, self.active_flight_track = activeFlightTrack self.listOperationsMSC = listOperationsMSC self.listFlightTracks = listFlightTracks + self.color = color self.operation_list = False self.flighttrack_list = False @@ -136,6 +139,7 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, self.list_flighttrack.itemChanged.connect(self.flagop) self.pushButton_color.clicked.connect(self.select_color) + self.ui.signal_ft_vertices_color_change.connect(self.ft_vertices_color) self.dsbx_linewidth.valueChanged.connect(self.set_linewidth) # Load flighttracks @@ -152,6 +156,8 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, # Signal emitted, on activation of operation from MSUI self.ui.signal_activate_operation.connect(self.update_op_id) + self.ui.signal_operation_added.connect(self.add_operation_slot) + self.ui.signal_operation_removed.connect(self.remove_operation_slot) # deactivate vice versa selection of Operation or Flight Track self.listFlightTracks.itemClicked.connect(lambda: self.list_operation_track.setCurrentItem(None)) @@ -163,6 +169,14 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, # self.view.plot_multiple_flightpath(self) + @QtCore.Slot(int, str) + def add_operation_slot(self, op_id, path): + self.operations.operationsAdded(op_id, path) + + @QtCore.Slot(int) + def remove_operation_slot(self, op_id): + self.operations.operationRemoved(op_id) + def update(self): for entry in self.dict_flighttrack.values(): entry["patch"].update() @@ -176,6 +190,7 @@ def wait(self, parent, start, end): Adding of flighttrack take time, to avoid emitting of rowInserted signal before that, a delay is inserted in new thread(it avoid freezing of UI). """ + # ToDo: self.flighttrack_added = True t1 = threading.Timer(0.5, self.flighttrackAdded, [parent, start, end]) t1.start() @@ -198,6 +213,17 @@ def flighttrackAdded(self, parent, start, end): listItem = self.create_list_item(wp_model) self.activate_flighttrack() + @QtCore.Slot(tuple) + def ft_vertices_color(self, color): + self.color = color + self.dict_flighttrack[self.active_flight_track]["color"] = color + + for index in range(self.list_flighttrack.count()): + if self.list_flighttrack.item(index).flighttrack_model == self.active_flight_track: + self.list_flighttrack.item(index).setIcon( + self.show_color_icon(self.get_color(self.active_flight_track))) + break + def save_waypoint_model_data(self, wp_model, listWidget): wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] if self.dict_flighttrack[wp_model] is None: @@ -211,8 +237,7 @@ def create_list_item(self, wp_model): # Create new key in dict self.dict_flighttrack[wp_model] = {} self.dict_flighttrack[wp_model]["patch"] = None - self.dict_flighttrack[wp_model]["color"] = ( - 0.0, 0.3333333333333333, 1.0, 1.0) # (r,g,b,alpha) value for blue color + self.dict_flighttrack[wp_model]["color"] = self.color self.dict_flighttrack[wp_model]["linewidth"] = 2 self.dict_flighttrack[wp_model]["wp_data"] = [] self.dict_flighttrack[wp_model]["checkState"] = False @@ -248,13 +273,18 @@ def select_color(self): if (hasattr(self.list_flighttrack.currentItem(), "checkState")) and ( self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): wp_model = self.list_flighttrack.currentItem().flighttrack_model - color = QtWidgets.QColorDialog.getColor() - if color.isValid(): - self.dict_flighttrack[wp_model]["color"] = color.getRgbF() - self.color_change = True - self.list_flighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) - self.dict_flighttrack[wp_model]["patch"].update(color= - self.dict_flighttrack[wp_model]["color"]) + if wp_model == self.active_flight_track: + message_box = QtWidgets.QMessageBox() + message_box.setIcon(QtWidgets.QMessageBox.Information) + message_box.about(self, 'Message', 'Use options to change color of Activated Flighttrack.') + else: + color = QtWidgets.QColorDialog.getColor() + if color.isValid(): + self.dict_flighttrack[wp_model]["color"] = color.getRgbF() + self.color_change = True + self.list_flFighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) + self.dict_flighttrack[wp_model]["patch"].update(color= + self.dict_flighttrack[wp_model]["color"]) else: self.labelStatus.setText("Status: No flight track selected") @@ -410,7 +440,6 @@ class MultipleFlightpathOperations: """ def __init__(self, parent, mscolab_server_url, token, list_operation_track, listOperationsMSC, view): - # super(MultipleFlightpathOperations, self).__init__(parent) # Variables related to Mscolab Operations self.parent = parent self.active_op_id = None @@ -429,13 +458,12 @@ def __init__(self, parent, mscolab_server_url, token, list_operation_track, list # Connect signals and slots self.list_operation_track.itemChanged.connect(self.set_flag) - self.listOperationsMSC.model().rowsInserted.connect(self.wait2) - self.listOperationsMSC.model().rowsRemoved.connect(self.operationRemoved) # Load operations from wps server server_operations = self.get_wps_from_server() + sorted_server_operations = sorted(server_operations, key=lambda d: d["path"]) - for operations in server_operations: + for operations in sorted_server_operations: op_id = operations["op_id"] xml_content = self.request_wps_from_server(op_id) wp_model = ft.WaypointsTableModel(xml_content=xml_content) @@ -495,7 +523,8 @@ def create_operation(self, wp_model, op_id): self.dict_operations[wp_model] = {} self.dict_operations[wp_model]["patch"] = None self.dict_operations[wp_model]["op_id"] = None - self.dict_operations[wp_model]["color"] = (0.0, 0.3333333333333333, 1.0, 1.0) # (r,g,b,alpha) value for blue color + self.dict_operations[wp_model]["color"] = ( + 0.0, 0.3333333333333333, 1.0, 1.0) # (r,g,b,alpha) value for blue color # self.sav self.save_operation_data(wp_model, op_id) @@ -555,38 +584,34 @@ def draw_inactive_operations(self): color=self.dict_operations[listItem.flighttrack_model]["color"]) self.dict_operations[listItem.flighttrack_model]["patch"] = patch - # self.dict_operations[listItem.flighttrack_model]["checkState"] = True - else: - pass - # self.dict_operations[listItem.flighttrack_model]["checkState"] = False def get_op_id(self, op_id): self.active_op_id = op_id self.activate_operation() - def wait2(self, parent, start, end): - self.operation_added = True - t2 = threading.Timer(0.5, self.operationsAdded, [parent, start, end]) - t2.start() - - def operationsAdded(self, parent, start, end): + def operationsAdded(self, op_id, path): """ Slot to add operation. """ - wp_model = self.list_operation_track.item(start).flighttrack_model - listItem = self.create_operation(wp_model, self.list_operation_track) + wp_model = self.load_wps_from_server(op_id) + wp_model.name = path + listItem = self.create_operation(wp_model, op_id) + self.active_op_id = op_id self.activate_operation() - def operationRemoved(self, parent, start, end): + def operationRemoved(self, op_id): """ Slot to remove operation. """ self.operation_removed = True - if self.dict_operations[self.list_operation_track.item(start).flighttrack_model]["patch"] is None: - del self.dict_operations[self.list_operation_track.item(start).flighttrack_model] - else: - self.dict_operations[self.list_operation_track.item(start).flighttrack_model]["patch"].remove() - self.list_operation_track.takeItem(start) + for index in range(self.list_operation_track.count()): + if self.list_operation_track.item(index).op_id == op_id: + if self.dict_operations[self.list_operation_track.item(index).flighttrack_model]["patch"] is None: + del self.dict_operations[self.list_operation_track.item(index).flighttrack_model] + else: + self.dict_operations[self.list_operation_track.item(index).flighttrack_model]["patch"].remove() + self.list_operation_track.takeItem(index) + break def set_activate_flag(self): if not self.operation_activated: diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index 412c4adde..da49e4076 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -60,6 +60,7 @@ class MSUI_TV_MapAppearanceDialog(QtWidgets.QDialog, ui_ma.Ui_MapAppearanceDialo Dialog to set map appearance parameters. User interface is defined in "ui_topview_mapappearance.py". """ + signal_ft_vertices_color_change = QtCore.Signal(str, tuple) def __init__(self, parent=None, settings_dict=None, wms_connected=False): """ @@ -176,6 +177,7 @@ def setColour(self, which): colour = palette.color(QtGui.QPalette.Button) colour = QtWidgets.QColorDialog.getColor(colour) if colour.isValid(): + self.signal_ft_vertices_color_change.emit(which, colour.getRgbF()) palette.setColor(QtGui.QPalette.Button, colour) button.setPalette(palette) @@ -189,6 +191,9 @@ class MSUITopViewWindow(MSUIMplViewWindow, ui.Ui_TopViewWindow): signal_activate_flighttrack1 = QtCore.Signal(ft.WaypointsTableModel) signal_activate_operation = QtCore.Signal(int) + signal_ft_vertices_color_change = QtCore.Signal(tuple) + signal_operation_added = QtCore.Signal(int, str) + signal_operation_removed = QtCore.Signal(int) def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, mscolab_server_url=None , token=None): @@ -223,6 +228,9 @@ def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, m self.mscolab_server_url = mscolab_server_url self.token = token + # + self.ft_vertices_color = None + # Connect slots and signals. # ========================== @@ -243,6 +251,9 @@ def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, m self.ui.signal_activate_flighttrack.connect(self.update_active_flighttrack) self.ui.signal_activate_operation.connect(self.update_active_operation) + self.ui.signal_operation_added.connect(self.add_operation_slot) + self.ui.signal_operation_removed.connect(self.remove_operation_slot) + def __del__(self): del self.mpl.canvas.waypoints_interactor @@ -259,6 +270,14 @@ def update_active_operation(self, active_op_id): self.active_op_id = active_op_id self.signal_activate_operation.emit(active_op_id) + @QtCore.Slot(int, str) + def add_operation_slot(self, op_id, path): + self.signal_operation_added.emit(op_id, path) + + @QtCore.Slot(int) + def remove_operation_slot(self, op_id): + self.signal_operation_removed.emit(op_id) + def setup_top_view(self): """ Initialise GUI elements. (This method is called before signals/slots @@ -327,12 +346,13 @@ def openTool(self, index): widget = ad.AirdataDockwidget(parent=self, view=self.mpl.canvas) elif index == MULTIPLEFLIGHTPATH: title = "Multiple Flightpath" + self.load_ft_vertices_color() widget = mf.MultipleFlightpathControlWidget(parent=self, view=self.mpl.canvas, listFlightTracks=self.ui.listFlightTracks, listOperationsMSC=self.ui.listOperationsMSC, activeFlightTrack=self.active_flighttrack, mscolab_server_url=self.mscolab_server_url, - token=self.token) + token=self.token, color=self.ft_vertices_color) self.signal_activate_operation.emit(self.active_op_id) else: raise IndexError("invalid control index") @@ -385,6 +405,7 @@ def settings_dialogue(self): settings = self.getView().get_map_appearance() dlg = MSUI_TV_MapAppearanceDialog(parent=self, settings_dict=settings, wms_connected=self.wms_connected) dlg.setModal(False) + dlg.signal_ft_vertices_color_change.connect(self.set_ft_vertices_color) if dlg.exec_() == QtWidgets.QDialog.Accepted: settings = dlg.get_settings() self.getView().set_map_appearance(settings) @@ -392,6 +413,11 @@ def settings_dialogue(self): self.mpl.canvas.waypoints_interactor.redraw_path() dlg.destroy() + @QtCore.Slot(str, tuple) + def set_ft_vertices_color(self, which, color): + if which == "ft_vertices": + self.signal_ft_vertices_color_change.emit(color) + def save_settings(self): """ Save the current settings (map appearance) to the file @@ -440,3 +466,7 @@ def is_roundtrip_possible(self): def update_roundtrip_enabled(self): self.btRoundtrip.setEnabled(self.is_roundtrip_possible()) + + def load_ft_vertices_color(self): + settings = load_settings_qsettings(self.settings_tag, {}) + self.ft_vertices_color = settings["colour_ft_vertices"] From 6930d8f67b3812626326a7c55d8c8ad3dd337122 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sat, 5 Nov 2022 14:19:00 +0530 Subject: [PATCH 19/33] clear_operation_list_after_logout --- mslib/msui/mscolab.py | 6 + mslib/msui/msui.py | 5 + mslib/msui/multiple_flightpath_dockwidget.py | 235 +++++++++++------- .../qt5/ui_multiple_flightpath_dockwidget.py | 42 +++- mslib/msui/topview.py | 16 +- .../ui/ui_multiple_flightpath_dockwidget.ui | 46 +++- 6 files changed, 252 insertions(+), 98 deletions(-) diff --git a/mslib/msui/mscolab.py b/mslib/msui/mscolab.py index 6c6dde485..8e35cab0e 100644 --- a/mslib/msui/mscolab.py +++ b/mslib/msui/mscolab.py @@ -417,6 +417,8 @@ class MSUIMscolab(QtCore.QObject): signal_activate_operation = QtCore.Signal(int, name="signal_activate_operation") signal_operation_added = QtCore.Signal(int, str, name="signal_operation_added") signal_operation_removed = QtCore.Signal(int, name="signal_operation_removed") + signal_login_mscolab = QtCore.Signal(str, str, name="signal_login_mscolab") + signal_logout_mscolab = QtCore.Signal(name="signal_logout_mscolab") def __init__(self, parent=None, data_dir=None): super(MSUIMscolab, self).__init__(parent) @@ -615,6 +617,8 @@ def after_login(self, emailid, url, r): # disable activate operation button self.ui.actionActivateOperation.setEnabled(False) + self.signal_login_mscolab.emit(self.mscolab_server_url, self.token) + def fetch_gravatar(self, refresh=False): email_hash = hashlib.md5(bytes(self.email.encode('utf-8')).lower()).hexdigest() email_in_config = self.email in config_loader(dataset="gravatar_ids") @@ -1832,6 +1836,8 @@ def logout(self): del self.settings["auth"][self.mscolab_server_url] save_settings_qsettings('mscolab', self.settings) + self.signal_logout_mscolab.emit() + # Don't try to activate local flighttrack while testing if "pytest" not in sys.modules: # activate first local flighttrack after logging out diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index c91b3f1c1..5215af62e 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -140,6 +140,7 @@ class MSUI_ShortcutsDialog(QtWidgets.QDialog, ui_sh.Ui_ShortcutsDialog): """ Dialog showing shortcuts for all currently open windows """ + def __init__(self): super(MSUI_ShortcutsDialog, self).__init__(QtWidgets.QApplication.activeWindow()) self.setupUi(self) @@ -340,6 +341,8 @@ class MSUIMainWindow(QtWidgets.QMainWindow, ui.Ui_MSUIMainWindow): signal_activate_operation = QtCore.Signal(int, name="signal_activate_operation") signal_operation_added = QtCore.Signal(int, str, name="signal_operation_added") signal_operation_removed = QtCore.Signal(int, name="signal_operation_removed") + signal_login_mscolab = QtCore.Signal(str, str, name="signal_login_mscolab") + signal_logout_mscolab = QtCore.Signal(name="signal_logout_mscolab") def __init__(self, mscolab_data_dir=None, *args): super(MSUIMainWindow, self).__init__(*args) @@ -433,6 +436,8 @@ def __init__(self, mscolab_data_dir=None, *args): self.mscolab.signal_activate_operation.connect(self.activate_operation_slot) self.mscolab.signal_operation_added.connect(self.add_operation_slot) self.mscolab.signal_operation_removed.connect(self.remove_operation_slot) + self.mscolab.signal_login_mscolab.connect(lambda d, t: self.signal_login_mscolab.emit(d, t)) + self.mscolab.signal_logout_mscolab.connect(lambda: self.signal_logout_mscolab.emit()) # Don't start the updater during a test run of msui if "pytest" not in sys.modules: diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index a8d6d4ca0..6559f6564 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -24,6 +24,8 @@ See the License for the specific language governing permissions and limitations under the License. """ +import logging + from PyQt5 import QtWidgets, QtGui, QtCore from mslib.msui.qt5 import ui_multiple_flightpath_dockwidget as ui from mslib.msui import flighttrack as ft @@ -32,11 +34,13 @@ import threading import requests import json +import gc class QMscolabOperationsListWidgetItem(QtWidgets.QListWidgetItem): """ """ + def __init__(self, flighttrack_model, op_id: int, parent=None, type=QtWidgets.QListWidgetItem.UserType): view_name = flighttrack_model.name super(QMscolabOperationsListWidgetItem, self).__init__( @@ -109,8 +113,7 @@ class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidge # in MultipleFlightpathControlWidget and MultipleFlightpathOperations classes. def __init__(self, parent=None, view=None, listFlightTracks=None, - listOperationsMSC=None, activeFlightTrack=None, mscolab_server_url=None, token=None, - color=None): + listOperationsMSC=None, activeFlightTrack=None, mscolab_server_url=None, token=None): super(MultipleFlightpathControlWidget, self).__init__(parent) self.ui = parent self.setupUi(self) @@ -120,7 +123,11 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, self.active_flight_track = activeFlightTrack self.listOperationsMSC = listOperationsMSC self.listFlightTracks = listFlightTracks - self.color = color + self.mscolab_server_url = mscolab_server_url + self.token = token + self.ft_settings_dict = self.ui.get_settings() + self.color = self.ft_settings_dict["colour_ft_vertices"] + self.obb = [] self.operation_list = False self.flighttrack_list = False @@ -141,6 +148,12 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, self.pushButton_color.clicked.connect(self.select_color) self.ui.signal_ft_vertices_color_change.connect(self.ft_vertices_color) self.dsbx_linewidth.valueChanged.connect(self.set_linewidth) + self.ui.signal_login_mscolab.connect(self.login) + + self.colorPixmap.setPixmap(self.show_color_pixmap(self.color)) + + if self.mscolab_server_url is not None: + self.connect_mscolab_server() # Load flighttracks for index in range(self.listFlightTracks.count()): @@ -149,33 +162,39 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, self.activate_flighttrack() - # Connect Mscolab Operations ListWidget - if mscolab_server_url is not None: - self.operations = MultipleFlightpathOperations(self, mscolab_server_url, token, self.list_operation_track, - self.listOperationsMSC, self.view) + @QtCore.Slot() + def logout(self): + self.operations.logout_mscolab() + for idx in range(len(self.obb)): + del self.obb[idx] - # Signal emitted, on activation of operation from MSUI - self.ui.signal_activate_operation.connect(self.update_op_id) - self.ui.signal_operation_added.connect(self.add_operation_slot) - self.ui.signal_operation_removed.connect(self.remove_operation_slot) + @QtCore.Slot(str, str) + def login(self, url, token): + self.mscolab_server_url = url + self.token = token + self.connect_mscolab_server() - # deactivate vice versa selection of Operation or Flight Track - self.listFlightTracks.itemClicked.connect(lambda: self.list_operation_track.setCurrentItem(None)) - self.listOperationsMSC.itemClicked.connect(lambda: self.list_flighttrack.setCurrentItem(None)) + def connect_mscolab_server(self): + self.operations = MultipleFlightpathOperations(self, self.mscolab_server_url, self.token, + self.list_operation_track, + self.listOperationsMSC, self.view) + self.obb.append(self.operations) - # deactivate operation or flighttrack - self.listOperationsMSC.itemDoubleClicked.connect(self.deactivate_all_flighttracks) - self.listFlightTracks.itemDoubleClicked.connect(self.operations.deactivate_all_operations) + # Signal emitted, on activation of operation from MSUI + self.ui.signal_activate_operation.connect(self.update_op_id) + self.ui.signal_operation_added.connect(self.add_operation_slot) + self.ui.signal_operation_removed.connect(self.remove_operation_slot) - # self.view.plot_multiple_flightpath(self) + # deactivate vice versa selection of Operation or Flight Track + self.listFlightTracks.itemClicked.connect(lambda: self.list_operation_track.setCurrentItem(None)) + self.listOperationsMSC.itemClicked.connect(lambda: self.list_flighttrack.setCurrentItem(None)) - @QtCore.Slot(int, str) - def add_operation_slot(self, op_id, path): - self.operations.operationsAdded(op_id, path) + # deactivate operation or flighttrack + self.listOperationsMSC.itemDoubleClicked.connect(self.deactivate_all_flighttracks) + self.listFlightTracks.itemDoubleClicked.connect(self.operations.deactivate_all_operations) - @QtCore.Slot(int) - def remove_operation_slot(self, op_id): - self.operations.operationRemoved(op_id) + # Mscolab Server logout signal + self.ui.signal_logout_mscolab.connect(self.logout) def update(self): for entry in self.dict_flighttrack.values(): @@ -190,7 +209,7 @@ def wait(self, parent, start, end): Adding of flighttrack take time, to avoid emitting of rowInserted signal before that, a delay is inserted in new thread(it avoid freezing of UI). """ - # ToDo: + # ToDo: Use QThread self.flighttrack_added = True t1 = threading.Timer(0.5, self.flighttrackAdded, [parent, start, end]) t1.start() @@ -216,13 +235,35 @@ def flighttrackAdded(self, parent, start, end): @QtCore.Slot(tuple) def ft_vertices_color(self, color): self.color = color - self.dict_flighttrack[self.active_flight_track]["color"] = color + self.colorPixmap.setPixmap(self.show_color_pixmap(color)) + + if self.flighttrack_list: + self.dict_flighttrack[self.active_flight_track]["color"] = color + for index in range(self.list_flighttrack.count()): + if self.list_flighttrack.item(index).flighttrack_model == self.active_flight_track: + self.list_flighttrack.item(index).setIcon( + self.show_color_icon(self.get_color(self.active_flight_track))) + break + else: + self.operations.ft_color_update(color) - for index in range(self.list_flighttrack.count()): - if self.list_flighttrack.item(index).flighttrack_model == self.active_flight_track: - self.list_flighttrack.item(index).setIcon( - self.show_color_icon(self.get_color(self.active_flight_track))) - break + @QtCore.Slot(int, str) + def add_operation_slot(self, op_id, path): + self.operations.operationsAdded(op_id, path) + + @QtCore.Slot(int) + def remove_operation_slot(self, op_id): + self.operations.operationRemoved(op_id) + + @QtCore.Slot(int) + def update_op_id(self, op_id): + self.operations.get_op_id(op_id) + + @QtCore.Slot(ft.WaypointsTableModel) + def get_active(self, active_flighttrack): + self.update_last_flighttrack() + self.active_flight_track = active_flighttrack + self.activate_flighttrack() def save_waypoint_model_data(self, wp_model, listWidget): wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] @@ -274,15 +315,14 @@ def select_color(self): self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): wp_model = self.list_flighttrack.currentItem().flighttrack_model if wp_model == self.active_flight_track: - message_box = QtWidgets.QMessageBox() - message_box.setIcon(QtWidgets.QMessageBox.Information) - message_box.about(self, 'Message', 'Use options to change color of Activated Flighttrack.') + self.error_dialog = QtWidgets.QErrorMessage() + self.error_dialog.showMessage('Use "options" to change color of an activated flighttrack.') else: color = QtWidgets.QColorDialog.getColor() if color.isValid(): self.dict_flighttrack[wp_model]["color"] = color.getRgbF() self.color_change = True - self.list_flFighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) + self.list_flighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) self.dict_flighttrack[wp_model]["patch"].update(color= self.dict_flighttrack[wp_model]["color"]) else: @@ -294,12 +334,16 @@ def get_color(self, wp_model): """ return self.dict_flighttrack[wp_model]["color"] + def show_color_pixmap(self, clr): + pixmap = QtGui.QPixmap(20, 10) + pixmap.fill(QtGui.QColor(int(clr[0] * 255), int(clr[1] * 255), int(clr[2] * 255))) + return pixmap + def show_color_icon(self, clr): """ Creating object of QPixmap for displaying icon inside the listWidget. """ - pixmap = QtGui.QPixmap(20, 10) - pixmap.fill(QtGui.QColor(int(clr[0] * 255), int(clr[1] * 255), int(clr[2] * 255))) + pixmap = self.show_color_pixmap(clr) return QtGui.QIcon(pixmap) def set_linewidth(self): @@ -335,12 +379,6 @@ def flighttrackRemoved(self, parent, start, end): self.dict_flighttrack[self.list_flighttrack.item(start).flighttrack_model]["patch"].remove() self.list_flighttrack.takeItem(start) - @QtCore.Slot(ft.WaypointsTableModel) - def get_active(self, active_flighttrack): - self.update_last_flighttrack() - self.active_flight_track = active_flighttrack - self.activate_flighttrack() - def update_last_flighttrack(self): """ Update waypoint model for most recently activated flighttrack in dict_flighttrack. @@ -399,10 +437,6 @@ def set_activate_flag(self): if not self.flighttrack_added: self.flighttrack_activated = True - @QtCore.Slot(int) - def update_op_id(self, op_id): - self.operations.get_op_id(op_id) - def deactivate_all_flighttracks(self): """ Remove all flighttrack patches from topview canvas and make flighttracks userCheckable. @@ -432,6 +466,9 @@ def set_listControl(self, operation, flighttrack): self.operation_list = operation self.flighttrack_list = flighttrack + def get_ft_vertices_color(self): + return self.color + class MultipleFlightpathOperations: """ @@ -445,11 +482,10 @@ def __init__(self, parent, mscolab_server_url, token, list_operation_track, list self.active_op_id = None self.mscolab_server_url = mscolab_server_url self.token = token + self.view = view self.dict_operations = {} self.list_operation_track = list_operation_track self.listOperationsMSC = listOperationsMSC - self.active_flight_track = None - self.view = view self.operation_added = False self.operation_removed = False @@ -468,7 +504,7 @@ def __init__(self, parent, mscolab_server_url, token, list_operation_track, list xml_content = self.request_wps_from_server(op_id) wp_model = ft.WaypointsTableModel(xml_content=xml_content) wp_model.name = operations["path"] - self.create_operation(wp_model, op_id) + self.create_operation(op_id, wp_model) self.activate_operation() @@ -510,24 +546,21 @@ def load_wps_from_server(self, op_id): waypoints_model = ft.WaypointsTableModel(xml_content=xml_content) return waypoints_model - def save_operation_data(self, wp_model, op_id): + def save_operation_data(self, op_id, wp_model): wp_data = [(wp.lat, wp.lon, wp.flightlevel, wp.location, wp.comments) for wp in wp_model.all_waypoint_data()] - if self.dict_operations[wp_model] is None: - self.create_operation(wp_model, op_id) - self.dict_operations[wp_model]["wp_data"] = wp_data - self.dict_operations[wp_model]["op_id"] = op_id + if self.dict_operations[op_id] is None: + self.create_operation(op_id, wp_model) + self.dict_operations[op_id]["wp_data"] = wp_data - def create_operation(self, wp_model, op_id): + def create_operation(self, op_id, wp_model): """ """ - self.dict_operations[wp_model] = {} - self.dict_operations[wp_model]["patch"] = None - self.dict_operations[wp_model]["op_id"] = None - self.dict_operations[wp_model]["color"] = ( - 0.0, 0.3333333333333333, 1.0, 1.0) # (r,g,b,alpha) value for blue color - # self.sav + self.dict_operations[op_id] = {} + self.dict_operations[op_id]["patch"] = None + self.dict_operations[op_id]["wp_data"] = None + self.dict_operations[op_id]["color"] = self.parent.get_ft_vertices_color() - self.save_operation_data(wp_model, op_id) + self.save_operation_data(op_id, wp_model) listItem = QMscolabOperationsListWidgetItem(wp_model, op_id, self.list_operation_track) listItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable) @@ -539,7 +572,7 @@ def create_operation(self, wp_model, op_id): self.operation_added = True # Show operations color icon - listItem.setIcon(self.show_color_icon(self.get_color(wp_model))) + listItem.setIcon(self.show_color_icon(self.get_color(op_id))) return listItem @@ -552,8 +585,8 @@ def activate_operation(self): listItem = self.list_operation_track.item(i) if self.active_op_id == listItem.op_id: # active operation font.setBold(True) - if self.dict_operations[listItem.flighttrack_model]["patch"] is not None: - self.dict_operations[listItem.flighttrack_model]["patch"].remove() + if self.dict_operations[listItem.op_id]["patch"] is not None: + self.dict_operations[listItem.op_id]["patch"].remove() if listItem.checkState() == QtCore.Qt.Unchecked: listItem.setCheckState(QtCore.Qt.Checked) self.set_activate_flag() @@ -579,11 +612,11 @@ def draw_inactive_operations(self): listItem.checkState() == QtCore.Qt.Checked): if listItem.op_id != self.active_op_id: patch = MultipleFlightpath(self.view.map, - self.dict_operations[listItem.flighttrack_model][ + self.dict_operations[listItem.op_id][ "wp_data"], - color=self.dict_operations[listItem.flighttrack_model]["color"]) + color=self.dict_operations[listItem.op_id]["color"]) - self.dict_operations[listItem.flighttrack_model]["patch"] = patch + self.dict_operations[listItem.op_id]["patch"] = patch def get_op_id(self, op_id): self.active_op_id = op_id @@ -595,7 +628,7 @@ def operationsAdded(self, op_id, path): """ wp_model = self.load_wps_from_server(op_id) wp_model.name = path - listItem = self.create_operation(wp_model, op_id) + listItem = self.create_operation(op_id, wp_model) self.active_op_id = op_id self.activate_operation() @@ -606,10 +639,10 @@ def operationRemoved(self, op_id): self.operation_removed = True for index in range(self.list_operation_track.count()): if self.list_operation_track.item(index).op_id == op_id: - if self.dict_operations[self.list_operation_track.item(index).flighttrack_model]["patch"] is None: - del self.dict_operations[self.list_operation_track.item(index).flighttrack_model] + if self.dict_operations[self.list_operation_track.item(index).op_id]["patch"] is None: + del self.dict_operations[self.list_operation_track.item(index).op_id] else: - self.dict_operations[self.list_operation_track.item(index).flighttrack_model]["patch"].remove() + self.dict_operations[self.list_operation_track.item(index).op_id]["patch"].remove() self.list_operation_track.takeItem(index) break @@ -624,8 +657,8 @@ def deactivate_all_operations(self): for index in range(self.listOperationsMSC.count()): listItem = self.list_operation_track.item(index) - if self.dict_operations[listItem.flighttrack_model]["patch"] is not None: - self.dict_operations[listItem.flighttrack_model]["patch"].remove() + if self.dict_operations[listItem.op_id]["patch"] is not None: + self.dict_operations[listItem.op_id]["patch"].remove() self.parent.set_listControl(False, True) @@ -649,25 +682,51 @@ def select_color(self): if self.list_operation_track.currentItem() is not None: if (hasattr(self.list_operation_track.currentItem(), "checkState")) and ( self.list_operation_track.currentItem().checkState() == QtCore.Qt.Checked): - wp_model = self.list_operation_track.currentItem().flighttrack_model - color = QtWidgets.QColorDialog.getColor() - if color.isValid(): - self.dict_operations[wp_model]["color"] = color.getRgbF() - self.color_change = True - self.list_operation_track.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) - self.dict_operations[wp_model]["patch"].update(color= - self.dict_operations[wp_model]["color"]) + op_id = self.list_operation_track.currentItem().op_id + if self.list_operation_track.currentItem().op_id == self.active_op_id: + self.error_dialog = QtWidgets.QErrorMessage() + self.error_dialog.showMessage('Use "options" to change color of an activated operation.') + else: + color = QtWidgets.QColorDialog.getColor() + if color.isValid(): + self.dict_operations[op_id]["color"] = color.getRgbF() + self.color_change = True + self.list_operation_track.currentItem().setIcon(self.show_color_icon(self.get_color(op_id))) + self.dict_operations[op_id]["patch"].update(color= + self.dict_operations[op_id]["color"]) - def get_color(self, wp_model): + def get_color(self, op_id): """ Returns color of respective operation. """ - return self.dict_operations[wp_model]["color"] + return self.dict_operations[op_id]["color"] def show_color_icon(self, clr): """ - Creating object of QPixmap for displaying icon inside the listWidget. """ - pixmap = QtGui.QPixmap(20, 10) - pixmap.fill(QtGui.QColor(int(clr[0] * 255), int(clr[1] * 255), int(clr[2] * 255))) + pixmap = self.parent.show_color_pixmap(clr) return QtGui.QIcon(pixmap) + + def ft_color_update(self, color): + self.color = color + self.dict_operations[self.active_op_id]["color"] = color + + for index in range(self.list_operation_track.count()): + if self.list_operation_track.item(index).op_id == self.active_op_id: + self.list_operation_track.item(index).setIcon( + self.show_color_icon(self.get_color(self.active_op_id))) + break + + def logout_mscolab(self): + a = self.list_operation_track.count() - 1 + while a >= 0: + if self.dict_operations[self.list_operation_track.item(0).op_id]['patch'] is None: + del self.dict_operations[self.list_operation_track.item(0).op_id] + else: + self.dict_operations[self.list_operation_track.item(0).op_id]['patch'].remove() + self.list_operation_track.takeItem(0) + a -= 1 + + self.mscolab_server_url = None + self.token = None + self.dict_operations = {} diff --git a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py index 265fa6404..6d81c3b41 100644 --- a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py +++ b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py @@ -13,7 +13,7 @@ class Ui_MultipleViewWidget(object): def setupUi(self, MultipleViewWidget): MultipleViewWidget.setObjectName("MultipleViewWidget") - MultipleViewWidget.resize(544, 235) + MultipleViewWidget.resize(778, 235) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) @@ -21,6 +21,35 @@ def setupUi(self, MultipleViewWidget): MultipleViewWidget.setSizePolicy(sizePolicy) self.verticalLayout_2 = QtWidgets.QVBoxLayout(MultipleViewWidget) self.verticalLayout_2.setObjectName("verticalLayout_2") + self.frame_2 = QtWidgets.QFrame(MultipleViewWidget) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.frame_2.sizePolicy().hasHeightForWidth()) + self.frame_2.setSizePolicy(sizePolicy) + self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel) + self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised) + self.frame_2.setObjectName("frame_2") + self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.frame_2) + self.horizontalLayout_3.setObjectName("horizontalLayout_3") + self.ft_color_label = QtWidgets.QLabel(self.frame_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.ft_color_label.sizePolicy().hasHeightForWidth()) + self.ft_color_label.setSizePolicy(sizePolicy) + self.ft_color_label.setObjectName("ft_color_label") + self.horizontalLayout_3.addWidget(self.ft_color_label) + self.colorPixmap = QtWidgets.QLabel(self.frame_2) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.colorPixmap.sizePolicy().hasHeightForWidth()) + self.colorPixmap.setSizePolicy(sizePolicy) + self.colorPixmap.setText("") + self.colorPixmap.setObjectName("colorPixmap") + self.horizontalLayout_3.addWidget(self.colorPixmap) + self.verticalLayout_2.addWidget(self.frame_2) self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.horizontalLayout_2 = QtWidgets.QHBoxLayout() @@ -84,9 +113,20 @@ def setupUi(self, MultipleViewWidget): def retranslateUi(self, MultipleViewWidget): _translate = QtCore.QCoreApplication.translate MultipleViewWidget.setWindowTitle(_translate("MultipleViewWidget", "Form")) + self.ft_color_label.setText(_translate("MultipleViewWidget", "(Color shown before flighttracks/operations are only visible in \"deactivated\" state) 𝐀𝐜𝐭𝐢𝐯𝐚𝐭𝐞𝐝 𝐓𝐫𝐚𝐜𝐤 𝐕𝐞𝐫𝐭𝐢𝐜𝐞𝐬 𝐂𝐨𝐥𝐨𝐫 : ")) self.list_flighttrack.setToolTip(_translate("MultipleViewWidget", "List of Open Flighttracks.\n" "Check box to activate and display track on topview.")) self.list_operation_track.setToolTip(_translate("MultipleViewWidget", "List of Mscolab Operations.\n" "Check box to activate and display track on topview.")) self.pushButton_color.setText(_translate("MultipleViewWidget", "Change Color")) self.labelStatus.setText(_translate("MultipleViewWidget", "Status: ")) + + +if __name__ == "__main__": + import sys + app = QtWidgets.QApplication(sys.argv) + MultipleViewWidget = QtWidgets.QWidget() + ui = Ui_MultipleViewWidget() + ui.setupUi(MultipleViewWidget) + MultipleViewWidget.show() + sys.exit(app.exec_()) diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index da49e4076..d2aef0e64 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -194,6 +194,8 @@ class MSUITopViewWindow(MSUIMplViewWindow, ui.Ui_TopViewWindow): signal_ft_vertices_color_change = QtCore.Signal(tuple) signal_operation_added = QtCore.Signal(int, str) signal_operation_removed = QtCore.Signal(int) + signal_login_mscolab = QtCore.Signal(str, str) + signal_logout_mscolab = QtCore.Signal() def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, mscolab_server_url=None , token=None): @@ -228,9 +230,6 @@ def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, m self.mscolab_server_url = mscolab_server_url self.token = token - # - self.ft_vertices_color = None - # Connect slots and signals. # ========================== @@ -346,13 +345,15 @@ def openTool(self, index): widget = ad.AirdataDockwidget(parent=self, view=self.mpl.canvas) elif index == MULTIPLEFLIGHTPATH: title = "Multiple Flightpath" - self.load_ft_vertices_color() widget = mf.MultipleFlightpathControlWidget(parent=self, view=self.mpl.canvas, listFlightTracks=self.ui.listFlightTracks, listOperationsMSC=self.ui.listOperationsMSC, activeFlightTrack=self.active_flighttrack, mscolab_server_url=self.mscolab_server_url, - token=self.token, color=self.ft_vertices_color) + token=self.token) + + self.ui.signal_login_mscolab.connect(lambda d, t: self.signal_login_mscolab.emit(d, t)) + self.ui.signal_logout_mscolab.connect(lambda: self.signal_logout_mscolab.emit()) self.signal_activate_operation.emit(self.active_op_id) else: raise IndexError("invalid control index") @@ -467,6 +468,5 @@ def is_roundtrip_possible(self): def update_roundtrip_enabled(self): self.btRoundtrip.setEnabled(self.is_roundtrip_possible()) - def load_ft_vertices_color(self): - settings = load_settings_qsettings(self.settings_tag, {}) - self.ft_vertices_color = settings["colour_ft_vertices"] + def get_settings(self): + return load_settings_qsettings(self.settings_tag, {}) diff --git a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui index db7854483..373308095 100644 --- a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui +++ b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui @@ -6,7 +6,7 @@ 0 0 - 544 + 778 235 @@ -20,6 +20,50 @@ Form + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + + + 0 + 0 + + + + (Color shown before flighttracks/operations are only visible in "deactivated" state) 𝐀𝐜𝐭𝐢𝐯𝐚𝐭𝐞𝐝 𝐓𝐫𝐚𝐜𝐤 𝐕𝐞𝐫𝐭𝐢𝐜𝐞𝐬 𝐂𝐨𝐥𝐨𝐫 : + + + + + + + + 0 + 0 + + + + + + + + + + From da3cd005df4a2e30385f936489e44d600a557232 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sun, 6 Nov 2022 09:30:39 +0530 Subject: [PATCH 20/33] signals_disconnected_after_logout --- mslib/msui/mscolab.py | 8 ++++++-- mslib/msui/msui.py | 2 ++ mslib/msui/multiple_flightpath_dockwidget.py | 13 ++++++++++--- mslib/msui/topview.py | 17 ++++++++++++++++- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/mslib/msui/mscolab.py b/mslib/msui/mscolab.py index 8e35cab0e..bfee31c4a 100644 --- a/mslib/msui/mscolab.py +++ b/mslib/msui/mscolab.py @@ -419,6 +419,7 @@ class MSUIMscolab(QtCore.QObject): signal_operation_removed = QtCore.Signal(int, name="signal_operation_removed") signal_login_mscolab = QtCore.Signal(str, str, name="signal_login_mscolab") signal_logout_mscolab = QtCore.Signal(name="signal_logout_mscolab") + signal_listFlighttrack_doubleClicked = QtCore.Signal() def __init__(self, parent=None, data_dir=None): super(MSUIMscolab, self).__init__(parent) @@ -435,8 +436,7 @@ def __init__(self, parent=None, data_dir=None): self.ui.activeOperationDesc.setHidden(True) # reset operation description label for flight tracks and open views - self.ui.listFlightTracks.itemDoubleClicked.connect( - lambda: self.ui.activeOperationDesc.setText("Select Operation to View Description.")) + self.ui.listFlightTracks.itemDoubleClicked.connect(self.listFlighttrack_itemDoubleClicked) self.ui.listViews.itemDoubleClicked.connect( lambda: self.ui.activeOperationDesc.setText("Select Operation to View Description.")) @@ -1775,6 +1775,10 @@ def handle_export_msc(self, extension, function, pickertype): show_popup(self.ui, "Error", "Your Connection is expired. New Login required!") self.logout() + def listFlighttrack_itemDoubleClicked(self): + self.ui.activeOperationDesc.setText("Select Operation to View Description.") + self.signal_listFlighttrack_doubleClicked.emit() + def logout(self): if self.mscolab_server_url is None: return diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index 5215af62e..907d53093 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -343,6 +343,7 @@ class MSUIMainWindow(QtWidgets.QMainWindow, ui.Ui_MSUIMainWindow): signal_operation_removed = QtCore.Signal(int, name="signal_operation_removed") signal_login_mscolab = QtCore.Signal(str, str, name="signal_login_mscolab") signal_logout_mscolab = QtCore.Signal(name="signal_logout_mscolab") + signal_listFlighttrack_doubleClicked = QtCore.Signal() def __init__(self, mscolab_data_dir=None, *args): super(MSUIMainWindow, self).__init__(*args) @@ -438,6 +439,7 @@ def __init__(self, mscolab_data_dir=None, *args): self.mscolab.signal_operation_removed.connect(self.remove_operation_slot) self.mscolab.signal_login_mscolab.connect(lambda d, t: self.signal_login_mscolab.emit(d, t)) self.mscolab.signal_logout_mscolab.connect(lambda: self.signal_logout_mscolab.emit()) + self.mscolab.signal_listFlighttrack_doubleClicked.connect(lambda: self.signal_listFlighttrack_doubleClicked.emit()) # Don't start the updater during a test run of msui if "pytest" not in sys.modules: diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 6559f6564..f80ef6cc3 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -112,6 +112,8 @@ class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidge # ToDO: Make a new parent class with all the functions in this class and inherit them # in MultipleFlightpathControlWidget and MultipleFlightpathOperations classes. + signal_parent_closes = QtCore.Signal() + def __init__(self, parent=None, view=None, listFlightTracks=None, listOperationsMSC=None, activeFlightTrack=None, mscolab_server_url=None, token=None): super(MultipleFlightpathControlWidget, self).__init__(parent) @@ -155,6 +157,9 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, if self.mscolab_server_url is not None: self.connect_mscolab_server() + if parent is not None: + parent.viewCloses.connect(lambda: self.signal_parent_closes.emit()) + # Load flighttracks for index in range(self.listFlightTracks.count()): wp_model = self.listFlightTracks.item(index).flighttrack_model @@ -165,6 +170,7 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, @QtCore.Slot() def logout(self): self.operations.logout_mscolab() + self.ui.signal_listFlighttrack_doubleClicked.disconnect() for idx in range(len(self.obb)): del self.obb[idx] @@ -186,12 +192,12 @@ def connect_mscolab_server(self): self.ui.signal_operation_removed.connect(self.remove_operation_slot) # deactivate vice versa selection of Operation or Flight Track - self.listFlightTracks.itemClicked.connect(lambda: self.list_operation_track.setCurrentItem(None)) - self.listOperationsMSC.itemClicked.connect(lambda: self.list_flighttrack.setCurrentItem(None)) + self.list_flighttrack.itemClicked.connect(lambda: self.list_operation_track.setCurrentItem(None)) + self.list_operation_track.itemClicked.connect(lambda: self.list_flighttrack.setCurrentItem(None)) # deactivate operation or flighttrack self.listOperationsMSC.itemDoubleClicked.connect(self.deactivate_all_flighttracks) - self.listFlightTracks.itemDoubleClicked.connect(self.operations.deactivate_all_operations) + self.ui.signal_listFlighttrack_doubleClicked.connect(self.operations.deactivate_all_operations) # Mscolab Server logout signal self.ui.signal_logout_mscolab.connect(self.logout) @@ -727,6 +733,7 @@ def logout_mscolab(self): self.list_operation_track.takeItem(0) a -= 1 + self.list_operation_track.itemChanged.disconnect() self.mscolab_server_url = None self.token = None self.dict_operations = {} diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index d2aef0e64..af1682f3f 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -196,6 +196,7 @@ class MSUITopViewWindow(MSUIMplViewWindow, ui.Ui_TopViewWindow): signal_operation_removed = QtCore.Signal(int) signal_login_mscolab = QtCore.Signal(str, str) signal_logout_mscolab = QtCore.Signal() + signal_listFlighttrack_doubleClicked = QtCore.Signal() def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, mscolab_server_url=None , token=None): @@ -253,6 +254,8 @@ def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, m self.ui.signal_operation_added.connect(self.add_operation_slot) self.ui.signal_operation_removed.connect(self.remove_operation_slot) + self.ui.signal_login_mscolab.connect(self.login) + def __del__(self): del self.mpl.canvas.waypoints_interactor @@ -277,6 +280,12 @@ def add_operation_slot(self, op_id, path): def remove_operation_slot(self, op_id): self.signal_operation_removed.emit(op_id) + @QtCore.Slot(str, str) + def login(self, mscolab_server_url, token): + self.mscolab_server_url = mscolab_server_url + self.token = token + self.signal_login_mscolab.emit(mscolab_server_url, token) + def setup_top_view(self): """ Initialise GUI elements. (This method is called before signals/slots @@ -352,15 +361,21 @@ def openTool(self, index): mscolab_server_url=self.mscolab_server_url, token=self.token) - self.ui.signal_login_mscolab.connect(lambda d, t: self.signal_login_mscolab.emit(d, t)) self.ui.signal_logout_mscolab.connect(lambda: self.signal_logout_mscolab.emit()) + self.ui.signal_listFlighttrack_doubleClicked.connect(lambda: self.signal_listFlighttrack_doubleClicked.emit()) self.signal_activate_operation.emit(self.active_op_id) + widget.signal_parent_closes.connect(self.closed) else: raise IndexError("invalid control index") # Create the actual dock widget containing . self.createDockWidget(index, title, widget) + def closed(self): + self.ui.signal_login_mscolab.disconnect() + self.ui.signal_logout_mscolab.disconnect() + self.ui.signal_listFlighttrack_doubleClicked.disconnect() + @QtCore.Slot() def disable_cbs(self): self.wms_connected = True From 94ac7b3b8e35ce80d1a4440faf1367d0c1bbb534 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sun, 6 Nov 2022 10:24:47 +0530 Subject: [PATCH 21/33] update_last_used_operation --- mslib/msui/multiple_flightpath_dockwidget.py | 12 ++++++++---- mslib/msui/topview.py | 6 ++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index f80ef6cc3..ae328771a 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -24,8 +24,6 @@ See the License for the specific language governing permissions and limitations under the License. """ -import logging - from PyQt5 import QtWidgets, QtGui, QtCore from mslib.msui.qt5 import ui_multiple_flightpath_dockwidget as ui from mslib.msui import flighttrack as ft @@ -34,7 +32,6 @@ import threading import requests import json -import gc class QMscolabOperationsListWidgetItem(QtWidgets.QListWidgetItem): @@ -199,7 +196,7 @@ def connect_mscolab_server(self): self.listOperationsMSC.itemDoubleClicked.connect(self.deactivate_all_flighttracks) self.ui.signal_listFlighttrack_doubleClicked.connect(self.operations.deactivate_all_operations) - # Mscolab Server logout signal + # Mscolab Server logout self.ui.signal_logout_mscolab.connect(self.logout) def update(self): @@ -603,6 +600,10 @@ def activate_operation(self): self.set_activate_flag() listItem.setFont(font) + def save_last_used_operation(self, op_id): + if self.active_op_id is not None: + self.save_operation_data(op_id, self.load_wps_from_server(self.active_op_id)) + def draw_inactive_operations(self): """ Draw flighttracks of inactive operations. @@ -625,6 +626,9 @@ def draw_inactive_operations(self): self.dict_operations[listItem.op_id]["patch"] = patch def get_op_id(self, op_id): + if self.active_op_id is not None: + tmp = self.active_op_id + self.save_last_used_operation(tmp) self.active_op_id = op_id self.activate_operation() diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index af1682f3f..d7bc83105 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -270,7 +270,7 @@ def update_active_flighttrack(self, active_flighttrack): @QtCore.Slot(int) def update_active_operation(self, active_op_id): self.active_op_id = active_op_id - self.signal_activate_operation.emit(active_op_id) + self.signal_activate_operation.emit(self.active_op_id) @QtCore.Slot(int, str) def add_operation_slot(self, op_id, path): @@ -363,7 +363,8 @@ def openTool(self, index): self.ui.signal_logout_mscolab.connect(lambda: self.signal_logout_mscolab.emit()) self.ui.signal_listFlighttrack_doubleClicked.connect(lambda: self.signal_listFlighttrack_doubleClicked.emit()) - self.signal_activate_operation.emit(self.active_op_id) + if self.active_op_id is not None: + self.signal_activate_operation.emit(self.active_op_id) widget.signal_parent_closes.connect(self.closed) else: raise IndexError("invalid control index") @@ -375,6 +376,7 @@ def closed(self): self.ui.signal_login_mscolab.disconnect() self.ui.signal_logout_mscolab.disconnect() self.ui.signal_listFlighttrack_doubleClicked.disconnect() + self.ui.signal_activate_operation.disconnect() @QtCore.Slot() def disable_cbs(self): From 85206ee99f2ad8866f36f6f1265f27f72b7df384 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sun, 6 Nov 2022 15:54:03 +0530 Subject: [PATCH 22/33] fixed_test --- mslib/msui/topview.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index d7bc83105..b740ccda1 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -247,14 +247,15 @@ def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, m # Tool opener. self.cbTools.currentIndexChanged.connect(self.openTool) - # Update flighttrack - self.ui.signal_activate_flighttrack.connect(self.update_active_flighttrack) - self.ui.signal_activate_operation.connect(self.update_active_operation) + if parent is not None: + # Update flighttrack + self.ui.signal_activate_flighttrack.connect(self.update_active_flighttrack) + self.ui.signal_activate_operation.connect(self.update_active_operation) - self.ui.signal_operation_added.connect(self.add_operation_slot) - self.ui.signal_operation_removed.connect(self.remove_operation_slot) + self.ui.signal_operation_added.connect(self.add_operation_slot) + self.ui.signal_operation_removed.connect(self.remove_operation_slot) - self.ui.signal_login_mscolab.connect(self.login) + self.ui.signal_login_mscolab.connect(self.login) def __del__(self): del self.mpl.canvas.waypoints_interactor From 4b7da8ab8cddb68f29a62464bdab4f0f71519e88 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sun, 6 Nov 2022 20:22:44 +0530 Subject: [PATCH 23/33] fixed_color --- mslib/msui/multiple_flightpath_dockwidget.py | 45 +++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index ae328771a..f100451d5 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -129,7 +129,7 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, self.obb = [] self.operation_list = False - self.flighttrack_list = False + self.flighttrack_list = True # Set flags self.flighttrack_added = False @@ -240,14 +240,14 @@ def ft_vertices_color(self, color): self.color = color self.colorPixmap.setPixmap(self.show_color_pixmap(color)) - if self.flighttrack_list: + if self.list_flighttrack.currentItem() is not None: self.dict_flighttrack[self.active_flight_track]["color"] = color for index in range(self.list_flighttrack.count()): if self.list_flighttrack.item(index).flighttrack_model == self.active_flight_track: self.list_flighttrack.item(index).setIcon( self.show_color_icon(self.get_color(self.active_flight_track))) break - else: + elif self.list_operation_track.currentItem() is not None: self.operations.ft_color_update(color) @QtCore.Slot(int, str) @@ -310,26 +310,27 @@ def select_color(self): # the check mark for enabled, but can't be changed (disabled). At the moment # the dockingwidget is closed the button and checkmark has to become activated again. - if self.operation_list: + if self.list_flighttrack.currentItem() is not None: + if (hasattr(self.list_flighttrack.currentItem(), "checkState")) and ( + self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): + wp_model = self.list_flighttrack.currentItem().flighttrack_model + if wp_model == self.active_flight_track: + self.error_dialog = QtWidgets.QErrorMessage() + self.error_dialog.showMessage('Use "options" to change color of an activated flighttrack.') + else: + color = QtWidgets.QColorDialog.getColor() + if color.isValid(): + self.dict_flighttrack[wp_model]["color"] = color.getRgbF() + self.color_change = True + self.list_flighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) + self.dict_flighttrack[wp_model]["patch"].update(color= + self.dict_flighttrack[wp_model]["color"]) + else: + self.labelStatus.setText("Check Mark the flighttrack to change its color.") + elif self.list_operation_track.currentItem() is not None: self.operations.select_color() else: - if self.list_flighttrack.currentItem() is not None: - if (hasattr(self.list_flighttrack.currentItem(), "checkState")) and ( - self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): - wp_model = self.list_flighttrack.currentItem().flighttrack_model - if wp_model == self.active_flight_track: - self.error_dialog = QtWidgets.QErrorMessage() - self.error_dialog.showMessage('Use "options" to change color of an activated flighttrack.') - else: - color = QtWidgets.QColorDialog.getColor() - if color.isValid(): - self.dict_flighttrack[wp_model]["color"] = color.getRgbF() - self.color_change = True - self.list_flighttrack.currentItem().setIcon(self.show_color_icon(self.get_color(wp_model))) - self.dict_flighttrack[wp_model]["patch"].update(color= - self.dict_flighttrack[wp_model]["color"]) - else: - self.labelStatus.setText("Status: No flight track selected") + self.labelStatus.setText("Status: No flight track selected") def get_color(self, wp_model): """ @@ -704,6 +705,8 @@ def select_color(self): self.list_operation_track.currentItem().setIcon(self.show_color_icon(self.get_color(op_id))) self.dict_operations[op_id]["patch"].update(color= self.dict_operations[op_id]["color"]) + else: + self.parent.labelStatus.setText("Check Mark the Operation to change color.") def get_color(self, op_id): """ From 9fe8fc7986dbf7b848ffaffa8ad195f780b099f1 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sun, 6 Nov 2022 21:00:05 +0530 Subject: [PATCH 24/33] implemented_operation_permission_revoked --- mslib/msui/mscolab.py | 2 ++ mslib/msui/multiple_flightpath_dockwidget.py | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/mslib/msui/mscolab.py b/mslib/msui/mscolab.py index bfee31c4a..68c0d16a9 100644 --- a/mslib/msui/mscolab.py +++ b/mslib/msui/mscolab.py @@ -420,6 +420,7 @@ class MSUIMscolab(QtCore.QObject): signal_login_mscolab = QtCore.Signal(str, str, name="signal_login_mscolab") signal_logout_mscolab = QtCore.Signal(name="signal_logout_mscolab") signal_listFlighttrack_doubleClicked = QtCore.Signal() + signal_permission_revoked = QtCore.Signal(int) def __init__(self, parent=None, data_dir=None): super(MSUIMscolab, self).__init__(parent) @@ -1393,6 +1394,7 @@ def handle_revoke_permission(self, op_id, u_id): # on import permissions revoked name can not taken from the operation list, # because we update the list first by reloading it. show_popup(self.ui, "Permission Revoked", "Access to an operation was revoked") + self.signal_permission_revoked.emit(op_id) @QtCore.Slot(int) def handle_operation_deleted(self, op_id): diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index f100451d5..6ab998237 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -168,6 +168,7 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, def logout(self): self.operations.logout_mscolab() self.ui.signal_listFlighttrack_doubleClicked.disconnect() + self.ui.signal_permission_revoked.disconnect() for idx in range(len(self.obb)): del self.obb[idx] @@ -183,6 +184,7 @@ def connect_mscolab_server(self): self.listOperationsMSC, self.view) self.obb.append(self.operations) + self.ui.signal_permission_revoked.connect(lambda op_id: self.operations.permission_revoked(op_id)) # Signal emitted, on activation of operation from MSUI self.ui.signal_activate_operation.connect(self.update_op_id) self.ui.signal_operation_added.connect(self.add_operation_slot) @@ -744,3 +746,7 @@ def logout_mscolab(self): self.mscolab_server_url = None self.token = None self.dict_operations = {} + + @QtCore.Slot(int) + def permission_revoked(self, op_id): + self.operationRemoved(op_id) From 303dfe0daacddf1025ebd31722cdf291032f3e8a Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Sun, 6 Nov 2022 21:49:07 +0530 Subject: [PATCH 25/33] revoked_mscolab_permission --- mslib/msui/mscolab.py | 2 ++ mslib/msui/msui.py | 5 +++++ mslib/msui/multiple_flightpath_dockwidget.py | 6 ++++++ mslib/msui/topview.py | 6 ++++++ 4 files changed, 19 insertions(+) diff --git a/mslib/msui/mscolab.py b/mslib/msui/mscolab.py index 68c0d16a9..ee93b07b5 100644 --- a/mslib/msui/mscolab.py +++ b/mslib/msui/mscolab.py @@ -421,6 +421,7 @@ class MSUIMscolab(QtCore.QObject): signal_logout_mscolab = QtCore.Signal(name="signal_logout_mscolab") signal_listFlighttrack_doubleClicked = QtCore.Signal() signal_permission_revoked = QtCore.Signal(int) + signal_render_new_permission = QtCore.Signal(int, str) def __init__(self, parent=None, data_dir=None): super(MSUIMscolab, self).__init__(parent) @@ -1312,6 +1313,7 @@ def render_new_permission(self, op_id, u_id): widgetItem.access_level = operation["access_level"] widgetItem.active_operation_desc = operation["description"] self.ui.listOperationsMSC.addItem(widgetItem) + self.signal_render_new_permission.emit(operation["op_id"], operation["path"]) if self.chat_window is not None: self.chat_window.load_users() else: diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index 907d53093..d5ee47745 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -344,6 +344,8 @@ class MSUIMainWindow(QtWidgets.QMainWindow, ui.Ui_MSUIMainWindow): signal_login_mscolab = QtCore.Signal(str, str, name="signal_login_mscolab") signal_logout_mscolab = QtCore.Signal(name="signal_logout_mscolab") signal_listFlighttrack_doubleClicked = QtCore.Signal() + signal_permission_revoked = QtCore.Signal(int) + signal_render_new_permission = QtCore.Signal(int, str) def __init__(self, mscolab_data_dir=None, *args): super(MSUIMainWindow, self).__init__(*args) @@ -440,6 +442,8 @@ def __init__(self, mscolab_data_dir=None, *args): self.mscolab.signal_login_mscolab.connect(lambda d, t: self.signal_login_mscolab.emit(d, t)) self.mscolab.signal_logout_mscolab.connect(lambda: self.signal_logout_mscolab.emit()) self.mscolab.signal_listFlighttrack_doubleClicked.connect(lambda: self.signal_listFlighttrack_doubleClicked.emit()) + self.mscolab.signal_permission_revoked.connect(lambda op_id: self.signal_permission_revoked.emit(op_id)) + self.mscolab.signal_render_new_permission.connect(lambda op_id, path: self.signal_render_new_permission.emit(op_id, path)) # Don't start the updater during a test run of msui if "pytest" not in sys.modules: @@ -780,6 +784,7 @@ def save_as_handler(self): self.save_flight_track(filename) self.active_flight_track.filename = filename self.active_flight_track.name = fs.path.basename(filename.replace(f"{ext}", "").strip()) + self.signal_saveas_flighttrack.emit(filename) def save_flight_track(self, file_name): ext = ".ftml" diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 6ab998237..17c5f7a22 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -169,6 +169,7 @@ def logout(self): self.operations.logout_mscolab() self.ui.signal_listFlighttrack_doubleClicked.disconnect() self.ui.signal_permission_revoked.disconnect() + self.ui.signal_render_new_permission.disconnect() for idx in range(len(self.obb)): del self.obb[idx] @@ -185,6 +186,7 @@ def connect_mscolab_server(self): self.obb.append(self.operations) self.ui.signal_permission_revoked.connect(lambda op_id: self.operations.permission_revoked(op_id)) + self.ui.signal_render_new_permission.connect(lambda op_id, path: self.operations.render_permission(op_id, path)) # Signal emitted, on activation of operation from MSUI self.ui.signal_activate_operation.connect(self.update_op_id) self.ui.signal_operation_added.connect(self.add_operation_slot) @@ -750,3 +752,7 @@ def logout_mscolab(self): @QtCore.Slot(int) def permission_revoked(self, op_id): self.operationRemoved(op_id) + + @QtCore.Slot(int, str) + def render_permission(self, op_id, path): + self.operationsAdded(op_id, path) diff --git a/mslib/msui/topview.py b/mslib/msui/topview.py index b740ccda1..814dd1584 100644 --- a/mslib/msui/topview.py +++ b/mslib/msui/topview.py @@ -197,6 +197,8 @@ class MSUITopViewWindow(MSUIMplViewWindow, ui.Ui_TopViewWindow): signal_login_mscolab = QtCore.Signal(str, str) signal_logout_mscolab = QtCore.Signal() signal_listFlighttrack_doubleClicked = QtCore.Signal() + signal_permission_revoked = QtCore.Signal(int) + signal_render_new_permission = QtCore.Signal(int, str) def __init__(self, parent=None, model=None, _id=None, active_flighttrack=None, mscolab_server_url=None , token=None): @@ -364,6 +366,8 @@ def openTool(self, index): self.ui.signal_logout_mscolab.connect(lambda: self.signal_logout_mscolab.emit()) self.ui.signal_listFlighttrack_doubleClicked.connect(lambda: self.signal_listFlighttrack_doubleClicked.emit()) + self.ui.signal_permission_revoked.connect(lambda op_id: self.signal_permission_revoked.emit(op_id)) + self.ui.signal_render_new_permission.connect(lambda op_id, path: self.signal_render_new_permission.emit(op_id, path)) if self.active_op_id is not None: self.signal_activate_operation.emit(self.active_op_id) widget.signal_parent_closes.connect(self.closed) @@ -378,6 +382,8 @@ def closed(self): self.ui.signal_logout_mscolab.disconnect() self.ui.signal_listFlighttrack_doubleClicked.disconnect() self.ui.signal_activate_operation.disconnect() + self.ui.signal_permission_revoked.disconnect() + self.ui.signal_render_new_permission.disconnect() @QtCore.Slot() def disable_cbs(self): From 1526358489bfa827a491716d1cc9b5603a849d56 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Mon, 7 Nov 2022 01:18:01 +0530 Subject: [PATCH 26/33] change_operations_linewidth --- mslib/msui/multiple_flightpath_dockwidget.py | 77 ++++++++++++++++---- 1 file changed, 64 insertions(+), 13 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 17c5f7a22..d9955508f 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -151,6 +151,8 @@ def __init__(self, parent=None, view=None, listFlightTracks=None, self.colorPixmap.setPixmap(self.show_color_pixmap(self.color)) + self.list_flighttrack.itemClicked.connect(self.listFlighttrack_itemClicked) + if self.mscolab_server_url is not None: self.connect_mscolab_server() @@ -193,8 +195,7 @@ def connect_mscolab_server(self): self.ui.signal_operation_removed.connect(self.remove_operation_slot) # deactivate vice versa selection of Operation or Flight Track - self.list_flighttrack.itemClicked.connect(lambda: self.list_operation_track.setCurrentItem(None)) - self.list_operation_track.itemClicked.connect(lambda: self.list_flighttrack.setCurrentItem(None)) + self.list_operation_track.itemClicked.connect(self.operations.listOperations_itemClicked) # deactivate operation or flighttrack self.listOperationsMSC.itemDoubleClicked.connect(self.deactivate_all_flighttracks) @@ -362,17 +363,20 @@ def set_linewidth(self): if (hasattr(self.list_flighttrack.currentItem(), "checkState")) and ( self.list_flighttrack.currentItem().checkState() == QtCore.Qt.Checked): wp_model = self.list_flighttrack.currentItem().flighttrack_model - if self.dict_flighttrack[wp_model]["linewidth"] != self.dsbx_linewidth.value(): - self.dict_flighttrack[wp_model]["linewidth"] = self.dsbx_linewidth.value() - - self.dict_flighttrack[wp_model]["patch"].remove() - self.dict_flighttrack[wp_model]["patch"].update( - self.dict_flighttrack[wp_model]["linewidth"], self.dict_flighttrack[wp_model]["color"] - ) - self.change_linewidth = True - self.dsbx_linewidth.setValue(self.dict_flighttrack[wp_model]["linewidth"]) + if wp_model != self.active_flight_track: + if self.dict_flighttrack[wp_model]["linewidth"] != self.dsbx_linewidth.value(): + self.dict_flighttrack[wp_model]["linewidth"] = self.dsbx_linewidth.value() + + self.dict_flighttrack[wp_model]["patch"].remove() + self.dict_flighttrack[wp_model]["patch"].update( + self.dict_flighttrack[wp_model]["linewidth"], self.dict_flighttrack[wp_model]["color"] + ) + self.change_linewidth = True + self.dsbx_linewidth.setValue(self.dict_flighttrack[wp_model]["linewidth"]) else: self.labelStatus.setText("Status: No flight track selected") + elif self.list_operation_track.currentItem() is not None: + self.operations.set_linewidth() else: self.labelStatus.setText("Status: No flight track selected") @@ -477,6 +481,19 @@ def set_listControl(self, operation, flighttrack): def get_ft_vertices_color(self): return self.color + def listFlighttrack_itemClicked(self): + if self.list_operation_track.currentItem() is not None: + self.list_operation_track.setCurrentItem(None) + + if self.list_flighttrack.currentItem() is not None: + wp_model = self.list_flighttrack.currentItem().flighttrack_model + self.dsbx_linewidth.setValue(self.dict_flighttrack[wp_model]["linewidth"]) + + if self.list_flighttrack.currentItem().flighttrack_model == self.active_flight_track: + self.frame.hide() + else: + self.frame.show() + class MultipleFlightpathOperations: """ @@ -566,6 +583,7 @@ def create_operation(self, op_id, wp_model): self.dict_operations[op_id] = {} self.dict_operations[op_id]["patch"] = None self.dict_operations[op_id]["wp_data"] = None + self.dict_operations[op_id]["linewidth"] = 2 self.dict_operations[op_id]["color"] = self.parent.get_ft_vertices_color() self.save_operation_data(op_id, wp_model) @@ -626,7 +644,8 @@ def draw_inactive_operations(self): patch = MultipleFlightpath(self.view.map, self.dict_operations[listItem.op_id][ "wp_data"], - color=self.dict_operations[listItem.op_id]["color"]) + color=self.dict_operations[listItem.op_id]["color"], + linewidth=self.dict_operations[listItem.op_id]["linewidth"]) self.dict_operations[listItem.op_id]["patch"] = patch @@ -708,7 +727,8 @@ def select_color(self): self.color_change = True self.list_operation_track.currentItem().setIcon(self.show_color_icon(self.get_color(op_id))) self.dict_operations[op_id]["patch"].update(color= - self.dict_operations[op_id]["color"]) + self.dict_operations[op_id]["color"], linewidth= + self.dict_operations[op_id]["linewidth"]) else: self.parent.labelStatus.setText("Check Mark the Operation to change color.") @@ -756,3 +776,34 @@ def permission_revoked(self, op_id): @QtCore.Slot(int, str) def render_permission(self, op_id, path): self.operationsAdded(op_id, path) + + def set_linewidth(self): + if (hasattr(self.list_operation_track.currentItem(), "checkState")) and ( + self.list_operation_track.currentItem().checkState() == QtCore.Qt.Checked): + op_id = self.list_operation_track.currentItem().op_id + if op_id != self.active_op_id: + self.parent.frame.show() + if self.dict_operations[op_id]["linewidth"] != self.parent.dsbx_linewidth.value(): + self.dict_operations[op_id]["linewidth"] = self.parent.dsbx_linewidth.value() + + self.dict_operations[op_id]["patch"].remove() + self.dict_operations[op_id]["patch"].update( + self.dict_operations[op_id]["linewidth"], self.dict_operations[op_id]["color"] + ) + self.change_linewidth = True + self.parent.dsbx_linewidth.setValue(self.dict_operations[op_id]["linewidth"]) + + def listOperations_itemClicked(self): + if self.parent.list_flighttrack.currentItem() is not None: + self.parent.list_flighttrack.setCurrentItem(None) + + if self.list_operation_track.currentItem() is not None: + op_id = self.list_operation_track.currentItem().op_id + self.parent.dsbx_linewidth.setValue(self.dict_operations[op_id]["linewidth"]) + + if self.list_operation_track.currentItem().op_id == self.active_op_id: + self.parent.frame.hide() + + else: + self.parent.frame.show() + From b93a3c5b848a3cfb04e18543eb1bbb2bc89ee69c Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Mon, 7 Nov 2022 03:02:07 +0530 Subject: [PATCH 27/33] fixed_uncheck_operations --- mslib/msui/multiple_flightpath_dockwidget.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index d9955508f..d926adb94 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -456,14 +456,8 @@ def deactivate_all_flighttracks(self): for index in range(self.list_flighttrack.count()): listItem = self.list_flighttrack.item(index) - if self.dict_flighttrack[listItem.flighttrack_model]["patch"] is not None: - self.dict_flighttrack[listItem.flighttrack_model]["patch"].remove() - self.set_listControl(True, False) - # Uncheck all flighttracks - self.set_activate_flag() - listItem.setCheckState(QtCore.Qt.Unchecked) self.set_activate_flag() listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) @@ -678,6 +672,7 @@ def operationRemoved(self, op_id): else: self.dict_operations[self.list_operation_track.item(index).op_id]["patch"].remove() self.list_operation_track.takeItem(index) + self.active_op_id = None break def set_activate_flag(self): @@ -691,14 +686,8 @@ def deactivate_all_operations(self): for index in range(self.listOperationsMSC.count()): listItem = self.list_operation_track.item(index) - if self.dict_operations[listItem.op_id]["patch"] is not None: - self.dict_operations[listItem.op_id]["patch"].remove() - self.parent.set_listControl(False, True) - # Uncheck all operations - self.set_activate_flag() - listItem.setCheckState(QtCore.Qt.Unchecked) self.set_activate_flag() listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) From e067250a45881fa63eec5344d361eee08a42ca95 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Mon, 7 Nov 2022 04:33:50 +0530 Subject: [PATCH 28/33] remove_filter_flightpaths_test --- .github/workflows/testing-develop.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/testing-develop.yml b/.github/workflows/testing-develop.yml index 8208175a3..2d8787364 100644 --- a/.github/workflows/testing-develop.yml +++ b/.github/workflows/testing-develop.yml @@ -31,13 +31,3 @@ jobs: secrets: PAT: ${{ secrets.PAT }} - test-filter-flight-paths: - uses: - ./.github/workflows/testing.yml - with: - xdist: no - branch_name: filter_flight_paths - event_name: ${{ github.event_name }} - secrets: - PAT: ${{ secrets.PAT }} - From befa591d6ed6922a4d2b60d6d61e1dfd267bb284 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Mon, 7 Nov 2022 20:12:03 +0530 Subject: [PATCH 29/33] color_change_updated --- mslib/msui/multiple_flightpath_dockwidget.py | 6 ++++-- .../msui/qt5/ui_multiple_flightpath_dockwidget.py | 14 ++------------ mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui | 4 ++-- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index d926adb94..8fb3e0ec4 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -408,6 +408,7 @@ def activate_flighttrack(self): for i in range(self.list_flighttrack.count()): listItem = self.list_flighttrack.item(i) if self.active_flight_track == listItem.flighttrack_model: # active flighttrack + listItem.setIcon(self.show_color_icon(self.color)) font.setBold(True) if self.dict_flighttrack[listItem.flighttrack_model]["patch"] is not None: self.dict_flighttrack[listItem.flighttrack_model]["patch"].remove() @@ -416,6 +417,7 @@ def activate_flighttrack(self): self.set_activate_flag() listItem.setFlags(listItem.flags() & ~QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: + listItem.setIcon(self.show_color_icon(self.get_color(listItem.flighttrack_model))) font.setBold(False) listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) self.set_activate_flag() @@ -604,6 +606,7 @@ def activate_operation(self): for i in range(self.list_operation_track.count()): listItem = self.list_operation_track.item(i) if self.active_op_id == listItem.op_id: # active operation + listItem.setIcon(self.show_color_icon(self.parent.color)) font.setBold(True) if self.dict_operations[listItem.op_id]["patch"] is not None: self.dict_operations[listItem.op_id]["patch"].remove() @@ -612,6 +615,7 @@ def activate_operation(self): self.set_activate_flag() listItem.setFlags(listItem.flags() & ~QtCore.Qt.ItemIsUserCheckable) # make activated track uncheckable else: + listItem.setIcon(self.show_color_icon(self.get_color(listItem.op_id))) font.setBold(False) listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) self.set_activate_flag() @@ -792,7 +796,5 @@ def listOperations_itemClicked(self): if self.list_operation_track.currentItem().op_id == self.active_op_id: self.parent.frame.hide() - else: self.parent.frame.show() - diff --git a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py index 6d81c3b41..970c921d1 100644 --- a/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py +++ b/mslib/msui/qt5/ui_multiple_flightpath_dockwidget.py @@ -33,7 +33,7 @@ def setupUi(self, MultipleViewWidget): self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.frame_2) self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.ft_color_label = QtWidgets.QLabel(self.frame_2) - sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.ft_color_label.sizePolicy().hasHeightForWidth()) @@ -113,20 +113,10 @@ def setupUi(self, MultipleViewWidget): def retranslateUi(self, MultipleViewWidget): _translate = QtCore.QCoreApplication.translate MultipleViewWidget.setWindowTitle(_translate("MultipleViewWidget", "Form")) - self.ft_color_label.setText(_translate("MultipleViewWidget", "(Color shown before flighttracks/operations are only visible in \"deactivated\" state) 𝐀𝐜𝐭𝐢𝐯𝐚𝐭𝐞𝐝 𝐓𝐫𝐚𝐜𝐤 𝐕𝐞𝐫𝐭𝐢𝐜𝐞𝐬 𝐂𝐨𝐥𝐨𝐫 : ")) + self.ft_color_label.setText(_translate("MultipleViewWidget", "𝐀𝐜𝐭𝐢𝐯𝐚𝐭𝐞𝐝 𝐓𝐫𝐚𝐜𝐤 𝐕𝐞𝐫𝐭𝐢𝐜𝐞𝐬 𝐂𝐨𝐥𝐨𝐫 : ")) self.list_flighttrack.setToolTip(_translate("MultipleViewWidget", "List of Open Flighttracks.\n" "Check box to activate and display track on topview.")) self.list_operation_track.setToolTip(_translate("MultipleViewWidget", "List of Mscolab Operations.\n" "Check box to activate and display track on topview.")) self.pushButton_color.setText(_translate("MultipleViewWidget", "Change Color")) self.labelStatus.setText(_translate("MultipleViewWidget", "Status: ")) - - -if __name__ == "__main__": - import sys - app = QtWidgets.QApplication(sys.argv) - MultipleViewWidget = QtWidgets.QWidget() - ui = Ui_MultipleViewWidget() - ui.setupUi(MultipleViewWidget) - MultipleViewWidget.show() - sys.exit(app.exec_()) diff --git a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui index 373308095..0eeddd3c9 100644 --- a/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui +++ b/mslib/msui/ui/ui_multiple_flightpath_dockwidget.ui @@ -38,13 +38,13 @@ - + 0 0 - (Color shown before flighttracks/operations are only visible in "deactivated" state) 𝐀𝐜𝐭𝐢𝐯𝐚𝐭𝐞𝐝 𝐓𝐫𝐚𝐜𝐤 𝐕𝐞𝐫𝐭𝐢𝐜𝐞𝐬 𝐂𝐨𝐥𝐨𝐫 : + 𝐀𝐜𝐭𝐢𝐯𝐚𝐭𝐞𝐝 𝐓𝐫𝐚𝐜𝐤 𝐕𝐞𝐫𝐭𝐢𝐜𝐞𝐬 𝐂𝐨𝐥𝐨𝐫 : From c4d93d7e39b62eac1fc8456e4976dcfd3a831138 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Tue, 8 Nov 2022 00:41:53 +0530 Subject: [PATCH 30/33] removed_activation_of_operations_on_addition --- mslib/msui/multiple_flightpath_dockwidget.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 8fb3e0ec4..dba91e0ae 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -172,6 +172,7 @@ def logout(self): self.ui.signal_listFlighttrack_doubleClicked.disconnect() self.ui.signal_permission_revoked.disconnect() self.ui.signal_render_new_permission.disconnect() + self.operations = None for idx in range(len(self.obb)): del self.obb[idx] @@ -238,6 +239,8 @@ def flighttrackAdded(self, parent, start, end): """ wp_model = self.listFlightTracks.item(start).flighttrack_model listItem = self.create_list_item(wp_model) + if self.mscolab_server_url is not None: + self.operations.deactivate_all_operations() self.activate_flighttrack() @QtCore.Slot(tuple) @@ -527,8 +530,6 @@ def __init__(self, parent, mscolab_server_url, token, list_operation_track, list wp_model.name = operations["path"] self.create_operation(op_id, wp_model) - self.activate_operation() - def set_flag(self): if self.operation_added: self.operation_added = False @@ -661,8 +662,6 @@ def operationsAdded(self, op_id, path): wp_model = self.load_wps_from_server(op_id) wp_model.name = path listItem = self.create_operation(op_id, wp_model) - self.active_op_id = op_id - self.activate_operation() def operationRemoved(self, op_id): """ @@ -695,10 +694,11 @@ def deactivate_all_operations(self): self.set_activate_flag() listItem.setFlags(listItem.flags() | QtCore.Qt.ItemIsUserCheckable) - if listItem.op_id == self.active_op_id: - font = QtGui.QFont() - font.setBold(False) - listItem.setFont(font) + # if listItem.op_id == self.active_op_id: + self.set_activate_flag() + font = QtGui.QFont() + font.setBold(False) + listItem.setFont(font) self.active_op_id = None From ae6c72dd0db24436a25ff41236a253f88daf2974 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Tue, 8 Nov 2022 00:48:51 +0530 Subject: [PATCH 31/33] Update msui.py --- mslib/msui/msui.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mslib/msui/msui.py b/mslib/msui/msui.py index d5ee47745..5e934f99c 100644 --- a/mslib/msui/msui.py +++ b/mslib/msui/msui.py @@ -784,7 +784,6 @@ def save_as_handler(self): self.save_flight_track(filename) self.active_flight_track.filename = filename self.active_flight_track.name = fs.path.basename(filename.replace(f"{ext}", "").strip()) - self.signal_saveas_flighttrack.emit(filename) def save_flight_track(self, file_name): ext = ".ftml" From c26be620cfccf82a8a71be46f73b12457fa46781 Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Tue, 8 Nov 2022 01:52:14 +0530 Subject: [PATCH 32/33] fixed_tracks_coloring --- mslib/msui/multiple_flightpath_dockwidget.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index dba91e0ae..86b2f35ae 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -24,6 +24,8 @@ See the License for the specific language governing permissions and limitations under the License. """ +import logging + from PyQt5 import QtWidgets, QtGui, QtCore from mslib.msui.qt5 import ui_multiple_flightpath_dockwidget as ui from mslib.msui import flighttrack as ft @@ -173,6 +175,8 @@ def logout(self): self.ui.signal_permission_revoked.disconnect() self.ui.signal_render_new_permission.disconnect() self.operations = None + self.flighttrack_list = True + self.operation_list = False for idx in range(len(self.obb)): del self.obb[idx] @@ -248,14 +252,14 @@ def ft_vertices_color(self, color): self.color = color self.colorPixmap.setPixmap(self.show_color_pixmap(color)) - if self.list_flighttrack.currentItem() is not None: + if self.flighttrack_list: self.dict_flighttrack[self.active_flight_track]["color"] = color for index in range(self.list_flighttrack.count()): if self.list_flighttrack.item(index).flighttrack_model == self.active_flight_track: self.list_flighttrack.item(index).setIcon( self.show_color_icon(self.get_color(self.active_flight_track))) break - elif self.list_operation_track.currentItem() is not None: + elif self.operation_list: self.operations.ft_color_update(color) @QtCore.Slot(int, str) From fd4dc39167ce1c9ff04d07ea35b337642e2f1c6e Mon Sep 17 00:00:00 2001 From: Jatin Jain <72596619+Jatin2020-24@users.noreply.github.com> Date: Tue, 8 Nov 2022 02:10:07 +0530 Subject: [PATCH 33/33] add_todos --- mslib/msui/multiple_flightpath_dockwidget.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mslib/msui/multiple_flightpath_dockwidget.py b/mslib/msui/multiple_flightpath_dockwidget.py index 86b2f35ae..e895141aa 100644 --- a/mslib/msui/multiple_flightpath_dockwidget.py +++ b/mslib/msui/multiple_flightpath_dockwidget.py @@ -116,6 +116,7 @@ class MultipleFlightpathControlWidget(QtWidgets.QWidget, ui.Ui_MultipleViewWidge def __init__(self, parent=None, view=None, listFlightTracks=None, listOperationsMSC=None, activeFlightTrack=None, mscolab_server_url=None, token=None): super(MultipleFlightpathControlWidget, self).__init__(parent) + # ToDO: Remove all patches, on closing dockwidget. self.ui = parent self.setupUi(self) self.view = view # canvas