diff --git a/sohstationviewer/view/select_channels_to_show_dialog.py b/sohstationviewer/view/select_channels_to_show_dialog.py index 0d9b787eb1922358c3ad397ec23960a9f81e5794..fbbd8000d91c8fc50d3ce873d37f55dba9b6be0e 100644 --- a/sohstationviewer/view/select_channels_to_show_dialog.py +++ b/sohstationviewer/view/select_channels_to_show_dialog.py @@ -2,19 +2,10 @@ from typing import Dict, List from PySide6 import QtWidgets, QtCore from PySide6.QtWidgets import ( - QDialog, QLabel, QFrame + QDialog, QListWidget, QListWidgetItem, QAbstractItemView, QLabel, + QPushButton ) - - -def add_separation_line(layout): - """ - Add a line for separation to the given layout. - :param layout: QLayout - the layout that contains the line - """ - label = QLabel() - label.setFrameStyle(QFrame.Shape.HLine | QFrame.Shadow.Sunken) - label.setLineWidth(1) - layout.addWidget(label) +from PySide6.QtCore import Qt class SelectChanelsToShowDialog(QDialog): @@ -27,58 +18,79 @@ class SelectChanelsToShowDialog(QDialog): """ super(SelectChanelsToShowDialog, self).__init__() self.parent = parent - self.channel_checkboxes1 = self.create_chan_checkboxes( - self.parent.plotting_data1, self.parent.pref_order + + self.channel_list_widget1 = self.create_chan_list_widget( + self.parent.plotting_data1, self.parent.pref_order, True ) - self.channel_checkboxes2 = self.create_chan_checkboxes( - self.parent.plotting_data2, [] + self.channel_list_widget2 = self.create_chan_list_widget( + self.parent.plotting_data2, [], False ) - self.cancel_btn = QtWidgets.QPushButton('CANCEL', self) - self.apply_btn = QtWidgets.QPushButton('APPLY', self) + self.cancel_btn = QPushButton('CANCEL', self) + self.apply_btn = QPushButton('APPLY', self) self.setup_ui() self.connect_signals() - def create_chan_checkboxes(self, channel_dict: Dict, - pref_order: List[str]): + @staticmethod + def create_chan_list_widget(channel_dict: Dict, + pref_order: List[str], + reorderable: bool): """ Create a checkbox for each channel in channel_dict with the order - according to pref_order if any and not show the channels that aren't - plotted + according to pref_order if any. :param channel_dict: dictionary of channel data :param pref_order: list of preferred order of channels to be plotted + :param reorderable: flag for chan_list to be able to drag and drop for + reordering """ + chan_list_widget = QListWidget() chan_order = channel_dict.keys() if pref_order: chan_order = pref_order - channel_checkboxes = [] + for chan_id in chan_order: - chan_db_info = channel_dict[chan_id]['chan_db_info'] - if (chan_db_info['height'] == 0 or - chan_db_info['plotType'] == ''): + if chan_id not in channel_dict.keys(): continue - chan_chkbox = QtWidgets.QCheckBox(chan_id, self) + chan_item = QListWidgetItem(chan_id) if channel_dict[chan_id]['show']: - chan_chkbox.setChecked(True) - channel_checkboxes.append(chan_chkbox) - return channel_checkboxes + chan_item.setCheckState(Qt.CheckState.Checked) + else: + chan_item.setCheckState(Qt.CheckState.Unchecked) + chan_list_widget.addItem(chan_item) + if reorderable: + chan_list_widget.setDragDropMode( + QAbstractItemView.DragDropMode.InternalMove) + + # set height fit to content's height, not use scroll bar + chan_list_widget.verticalScrollBar().setDisabled(True) + chan_list_widget.setHorizontalScrollBarPolicy( + QtCore.Qt.ScrollBarAlwaysOff) + chan_list_widget.setVerticalScrollBarPolicy( + QtCore.Qt.ScrollBarAlwaysOff) + chan_list_widget.setFixedHeight( + chan_list_widget.count() * chan_list_widget.sizeHintForRow(0) + ) + + return chan_list_widget def setup_ui(self) -> None: - self.setWindowTitle("Select Channels to Show") + self.setWindowTitle("Show/Hide and Reorder Channels") main_layout = QtWidgets.QVBoxLayout() self.setLayout(main_layout) - for chan_chkbox in self.channel_checkboxes1: - main_layout.addWidget(chan_chkbox) - - add_separation_line(main_layout) - - for chan_chkbox in self.channel_checkboxes2: - main_layout.addWidget(chan_chkbox) + main_layout.addWidget(QLabel( + "* Check to show/ uncheck to hide a channel.\n\n" + "* Drop and drag channels in the first list to reorder." + )) + main_layout.addWidget(self.channel_list_widget1) + main_layout.addWidget(QLabel( + "* Mass Position channels won't be reorderable." + )) + main_layout.addWidget(self.channel_list_widget2) button_layout = QtWidgets.QHBoxLayout() main_layout.addLayout(button_layout) @@ -89,20 +101,41 @@ class SelectChanelsToShowDialog(QDialog): self.cancel_btn.clicked.connect(self.close) self.apply_btn.clicked.connect(self.apply) + @staticmethod + def channel_list_widget_to_plotting_data( + channel_list_widget, plotting_data): + """ + Set show value according to channel checkboxes' check state + :param channel_list_widget: the list widget that contains checkboxes + representing channels' show status + :param plotting_data: the channel dota in which channels have item show + to be modified. + :return new_pref_order: the new preferred order that channels are going + to be plotted according to. + """ + new_pref_order = [] + for row in range(channel_list_widget.count()): + chan_item = channel_list_widget.item(row) + chan_id = chan_item.text() + if chan_item.checkState() == Qt.CheckState.Checked: + plotting_data[chan_id]['show'] = True + else: + plotting_data[chan_id]['show'] = False + new_pref_order.append(chan_id) + return new_pref_order + @QtCore.Slot() def apply(self) -> None: """ Change value of key 'show' according to the selections then replot - channels in parent widget + channels in new order for plotting_data1 in parent widget """ - for chan_chkbox in self.channel_checkboxes1: - chan_id = chan_chkbox.text() - self.parent.plotting_data1[chan_id]['show'] = \ - chan_chkbox.isChecked() - for chan_chkbox in self.channel_checkboxes2: - chan_id = chan_chkbox.text() - self.parent.plotting_data2[chan_id]['show'] = \ - chan_chkbox.isChecked() + + new_pref_order = ( + self.channel_list_widget_to_plotting_data( + self.channel_list_widget1, self.parent.plotting_data1)) + self.channel_list_widget_to_plotting_data( + self.channel_list_widget2, self.parent.plotting_data2) self.parent.clear() self.parent.plot_channels( @@ -111,7 +144,7 @@ class SelectChanelsToShowDialog(QDialog): self.parent.start_tm, self.parent.end_tm, self.parent.time_ticks_total, - self.parent.pref_order) + new_pref_order) self.parent.draw() self.close()