Skip to content
Snippets Groups Projects

Fix channel prefer dialog not save

Merged Lan Dam requested to merge i222_channel_prefer_dialog_not_save into develop
1 file
+ 50
15
Compare changes
  • Side-by-side
  • Inline
from typing import Dict, List, Union
from typing import Dict, List, Union, Optional, Tuple
from pathlib import Path
from pathlib import Path
from PySide6 import QtWidgets, QtCore
from PySide6 import QtWidgets, QtCore
@@ -24,7 +24,8 @@ main window.
@@ -24,7 +24,8 @@ main window.
"""
"""
TOTAL_ROW = 20
TOTAL_ROW = 20
COL = {'sel': 0, 'name': 1, 'dataType': 2, 'IDs': 3, 'edit': 4, 'clr': 5}
COL = {'sel': 0, 'name': 1, 'dataType': 2,
 
'preferredSOHs': 3, 'edit': 4, 'clr': 5}
class InputDialog(QDialog):
class InputDialog(QDialog):
@@ -81,7 +82,8 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -81,7 +82,8 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
"""
"""
avail_data_types: list of available data types in DB
avail_data_types: list of available data types in DB
"""
"""
self.avail_data_types: List[str] = []
self.avail_data_types: List[str] = self.get_data_types(
 
include_default=False)
"""
"""
curr_row: current row
curr_row: current row
"""
"""
@@ -241,7 +243,6 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -241,7 +243,6 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
)
)
self.soh_list_table_widget.setRowCount(TOTAL_ROW)
self.soh_list_table_widget.setRowCount(TOTAL_ROW)
self.avail_data_types = self.get_data_types()
for row_idx in range(TOTAL_ROW):
for row_idx in range(TOTAL_ROW):
self.add_row(row_idx)
self.add_row(row_idx)
self.update_data_table_widget_items()
self.update_data_table_widget_items()
@@ -285,7 +286,8 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -285,7 +286,8 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
row_idx, COL['dataType'], data_type_combo_box)
row_idx, COL['dataType'], data_type_combo_box)
soh_list_item = QtWidgets.QTableWidgetItem()
soh_list_item = QtWidgets.QTableWidgetItem()
self.soh_list_table_widget.setItem(row_idx, COL['IDs'], soh_list_item)
self.soh_list_table_widget.setItem(
 
row_idx, COL['preferredSOHs'], soh_list_item)
edit_button = QtWidgets.QPushButton(self, text='EDIT')
edit_button = QtWidgets.QPushButton(self, text='EDIT')
edit_button.clicked.connect(lambda arg: self.edit_soh_list(row_idx))
edit_button.clicked.connect(lambda arg: self.edit_soh_list(row_idx))
@@ -325,7 +327,7 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -325,7 +327,7 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
self.soh_list_table_widget.cellWidget(
self.soh_list_table_widget.cellWidget(
count, COL['dataType']).setCurrentText(r['dataType'])
count, COL['dataType']).setCurrentText(r['dataType'])
self.soh_list_table_widget.item(
self.soh_list_table_widget.item(
count, COL['IDs']).setText(r['IDs'])
count, COL['preferredSOHs']).setText(r['preferredSOHs'])
if r['current'] == 1:
if r['current'] == 1:
self.curr_sel_changed(count)
self.curr_sel_changed(count)
self.soh_list_table_widget.selectRow(count)
self.soh_list_table_widget.selectRow(count)
@@ -343,7 +345,7 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -343,7 +345,7 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
data_type_combobox = self.soh_list_table_widget.cellWidget(
data_type_combobox = self.soh_list_table_widget.cellWidget(
row_idx, COL['dataType'])
row_idx, COL['dataType'])
soh_list_item = self.soh_list_table_widget.item(
soh_list_item = self.soh_list_table_widget.item(
row_idx, COL['IDs'])
row_idx, COL['preferredSOHs'])
clear_widget = self.soh_list_table_widget.cellWidget(
clear_widget = self.soh_list_table_widget.cellWidget(
row_idx, COL['clr'])
row_idx, COL['clr'])
return (soh_list_name_item,
return (soh_list_name_item,
@@ -366,7 +368,8 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -366,7 +368,8 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@QtCore.Slot()
@QtCore.Slot()
def edit_soh_list(self, row_idx):
def edit_soh_list(self, row_idx):
soh_list_item = self.soh_list_table_widget.item(row_idx, COL['IDs'])
soh_list_item = self.soh_list_table_widget.item(row_idx,
 
COL['preferredSOHs'])
edit_dialog = InputDialog(text=soh_list_item.text())
edit_dialog = InputDialog(text=soh_list_item.text())
if edit_dialog.exec():
if edit_dialog.exec():
soh_list_item.setText(edit_dialog.get_input())
soh_list_item.setText(edit_dialog.get_input())
@@ -430,6 +433,7 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -430,6 +433,7 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
def add_db_channels(self):
def add_db_channels(self):
"""
"""
Add channels from DB to preferred channel list.
Add channels from DB to preferred channel list.
 
A DB data_type is required in to retrieve its channels from DB
"""
"""
if not self.validate_row(check_data_type=True):
if not self.validate_row(check_data_type=True):
return
return
@@ -550,9 +554,22 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -550,9 +554,22 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
"""
"""
if not self.validate_row():
if not self.validate_row():
return
return
 
# call setFocus() to finish any QEditLine's editing or the editing not
 
# take affect
 
self.save_btn.setFocus()
 
sql_list = self.get_sql_list()
 
 
if sql_list is None:
 
return False
 
if len(sql_list) == 0:
 
self.parent.pref_soh_list = []
 
self.parent.pref_soh_list_name = ''
 
self.parent.pref_soh_list_data_type = 'Unknown'
 
if self.changed:
if self.changed:
msg = ("All IDs in the database will be overwritten with "
msg = ("All Preferred SOH IDs in the database will be "
"current IDs in the dialog.\nClick Cancel to stop updating "
"overwritten with current Preferred SOH IDs in the dialog."
 
"\nClick Cancel to stop updating "
"database.")
"database.")
result = QtWidgets.QMessageBox.question(
result = QtWidgets.QMessageBox.question(
self, "Confirmation", msg,
self, "Confirmation", msg,
@@ -560,19 +577,10 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -560,19 +577,10 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
QtWidgets.QMessageBox.StandardButton.Cancel)
QtWidgets.QMessageBox.StandardButton.Cancel)
if result == QtWidgets.QMessageBox.StandardButton.Cancel:
if result == QtWidgets.QMessageBox.StandardButton.Cancel:
return False
return False
sql_list = []
for row_idx in range(TOTAL_ROW):
sql = self.create_save_row_sql(row_idx)
if sql is not None:
sql_list.append(sql)
if len(sql_list) == 0:
self.parent.pref_soh_list = []
self.parent.pref_soh_list_name = ''
self.parent.pref_soh_list_data_type = 'Unknown'
ret = trunc_add_db('ChannelPrefer', sql_list)
ret = trunc_add_db('ChannelPrefer', sql_list)
if ret is not True:
if ret is not True:
display_tracking_info(self.parent, ret, LogType.ERROR)
display_tracking_info(self.tracking_info_text_browser,
 
ret, LogType.ERROR)
self.parent.pref_soh_list = [
self.parent.pref_soh_list = [
t.strip() for t in self.soh_list_item.text().split(',')]
t.strip() for t in self.soh_list_item.text().split(',')]
self.parent.pref_soh_list_name = self.soh_list_name_item.text().strip()
self.parent.pref_soh_list_name = self.soh_list_name_item.text().strip()
@@ -581,12 +589,73 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -581,12 +589,73 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
self.changed = False
self.changed = False
return True
return True
def create_save_row_sql(self, row_idx):
def get_sql_list(self) -> Optional[List[str]]:
 
"""
 
Create list of sql to insert data to ChannelPrefer table in which:
 
+ If there is error it will mark it to return but continue to report
 
all errors of all rows.
 
+ Beside checking each row, primary key will be checked to make sure
 
the list_of_sql returned can be executed.
 
 
:return:
 
None if there are any error
 
Otherwise, list of sql
 
"""
 
sql_list = []
 
display_id_by_primary_key_dict = {}
 
has_error = False
 
for row_idx in range(TOTAL_ROW):
 
result = self.create_save_row_sql(row_idx)
 
if result is None:
 
has_error = True
 
continue
 
else:
 
primary_key, display_id, sql = result
 
if sql == '':
 
continue
 
sql_list.append(sql)
 
if primary_key not in display_id_by_primary_key_dict:
 
display_id_by_primary_key_dict[primary_key] = []
 
display_id_by_primary_key_dict[primary_key].append(display_id)
 
if self.check_primary_key_duplicated(display_id_by_primary_key_dict):
 
return
 
if has_error:
 
return
 
return sql_list
 
 
def check_primary_key_duplicated(self, display_id_by_primary_key_dict) \
 
-> bool:
 
"""
 
Check if there are any primary keys duplicated.
 
:param display_id_by_primary_key_dict: dictionary with primary key as
 
key and list of display row id for that primary key as value.
 
:return: True if duplicated, False otherwise
 
"""
 
duplicated = False
 
duplicated_primary_keys = [
 
pk for pk in display_id_by_primary_key_dict
 
if len(display_id_by_primary_key_dict[pk]) > 1]
 
if duplicated_primary_keys:
 
duplicated = True
 
for pk in duplicated_primary_keys:
 
msg = (f"Name '{pk}' is duplicated in rows "
 
f"{', '.join(display_id_by_primary_key_dict[pk])}.\n"
 
f"Please change Name '{pk}' to make Name unique.")
 
QtWidgets.QMessageBox.information(self, "Missing info", msg)
 
return duplicated
 
 
def create_save_row_sql(self, row_idx: int) \
 
-> Optional[Tuple[str, str, str]]:
"""
"""
Read info from the row with index row_idx to create insert sql.
Read info from the row with index row_idx to create insert sql.
:param row_idx: int - index of a row
:param row_idx: int - index of a row
:return: str - insert sql with the row's info
:return:
 
None: has error
 
Tuple of:
 
primary key of the row
 
display_id of the row
 
sql to insert row data to ChannelPrefer table
"""
"""
current = 1 if self.soh_list_table_widget.cellWidget(
current = 1 if self.soh_list_table_widget.cellWidget(
row_idx, COL['sel']).isChecked() else 0
row_idx, COL['sel']).isChecked() else 0
@@ -594,16 +663,29 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -594,16 +663,29 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
row_idx, COL['name']).text()
row_idx, COL['name']).text()
data_type = self.soh_list_table_widget.cellWidget(
data_type = self.soh_list_table_widget.cellWidget(
row_idx, COL['dataType']).currentText()
row_idx, COL['dataType']).currentText()
idx = self.soh_list_table_widget.item(
preferred_sohs = self.soh_list_table_widget.item(
row_idx, COL['IDs']).text()
row_idx, COL['preferredSOHs']).text()
if idx.strip() == '':
if preferred_sohs.strip() == '' and name.strip() == '':
 
return '', '', ''
 
display_id = row_idx + 1
 
 
if preferred_sohs.strip() == '' and name.strip() != '':
 
msg = f"Please add Preferred SOH IDs for row {display_id}."
 
QtWidgets.QMessageBox.information(self, "Missing info", msg)
 
return
 
if name.strip() == '' and preferred_sohs.strip() != '':
 
msg = f"Please add Name for row {display_id}."
 
QtWidgets.QMessageBox.information(self, "Missing info", msg)
return
return
if name.strip() == '' and idx.strip() != '':
if preferred_sohs.strip() != '' and data_type == '':
msg = f"Please add Name for row {row_idx}."
msg = f"Please add a data type for row {display_id}."
QtWidgets.QMessageBox.information(self, "Missing info", msg)
QtWidgets.QMessageBox.information(self, "Missing info", msg)
return
return
return (f"INSERT INTO ChannelPrefer (name, IDs, dataType, current)"
sql = (f"INSERT INTO ChannelPrefer (name, preferredSOHs, dataType, "
f"VALUES ('{name}', '{idx}', '{data_type}', {current})")
f"current) VALUES "
 
f"('{name}', '{preferred_sohs}', '{data_type}', {current})")
 
primary_key = name
 
return primary_key, str(display_id), sql
@QtCore.Slot()
@QtCore.Slot()
def save_add_to_main_and_close(self):
def save_add_to_main_and_close(self):
@@ -613,21 +695,31 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -613,21 +695,31 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
"""
"""
if not self.save():
if not self.save():
return
return
 
if self.parent.pref_soh_list_name == '':
 
msg = "Please select a row to add to Main Window."
 
QtWidgets.QMessageBox.information(self, "Missing info", msg)
 
return
self.parent.curr_pref_soh_list_name_txtbox.setText(
self.parent.curr_pref_soh_list_name_txtbox.setText(
self.parent.pref_soh_list_name)
self.parent.pref_soh_list_name)
self.parent.all_soh_chans_check_box.setChecked(False)
self.parent.all_soh_chans_check_box.setChecked(False)
self.close()
self.close()
@staticmethod
@staticmethod
def get_data_types():
def get_data_types(include_default: bool = True):
"""
"""
Get list of data types from DB.
Get list of data types from DB.
 
:param include_default: flag indicate if Default data type should be
 
included or not
:return: [str, ] - list of data types
:return: [str, ] - list of data types
"""
"""
data_type_rows = execute_db(
data_type_rows = execute_db(
'SELECT * FROM DataTypes ORDER BY dataType ASC')
'SELECT * FROM DataTypes ORDER BY dataType ASC')
return [d[0] for d in data_type_rows]
if include_default:
 
return [d[0] for d in data_type_rows]
 
else:
 
return [d[0] for d in data_type_rows
 
if d[0] != 'Default']
@staticmethod
@staticmethod
def get_db_channels(data_type) -> List[str]:
def get_db_channels(data_type) -> List[str]:
@@ -652,6 +744,6 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
@@ -652,6 +744,6 @@ class ChannelPreferDialog(OneWindowAtATimeDialog):
:return id_rows: [dict,] - list of data for each row
:return id_rows: [dict,] - list of data for each row
"""
"""
id_rows = execute_db_dict(
id_rows = execute_db_dict(
"SELECT name, IDs, dataType, current FROM ChannelPrefer "
"SELECT name, preferredSOHs, dataType, current FROM ChannelPrefer "
" ORDER BY name ASC")
" ORDER BY name ASC")
return id_rows
return id_rows
Loading