diff --git a/SIPPCompare.db b/SIPPCompare.db
index ef44f75..0e2d14c 100644
Binary files a/SIPPCompare.db and b/SIPPCompare.db differ
diff --git a/gui/dialogs/platform_rename.ui b/gui/dialogs/platform_rename.ui
index b18d19a..a19a166 100644
--- a/gui/dialogs/platform_rename.ui
+++ b/gui/dialogs/platform_rename.ui
@@ -1,55 +1,87 @@
PlatformRename
-
+
0
0
300
- 90
+ 100
- Rename Platform
+ Name Platform
-
+
- 221
- 62
- 75
- 24
+ 7
+ 41
+ 287
+ 22
-
- OK
+
+
+ 11
+
- 60
- 10
- 191
+ 35
+ 9
+ 241
20
+
+
+ 11
+
+
Enter a new name for the platform
-
+
- 8
- 34
- 287
- 22
+ 220
+ 70
+ 75
+ 24
+
+
+ 10
+
+
+
+ OK
+
-
+
+
+ rename_plat_ok_but
+ clicked()
+ PlatformRename
+ accept()
+
+
+ 257
+ 71
+
+
+ 149
+ 44
+
+
+
+
diff --git a/gui/output_window.ui b/gui/output_window.ui
index 3ba39c9..50c50d1 100644
--- a/gui/output_window.ui
+++ b/gui/output_window.ui
@@ -1,104 +1,37 @@
- ResultsWindow
-
+ OutputWindow
+
0
0
- 400
- 355
+ 1330
+ 630
-
-
- 400
- 355
-
-
-
-
- 400
- 355
-
-
Results
-
+
- 10
- 10
- 381
- 301
+ -10
+ -10
+ 1350
+ 650
-
-
- 11
-
-
-
-
-
-
- 318
- 323
- 75
- 24
-
-
-
-
- 10
-
-
-
- OK
-
-
-
-
-
- 238
- 323
- 75
- 24
-
-
-
-
- 10
-
-
-
- Save
-
-
- output
- res_save_but
- res_ok_but
-
+
+
+ MplWidget
+ QWidget
+
+ 1
+
+
-
-
- res_ok_but
- clicked(bool)
- ResultsWindow
- close()
-
-
- 357
- 281
-
-
- 199
- 149
-
-
-
-
+
diff --git a/gui/platform_edit.ui b/gui/platform_edit.ui
index fe3a57d..56f5558 100644
--- a/gui/platform_edit.ui
+++ b/gui/platform_edit.ui
@@ -2,6 +2,9 @@
PlatformEdit
+
+ Qt::WindowModality::ApplicationModal
+
0
diff --git a/gui/platform_list.ui b/gui/platform_list.ui
index fe6679a..e9d1222 100644
--- a/gui/platform_list.ui
+++ b/gui/platform_list.ui
@@ -2,6 +2,9 @@
PlatformList
+
+ Qt::WindowModality::ApplicationModal
+
0
@@ -120,5 +123,22 @@
-
+
+
+ plist_save_but
+ clicked()
+ PlatformList
+ close()
+
+
+ 196
+ 453
+
+
+ 131
+ 236
+
+
+
+
diff --git a/src/db_handler.py b/src/db_handler.py
index 7e95c14..252d62e 100644
--- a/src/db_handler.py
+++ b/src/db_handler.py
@@ -1,11 +1,13 @@
import os
import sqlite3
-import data_struct
+
+import resource_finder
from data_struct import Platform
class DBHandler:
def __init__(self):
+ # Function to create all necessary database tables if the DB file doesn't exist
def create_tables():
self.cur.execute("""
CREATE TABLE "tblPlatforms" (
@@ -59,16 +61,17 @@ class DBHandler:
)
""")
- if not os.path.exists("SIPPCompare.db"):
+ if not os.path.exists(resource_finder.get_res_path("SIPPCompare.db")):
db_exists = False
else:
db_exists = True
- self.conn = sqlite3.connect("SIPPCompare.db")
+ self.conn = sqlite3.connect(resource_finder.get_res_path("SIPPCompare.db"))
self.cur = self.conn.cursor()
if not db_exists:
create_tables()
+ # Retrieve the list of platform names for list population
def retrieve_plat_list(self) -> list:
res = self.cur.execute("SELECT PlatformName FROM tblPlatforms").fetchall()
plat_name_list = []
@@ -77,7 +80,80 @@ class DBHandler:
return plat_name_list
+ def write_platforms(self, plat_list: list[Platform]):
+ for i in range(len(plat_list)):
+ platforms_data = [
+ plat_list[i].plat_id,
+ plat_list[i].plat_name,
+ plat_list[i].enabled
+ ]
+
+ flat_plat_fees_data = [
+ plat_list[i].plat_id,
+ plat_list[i].share_plat_fee,
+ plat_list[i].share_plat_max_fee
+ ]
+
+ flat_deal_fees_data = [
+ plat_list[i].plat_id,
+ plat_list[i].fund_deal_fee,
+ plat_list[i].share_deal_fee,
+ plat_list[i].share_deal_reduce_trades,
+ plat_list[i].share_deal_reduce_amount
+ ]
+
+ res = self.cur.execute(f"""
+ SELECT EXISTS(
+ SELECT PlatformID FROM tblPlatforms
+ WHERE PlatformID = {i}
+ )""").fetchall()
+
+ if res[0][0] == 1:
+ self.cur.execute(f"""
+ UPDATE tblPlatforms SET
+ PlatformID = ?,
+ PlatformName = ?,
+ IsEnabled = ?
+ WHERE PlatformID = {i}
+ """, platforms_data)
+
+ self.cur.execute(f"""
+ UPDATE tblFlatPlatFees SET
+ PlatformID = ?,
+ SharePlatFee = ?,
+ SharePlatMaxFee = ?
+ WHERE PlatformID = {i}
+ """, flat_plat_fees_data)
+
+ self.cur.execute(f"""
+ UPDATE tblFlatDealFees SET
+ PlatformID = ?,
+ FundDealFee = ?,
+ ShareDealFee = ?,
+ ShareDealReduceTrades = ?,
+ ShareDealReduceAmount = ?
+ WHERE PlatformID = {i}
+ """, flat_deal_fees_data)
+
+ self.cur.execute(f"DELETE FROM tblFundPlatFee WHERE PlatformID = {i}")
+ else:
+ self.cur.execute("INSERT INTO tblPlatforms VALUES (?, ?, ?)", platforms_data)
+ self.cur.execute("INSERT INTO tblFlatPlatFees VALUES (?, ?, ?)", flat_plat_fees_data)
+ self.cur.execute("INSERT INTO tblFlatDealFees VALUES (?, ?, ?, ?, ?)", flat_deal_fees_data)
+
+ exec_str = f"INSERT INTO tblFundPlatFee VALUES\n"
+ for x in range(len(plat_list[i].fund_plat_fee[0])):
+ band = plat_list[i].fund_plat_fee[0][x]
+ fee = plat_list[i].fund_plat_fee[1][x]
+ exec_str += f"({i}, {band}, {fee}),\n"
+ exec_str = exec_str[:-2]
+ self.cur.execute(exec_str)
+
+ self.conn.commit()
+
+ # Retrieve all info about all platforms in DB and initialise Platform objects
def retrieve_platforms(self) -> list[Platform]:
+ # Retrieve all one-to-one relations
platforms_res = self.cur.execute("""
SELECT
-- tblPlatforms
@@ -104,10 +180,13 @@ class DBHandler:
platform[5], platform[6], platform[7], platform[8]]
platforms.append(this_platform)
+ # Insert 2D array into each platform data in preparation for fund_plat_fee retrival
for platform in platforms:
platform.insert(1, [[], []])
- fund_plat_fee_res = self.cur.execute("SELECT * FROM tblFundPlatFee").fetchall()
+ # Get all records from tblFundPlatFee, add them to the platforms list based on ID
+ # WARNING: This code is dependent on PlatformID being sequential from 0 in DB records
+ fund_plat_fee_res = self.cur.execute("SELECT * FROM tblFundPlatFee ORDER BY PlatformID ASC").fetchall()
for i in range(len(fund_plat_fee_res)):
plat_id = fund_plat_fee_res[i][0]
platforms[plat_id][1][0].append(fund_plat_fee_res[i][1])
@@ -123,15 +202,18 @@ class DBHandler:
return platform_obj_list
-
+ # This function writes the details the user entered this session to the DB
def write_user_details(self, pension_val: float, slider_val: int, share_trades: int, fund_trades: int):
# Hardcode UserID as 0
user_details_data = (0, pension_val, slider_val, share_trades, fund_trades)
+ # Check if there is already a record in tblUserDetails
res = self.cur.execute("SELECT EXISTS(SELECT 1 FROM tblUserDetails)").fetchone()
if res[0] == 0:
+ # If there isn't then insert a new record
self.cur.execute("INSERT INTO tblUserDetails VALUES (?, ?, ?, ?, ?)", user_details_data)
else:
+ # If there is then update the existing record (only ever one record as of now)
self.cur.execute("""
UPDATE tblUserDetails SET
UserID = ?,
@@ -142,6 +224,7 @@ class DBHandler:
""", user_details_data)
self.conn.commit()
+ # Function to retrieve details entered by the user in prev session from DB
def retrieve_user_details(self) -> dict:
res = self.cur.execute("SELECT EXISTS(SELECT 1 FROM tblUserDetails)").fetchone()
if res[0] == 0:
diff --git a/src/main.py b/src/main.py
index 4ee5f19..86dad41 100644
--- a/src/main.py
+++ b/src/main.py
@@ -1,23 +1,12 @@
-from PyQt6.QtWidgets import QApplication
-
import sys
-import platform_edit
-import main_window
+from PyQt6.QtWidgets import QApplication
+
+from platform_edit import PlatformEdit
+from main_window import SIPPCompare
app = QApplication(sys.argv)
-# Show platform edit window first, before main win
-# When debugging, can be useful to autofill values to save time
-"""if len(sys.argv) > 1:
- if sys.argv[1] == "--DEBUG_AUTOFILL":
- window = platform_edit.PlatformEdit(True)
- else:
- window = platform_edit.PlatformEdit(False)
-else:
- window = platform_edit.PlatformEdit(False)"""
-#plat_edit_win = platform_edit.PlatformEdit()
-window = main_window.SIPPCompare()
-
+window = SIPPCompare()
window.show()
app.exec()
diff --git a/src/main_window.py b/src/main_window.py
index f500469..8bf91de 100644
--- a/src/main_window.py
+++ b/src/main_window.py
@@ -1,17 +1,18 @@
-from PyQt6.QtGui import QIntValidator, QIcon
-from PyQt6.QtWidgets import QMainWindow, QWidget
from PyQt6 import uic
+from PyQt6.QtGui import QIntValidator, QIcon
+from PyQt6.QtWidgets import QMainWindow
-import output_window
-import platform_list
import resource_finder
-import db_handler
+from db_handler import DBHandler
+from output_window import OutputWindow
+from platform_list import PlatformList
class SIPPCompare(QMainWindow):
def __init__(self):
super().__init__()
# Import Qt Designer UI XML file
+
uic.loadUi(resource_finder.get_res_path("gui/main_gui.ui"), self)
self.setWindowIcon(QIcon(resource_finder.get_res_path("icon2.ico")))
@@ -32,11 +33,12 @@ class SIPPCompare(QMainWindow):
self.fund_deal_fees = 0.0
self.share_plat_fees = 0.0
self.share_deal_fees = 0.0
+ self.results = []
# Create window objects
- self.db = db_handler.DBHandler()
- self.platform_list_win = platform_list.PlatformList(self.db)
- self.output_win = output_window.OutputWindow()
+ self.db = DBHandler()
+ self.platform_list_win = PlatformList(self.db)
+ self.output_win = OutputWindow()
# Handle events
self.calc_but.clicked.connect(self.calculate_fees)
@@ -61,8 +63,6 @@ class SIPPCompare(QMainWindow):
self.fund_trades_combo.setCurrentText(str(prev_session_data["fund_trades"]))
self.calc_but.setFocus()
-
-
# Display slider position as mix between two nums (funds/shares)
def update_slider_lab(self):
slider_val = self.mix_slider.value()
@@ -78,6 +78,7 @@ class SIPPCompare(QMainWindow):
self.calc_but.setEnabled(False)
# Get variables from platform editor input fields
+ """
def init_variables(self):
self.optional_boxes = self.platform_win.get_optional_boxes()
self.fund_plat_fee = self.platform_win.get_fund_plat_fee()
@@ -109,50 +110,59 @@ class SIPPCompare(QMainWindow):
self.share_deal_reduce_amount = self.platform_win.get_share_deal_reduce_amount()
else:
self.share_deal_reduce_amount = None
+ """
+ def init_variables(self):
+ self.fund_plat_fee = 1
# Calculate fees
def calculate_fees(self):
- self.init_variables()
-
- # Set to zero each time to avoid persistence
- self.fund_plat_fees = 0
+ # Set to empty list each time to avoid persistence
+ self.results = []
# Get user input
value_num = float(self.value_input.value())
slider_val: int = self.mix_slider.value()
fund_trades_num = int(self.fund_trades_combo.currentText())
share_trades_num = int(self.share_trades_combo.currentText())
-
- # Funds/shares mix
funds_value = (slider_val / 100) * value_num
- if self.fund_deal_fee is not None:
- self.fund_deal_fees = fund_trades_num * self.fund_deal_fee
-
- for i in range(1, len(self.fund_plat_fee[0])):
- band = self.fund_plat_fee[0][i]
- prev_band = self.fund_plat_fee[0][i - 1]
- fee = self.fund_plat_fee[1][i]
- gap = (band - prev_band)
-
- if funds_value > gap:
- self.fund_plat_fees += gap * (fee / 100)
- funds_value -= gap
- else:
- self.fund_plat_fees += funds_value * (fee / 100)
- break
-
shares_value = (1 - (slider_val / 100)) * value_num
- if self.share_plat_max_fee is not None:
- if (self.share_plat_fee * shares_value / 12) > self.share_plat_max_fee:
- self.share_plat_fees = self.share_plat_max_fee * 12
- else:
- self.share_plat_fees = self.share_plat_fee * shares_value
- if self.share_deal_reduce_trades is not None:
- if (share_trades_num / 12) >= self.share_deal_reduce_trades:
- self.share_deal_fees = self.share_deal_reduce_amount * share_trades_num
- else:
- self.share_deal_fees = self.share_deal_fee * share_trades_num
+ for platform in self.platform_list_win.plat_list:
+ fund_plat_fees = 0.0
+ fund_deal_fees = 0.0
+ share_plat_fees = 0.0
+ share_deal_fees = 0.0
+ plat_name = platform.plat_name
+
+ if platform.fund_deal_fee is not None:
+ fund_deal_fees = fund_trades_num * platform.fund_deal_fee
+
+ for i in range(1, len(platform.fund_plat_fee[0])):
+ band = platform.fund_plat_fee[0][i]
+ prev_band = platform.fund_plat_fee[0][i - 1]
+ fee = platform.fund_plat_fee[1][i]
+ gap = (band - prev_band)
+
+ if funds_value > gap:
+ fund_plat_fees += gap * (fee / 100)
+ funds_value -= gap
+ else:
+ fund_plat_fees += funds_value * (fee / 100)
+ break
+
+ if platform.share_plat_max_fee is not None:
+ if (platform.share_plat_fee * shares_value / 12) > platform.share_plat_max_fee:
+ share_plat_fees = platform.share_plat_max_fee * 12
+ else:
+ share_plat_fees = platform.share_plat_fee * shares_value
+
+ if platform.share_deal_reduce_trades is not None:
+ if (share_trades_num / 12) >= platform.share_deal_reduce_trades:
+ share_deal_fees = platform.share_deal_reduce_amount * share_trades_num
+ else:
+ share_deal_fees = platform.share_deal_fee * share_trades_num
+
+ self.results.append([fund_plat_fees, fund_deal_fees, share_plat_fees, share_deal_fees, plat_name])
self.db.write_user_details(value_num, slider_val, share_trades_num, fund_trades_num)
self.show_output_win()
@@ -160,10 +170,7 @@ class SIPPCompare(QMainWindow):
# Show the output window - this func is called from calculate_fee()
def show_output_win(self):
# Refresh the results when new fees are calculated
- self.output_win.display_output(self.fund_plat_fees, self.fund_deal_fees,
- self.share_plat_fees, self.share_deal_fees,
- self.plat_name
- )
+ self.output_win.display_output(self.results)
self.output_win.show()
def show_platform_list(self):
diff --git a/src/output_window.py b/src/output_window.py
index 06933da..fe80f64 100644
--- a/src/output_window.py
+++ b/src/output_window.py
@@ -1,10 +1,10 @@
-from PyQt6.QtGui import QIcon
-from PyQt6.QtWidgets import QWidget
-from PyQt6 import uic
-
import datetime
import os
+from PyQt6 import uic
+from PyQt6.QtGui import QIcon
+from PyQt6.QtWidgets import QWidget
+
import resource_finder
@@ -15,6 +15,7 @@ class OutputWindow(QWidget):
uic.loadUi(resource_finder.get_res_path("gui/output_window.ui"), self)
self.setWindowIcon(QIcon(resource_finder.get_res_path("icon2.ico")))
+ """
# Initialise class variables
self.results_str = ""
self.platform_name = ""
@@ -62,3 +63,25 @@ class OutputWindow(QWidget):
self.results_str += f"\n\nTotal fees: £{round(total_fees, 2):.2f}"
self.output.setText(self.results_str)
+ """
+
+ def display_output(self, results: list):
+ self.graphWidget.canvas.axes.clear()
+ self.graphWidget.canvas.axes.cla()
+ self.graphWidget.canvas.draw_idle()
+ ax = self.graphWidget.canvas.axes
+ #self.graphWidget.clf()
+ names = []
+ values = []
+ for result in results:
+ names.append(result[4])
+ values.append(sum(result[:4]))
+ h_bars = ax.barh(names, values)
+ #labels = []
+ #for value in values:
+ # labels.append(f"£{str(value)}")
+
+ ax.bar_label(h_bars, label_type='center', labels=[f"£{x:,.2f}" for x in h_bars.datavalues])
+ #ax.draw()
+ #self.graphWidget.draw()
+
diff --git a/src/platform_edit.py b/src/platform_edit.py
index 07b8817..cf45221 100644
--- a/src/platform_edit.py
+++ b/src/platform_edit.py
@@ -1,12 +1,12 @@
-from PyQt6.QtCore import QRegularExpression
+from PyQt6 import uic
+from PyQt6.QtCore import QRegularExpression, QRect
from PyQt6.QtGui import QRegularExpressionValidator, QFont, QIcon
from PyQt6.QtWidgets import QWidget, QLabel
-from PyQt6 import uic
-from widgets.fastedit_spinbox import FastEditQDoubleSpinBox
-from data_struct import Platform
-import main_window
import resource_finder
+from db_handler import DBHandler
+from data_struct import Platform
+from widgets.fastedit_spinbox import FastEditQDoubleSpinBox
class PlatformEdit(QWidget):
@@ -20,14 +20,10 @@ class PlatformEdit(QWidget):
self.plat = plat
self.fund_plat_fee = self.plat.fund_plat_fee
self.widgets_list_list = []
-
- self.fund_fee_rows = len(self.plat.fund_plat_fee[0])
- """
- # Debugging feature: set with "--DEBUG_AUTOFILL" cmd argument
- self.autofill = autofill
- if autofill:
- self.save_but.setEnabled(True)
- """
+ if len(self.plat.fund_plat_fee[0]) > 1:
+ self.fund_fee_rows = len(self.plat.fund_plat_fee[0]) - 1
+ else:
+ self.fund_fee_rows = 1
self.required_fields = [
self.share_plat_fee_box,
@@ -58,6 +54,7 @@ class PlatformEdit(QWidget):
False
]
+ # Set optional checkboxes based on DB storage
if self.plat.plat_name is None:
self.check_boxes_ticked[0] = False
self.plat_name_check.setChecked(False)
@@ -102,8 +99,10 @@ class PlatformEdit(QWidget):
self.share_deal_reduce_amount_check.setChecked(True)
self.share_deal_reduce_amount_box.setValue(self.plat.share_deal_reduce_amount)
- self.first_tier_box.setValue(self.plat.fund_plat_fee[0][1])
- self.first_tier_fee_box.setValue(self.plat.fund_plat_fee[1][1])
+ # Populate fund platform fee rows from DB
+ if len(self.plat.fund_plat_fee[0]) > 1:
+ self.first_tier_box.setValue(self.plat.fund_plat_fee[0][1])
+ self.first_tier_fee_box.setValue(self.plat.fund_plat_fee[1][1])
self.add_row(loading=True)
# Handle events
@@ -150,34 +149,34 @@ class PlatformEdit(QWidget):
# Get fee structure variables from user input when "Save" clicked
def init_variables(self):
- """
- # If debugging, save time by hardcoding
- if self.autofill:
- self.plat_name = "AJBell"
- self.fund_plat_fee = [
- [0, 250000, 1000000, 2000000],
- [0, 0.25, 0.1, 0.05]
- ]
- self.fund_deal_fee = 1.50
- self.share_plat_fee = 0.0025
- self.share_plat_max_fee = 3.50
- self.share_deal_fee = 5.00
- self.share_deal_reduce_trades = 10
- self.share_deal_reduce_amount = 3.50
- self.check_boxes_ticked = [True, True, True, True, True]
- else:
- """
- self.plat_name = self.plat_name_box.text()
- self.fund_plat_fee = self.create_plat_fee_struct()
- self.fund_deal_fee = float(self.fund_deal_fee_box.value())
- self.share_plat_fee = float(self.share_plat_fee_box.value()) / 100
- self.share_plat_max_fee = float(self.share_plat_max_fee_box.value())
- self.share_deal_fee = float(self.share_deal_fee_box.value())
- self.share_deal_reduce_trades = float(self.share_deal_reduce_trades_box.value())
- self.share_deal_reduce_amount = float(self.share_deal_reduce_amount_box.value())
+ self.plat.fund_plat_fee = self.create_plat_fee_struct()
+ self.plat.share_plat_fee = float(self.share_plat_fee_box.value()) / 100
+ self.plat.share_deal_fee = float(self.share_deal_fee_box.value())
- # Once user input is received show main window
- self.main_win.show()
+ if self.check_boxes_ticked[0]:
+ self.plat.plat_name = self.plat_name_box.text()
+ else:
+ self.plat.plat_name = None
+
+ if self.check_boxes_ticked[1]:
+ self.plat.fund_deal_fee = float(self.fund_deal_fee_box.value())
+ else:
+ self.plat.fund_deal_fee = None
+
+ if self.check_boxes_ticked[2]:
+ self.plat.share_plat_max_fee = float(self.share_plat_max_fee_box.value())
+ else:
+ self.plat.share_plat_max_fee = None
+
+ if self.check_boxes_ticked[3]:
+ self.plat.share_deal_reduce_trades = int(self.share_deal_reduce_trades_box.value())
+ else:
+ self.plat.share_deal_reduce_trades = None
+
+ if self.check_boxes_ticked[4]:
+ self.plat.share_deal_reduce_amount = float(self.share_deal_reduce_amount_box.value())
+ else:
+ self.plat.share_deal_reduce_amount = None
# This method does multiple things in order to validate the user's inputs:
# 1) Check all required fields have a non-zero value
@@ -261,12 +260,12 @@ class PlatformEdit(QWidget):
def add_row(self, loading: bool = False):
if loading:
- rows_needed = self.fund_fee_rows
+ rows_needed = self.fund_fee_rows - 1
else:
rows_needed = 1
- widgets = []
for x in range(rows_needed):
+ widgets = []
font = QFont()
font.setPointSize(11)
@@ -279,7 +278,7 @@ class PlatformEdit(QWidget):
widgets[1].setButtonSymbols(FastEditQDoubleSpinBox.ButtonSymbols.NoButtons)
widgets[1].setFont(font)
if loading:
- widgets[1].setValue(self.plat.fund_plat_fee[0][x+1])
+ widgets[1].setValue(self.plat.fund_plat_fee[0][x+2])
widgets[1].valueChanged.connect(self.check_valid)
widgets[1].valueChanged.connect(self.update_tier_labels)
@@ -293,13 +292,20 @@ class PlatformEdit(QWidget):
widgets[3].setButtonSymbols(FastEditQDoubleSpinBox.ButtonSymbols.NoButtons)
widgets[3].setFont(font)
if loading:
- widgets[3].setValue(self.plat.fund_plat_fee[1][x+1])
+ widgets[3].setValue(self.plat.fund_plat_fee[1][x+2])
widgets[3].valueChanged.connect(self.check_valid)
# TODO: why 28.5?
- self.gridLayoutWidget_2.setGeometry(11, 309, 611, int(round(28.5 * (self.fund_fee_rows + 1), 0)))
+ if loading:
+ grid_height = int(round(28.5 * self.fund_fee_rows))
+ else:
+ grid_height = int(round(28.5 * (self.fund_fee_rows + 1)))
+ self.gridLayoutWidget_2.setGeometry(QRect(11, 309, 611, grid_height))
for i in range(len(widgets)):
- self.gridLayout_2.addWidget(widgets[i], self.fund_fee_rows, i, 1, 1)
+ if loading:
+ self.gridLayout_2.addWidget(widgets[i], x + 1, i, 1, 1)
+ else:
+ self.gridLayout_2.addWidget(widgets[i], self.fund_fee_rows, i, 1, 1)
if not loading:
self.fund_fee_rows += 1
@@ -324,6 +330,7 @@ class PlatformEdit(QWidget):
self.add_row_but.setEnabled(False)
self.check_valid()
+ self.update_tier_labels()
# TODO: Tab order
diff --git a/src/platform_list.py b/src/platform_list.py
index 110f0a9..93e8f9c 100644
--- a/src/platform_list.py
+++ b/src/platform_list.py
@@ -1,56 +1,94 @@
-from PyQt6.QtWidgets import QWidget, QListWidgetItem
-from PyQt6.QtGui import QIcon, QRegularExpressionValidator
-from PyQt6.QtCore import QRegularExpression
from PyQt6 import uic
+from PyQt6.QtCore import QRegularExpression
+from PyQt6.QtGui import QIcon, QRegularExpressionValidator
+from PyQt6.QtWidgets import QWidget, QListWidgetItem, QDialog
import resource_finder
-import data_struct
-import platform_edit
+from db_handler import DBHandler
+from data_struct import Platform
+from platform_edit import PlatformEdit
-class PlatformRename(QWidget):
- def __init__(self):
- super().__init__()
+class PlatformRename(QDialog):
+ def __init__(self, parent=None):
+ super().__init__(parent)
# Import Qt Designer UI XML file
uic.loadUi(resource_finder.get_res_path("gui/dialogs/platform_rename.ui"), self)
self.setWindowIcon(QIcon(resource_finder.get_res_path("icon2.ico")))
+ self.rename_plat_box.setFocus()
+ self.new_name = ""
+
# Set validators
# Regex accepts any characters that match [a-Z], [0-9] or _
self.rename_plat_box.setValidator(
QRegularExpressionValidator(QRegularExpression("\\w*"))
)
+ self.rename_plat_ok_but.clicked.connect(self.store_new_name)
+
+ def store_new_name(self):
+ self.new_name = self.rename_plat_box.text()
+
+ def closeEvent(self, event):
+ event.ignore()
+ self.reject()
+
class PlatformList(QWidget):
- def __init__(self, db):
+ def __init__(self, db: DBHandler):
super().__init__()
# Import Qt Designer UI XML file
uic.loadUi(resource_finder.get_res_path("gui/platform_list.ui"), self)
self.setWindowIcon(QIcon(resource_finder.get_res_path("icon2.ico")))
- self.plat_list_dialog = PlatformRename()
- self.p_edit = None
self.db = db
- self.plat_name_list = self.db.retrieve_plat_list()
- self.plat_list = self.db.retrieve_platforms()
- print(self.plat_list[1].fund_plat_fee)
- print(self.plat_name_list)
+ self.plat_edit_win = None
+ self.plat_list_dialog = PlatformRename()
+ self.plat_list = []
+ self.plat_name_list = []
+ self.new_plat_name = ""
+ self.update_plat_list()
- for platform in self.plat_name_list:
+ for i in range(len(self.plat_name_list)):
+ plat_name = self.plat_name_list[i]
item = QListWidgetItem()
- item.setText(platform)
+ if plat_name is not None:
+ item.setText(plat_name)
+ else:
+ item.setText(f"Unnamed [ID: {i}]")
+
self.platListWidget.addItem(item)
# Handle events
self.add_plat_but.clicked.connect(self.add_platform)
self.del_plat_but.clicked.connect(self.remove_platform)
self.edit_plat_but.clicked.connect(self.edit_platform)
+ self.plist_save_but.clicked.connect(self.save_platforms)
self.plat_enabled_check.checkStateChanged.connect(self.toggle_platform_state)
self.platListWidget.currentRowChanged.connect(self.get_enabled_state)
+ def update_plat_list(self):
+ self.plat_name_list = self.db.retrieve_plat_list()
+ self.plat_list = self.db.retrieve_platforms()
+
def add_platform(self):
- self.plat_list_dialog.show()
+ name_dialog_res = self.plat_list_dialog.exec()
+ if name_dialog_res == QDialog.DialogCode.Accepted:
+ name = self.plat_list_dialog.new_name
+ index = self.platListWidget.count()
+ if name != "":
+ self.platListWidget.addItem(name)
+ name_param = name
+ else:
+ self.platListWidget.addItem(f"Unnamed [ID: {index}]")
+ name_param = None
+
+ self.plat_list.append(Platform(
+ index, [[0], [0]], name_param, True, 0, 0, None, 0, None, None)
+ )
+ self.plat_edit_win = PlatformEdit(self.plat_list[index])
+ self.plat_edit_win.show()
def get_enabled_state(self):
index = self.platListWidget.currentRow()
@@ -62,8 +100,11 @@ class PlatformList(QWidget):
def edit_platform(self):
index = self.platListWidget.currentRow()
- self.p_edit = platform_edit.PlatformEdit(self.plat_list[index])
- self.p_edit.show()
+ self.plat_edit_win = PlatformEdit(self.plat_list[index])
+ self.plat_edit_win.show()
+
+ def save_platforms(self):
+ self.db.write_platforms(self.plat_list)
def toggle_platform_state(self):
return None
diff --git a/src/widgets/mpl_widget.py b/src/widgets/mpl_widget.py
new file mode 100644
index 0000000..1d6e664
--- /dev/null
+++ b/src/widgets/mpl_widget.py
@@ -0,0 +1,14 @@
+from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
+from matplotlib.figure import Figure
+from PyQt6.QtWidgets import QWidget, QVBoxLayout
+
+
+class MplWidget(QWidget):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.canvas = FigureCanvasQTAgg(Figure(figsize=(10, 10), dpi=100))
+ vertical_layout = QVBoxLayout()
+ #vertical_layout.setSpacing(0)
+ vertical_layout.addWidget(self.canvas)
+ self.canvas.axes = self.canvas.figure.add_subplot(1, 1, 1)
+ self.setLayout(vertical_layout)
\ No newline at end of file