Compare commits

29 Commits

Author SHA1 Message Date
005f189c76 removed database binary from source tree 2025-04-29 14:22:06 +01:00
c8d7594af6 update nuitka product version 2025-04-29 14:17:30 +01:00
756efdf364 only update val_above_lab when input is valid 2025-04-28 16:41:52 +01:00
2af0ecfd75 fix logic for platform list 2025-04-28 15:26:28 +01:00
8ddc40baf6 refresh graph results properly 2025-04-28 14:59:22 +01:00
8f6f3dab00 add flowcharts 2025-04-28 14:56:44 +01:00
4b8bdfbeea update PyCharm indexing exclusions 2025-04-28 12:55:14 +01:00
09f8b7bba8 remove unused code 2025-04-28 12:54:07 +01:00
abbcbe41d0 final small fixes to UI files 2025-04-27 20:23:48 +01:00
75e26e229a finalise nuitka build options (for windows) 2025-04-27 16:22:06 +01:00
5eb0c3c4a3 fix mistakenly disabled checkbox + fix win size 2025-04-27 15:31:54 +01:00
78323c2ad8 switch from un-used trade QComboBox to FastEditQSpinBox 2025-04-27 15:29:04 +01:00
2422395759 properly implement resource finding for nuitka 2025-04-27 15:28:10 +01:00
7cb41652b4 switch from pyinstaller to nuitka for distribution 2025-04-27 11:56:19 +01:00
ae01d912e1 additional comments 2025-04-27 11:55:49 +01:00
9a8b0045fa defer import of matplotlib to spped up launch 2025-04-27 11:55:27 +01:00
9e79d986e4 add additional input validation 2025-04-27 11:54:09 +01:00
71d9590205 fix weird spacing bug 2025-04-27 11:51:05 +01:00
3b6b75ee48 updated .gitignore 2025-04-26 20:47:52 +01:00
Roland W-H
ca8f4409c1 Merge pull request #3 from RolandWH/db_testing
implement sqlite database and graphed results
2025-04-26 16:45:44 +01:00
ba204becc9 code formatting, clean up & comments 2025-04-26 16:40:36 +01:00
42afd128e5 add error handling for file saving 2025-04-26 16:39:56 +01:00
629ea6833d set min and max sizes for all windows 2025-04-26 16:39:05 +01:00
e2ca298919 make results window active and raise it when calculating 2025-04-26 16:38:37 +01:00
593dec96d1 add enable/disable platform functionality 2025-04-26 16:37:23 +01:00
fa74e9e8da fix critical calculation bug 2025-04-26 14:17:17 +01:00
16802648bc implement deleting platforms and csv saving 2025-04-26 12:57:49 +01:00
c151b19a3c update pyinstaller spec 2025-04-25 17:36:13 +01:00
f2a0735972 add time slider and saving functionality to output 2025-04-25 17:35:54 +01:00
28 changed files with 1290 additions and 193 deletions

7
.gitignore vendored
View File

@@ -2,8 +2,9 @@
.idea/workspace.xml
.idea/discord.xml
.idea/encodings.xml
build/
dist/
*build/
*dist/
output/
src/*/__pycache__/
src/__pycache__/
src/__pycache__/
*.db

2
.idea/SIPPCompare.iml generated
View File

@@ -3,6 +3,8 @@
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.venv" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/output" />
</content>
<orderEntry type="jdk" jdkName="Python 3.13 (SIPPCompare)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />

Binary file not shown.

View File

@@ -1,45 +0,0 @@
# -*- mode: python ; coding: utf-8 -*-
a = Analysis(
['src\\main.py'],
pathex=[],
binaries=[],
datas=[('gui/*.ui', 'gui'), ('icon2.ico', '.')],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
pyz = PYZ(a.pure)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='SIPPCompare',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon="icon2.ico"
)
coll = COLLECT(
exe,
a.binaries,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='SIPPCompare',
)

138
flowcharts/main_win.drawio Normal file
View File

@@ -0,0 +1,138 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="2068" dy="1219" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-0" target="GkLdqIe8JMVAQNq9l6uQ-4" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="144" y="120" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-0" value="Import user details from database" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.start_1;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="94" y="10" width="100" height="60" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-7" value="Yes&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-4" target="GkLdqIe8JMVAQNq9l6uQ-14" edge="1">
<mxGeometry x="0.0098" y="15" relative="1" as="geometry">
<mxPoint x="139" y="230" as="sourcePoint" />
<mxPoint x="144" y="270" as="targetPoint" />
<mxPoint x="1" y="-1" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-4" value="User input?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="94" y="120" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-8" target="GkLdqIe8JMVAQNq9l6uQ-4" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="330" y="320" as="targetPoint" />
<Array as="points">
<mxPoint x="250" y="480" />
<mxPoint x="250" y="170" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-10" value="No" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="GkLdqIe8JMVAQNq9l6uQ-9" vertex="1" connectable="0">
<mxGeometry x="0.0214" y="1" relative="1" as="geometry">
<mxPoint x="1" y="120" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-12" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-8" target="GkLdqIe8JMVAQNq9l6uQ-11" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-8" value="User input&amp;nbsp;&lt;div&gt;valid?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="94" y="430" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-11" value="Enable calculate button" style="whiteSpace=wrap;html=1;strokeWidth=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="84" y="584" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-15" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-14" target="GkLdqIe8JMVAQNq9l6uQ-20" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="340" y="320" as="targetPoint" />
<Array as="points">
<mxPoint x="300" y="320" />
<mxPoint x="300" y="40" />
</Array>
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-14" value="Calculate&amp;nbsp;&lt;div&gt;button&amp;nbsp;&lt;/div&gt;&lt;div&gt;clicked?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="94" y="270" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-17" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-14" target="GkLdqIe8JMVAQNq9l6uQ-8" edge="1">
<mxGeometry x="0.2" y="16" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-18" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-11" target="GkLdqIe8JMVAQNq9l6uQ-4" edge="1">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="30" y="614" />
<mxPoint x="30" y="170" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-20" target="GkLdqIe8JMVAQNq9l6uQ-21" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-20" value="Calculate fund platform fees" style="whiteSpace=wrap;html=1;strokeWidth=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="340" y="10" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-21" target="GkLdqIe8JMVAQNq9l6uQ-24" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-21" value="Calculate fund dealing fees" style="whiteSpace=wrap;html=1;strokeWidth=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="340" y="120" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-24" target="GkLdqIe8JMVAQNq9l6uQ-27" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="400" y="330" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-24" value="Calculate share platform fees" style="whiteSpace=wrap;html=1;strokeWidth=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="340" y="230" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-27" target="CeQ2sipdlTVvld8hq7BN-4" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-27" value="Calculate share dealing fees" style="whiteSpace=wrap;html=1;strokeWidth=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="340" y="340" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="CeQ2sipdlTVvld8hq7BN-1" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="GkLdqIe8JMVAQNq9l6uQ-28" target="CeQ2sipdlTVvld8hq7BN-0">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="GkLdqIe8JMVAQNq9l6uQ-28" value="Send results list to output window (display results)" style="whiteSpace=wrap;html=1;strokeWidth=2;" parent="WIyWlLk6GJQsqaUBKTNV-1" vertex="1">
<mxGeometry x="520" y="450" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="CeQ2sipdlTVvld8hq7BN-0" value="Save user details to database" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="520" y="584" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="CeQ2sipdlTVvld8hq7BN-7" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="CeQ2sipdlTVvld8hq7BN-4" target="CeQ2sipdlTVvld8hq7BN-8">
<mxGeometry relative="1" as="geometry">
<mxPoint x="400" y="556" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="CeQ2sipdlTVvld8hq7BN-4" value="Add results for this platform to list" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="340" y="450" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="CeQ2sipdlTVvld8hq7BN-9" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="CeQ2sipdlTVvld8hq7BN-8" target="GkLdqIe8JMVAQNq9l6uQ-28">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="CeQ2sipdlTVvld8hq7BN-8" value="Last platform processed?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="350" y="564" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="CeQ2sipdlTVvld8hq7BN-11" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.89;entryY=0.616;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="CeQ2sipdlTVvld8hq7BN-0" target="GkLdqIe8JMVAQNq9l6uQ-4">
<mxGeometry relative="1" as="geometry">
<mxPoint x="154" y="130" as="targetPoint" />
<mxPoint x="154" y="80" as="sourcePoint" />
<Array as="points">
<mxPoint x="580" y="680" />
<mxPoint x="220" y="680" />
<mxPoint x="220" y="220" />
<mxPoint x="183" y="220" />
</Array>
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@@ -0,0 +1,79 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="1426" dy="841" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-5" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-0" target="D6qvsPv5HUMZqZDP2d3Z-22">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-0" value="Print results to screen" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.start_1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="210" y="10" width="100" height="60" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-7" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-4" target="D6qvsPv5HUMZqZDP2d3Z-9">
<mxGeometry relative="1" as="geometry">
<mxPoint x="310" y="170.0000000000001" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-16" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-4" target="D6qvsPv5HUMZqZDP2d3Z-17">
<mxGeometry relative="1" as="geometry">
<mxPoint x="360" y="175.0000000000001" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-4" value="Save&lt;div&gt;button&amp;nbsp;&lt;/div&gt;&lt;div&gt;clicked?&lt;/div&gt;" style="rhombus;whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="210" y="230" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-13" target="D6qvsPv5HUMZqZDP2d3Z-22">
<mxGeometry relative="1" as="geometry">
<mxPoint x="190" y="90" as="sourcePoint" />
<mxPoint x="150" y="150" as="targetPoint" />
<Array as="points">
<mxPoint x="90" y="150" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-12" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-9" target="D6qvsPv5HUMZqZDP2d3Z-11">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-21" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-9" target="D6qvsPv5HUMZqZDP2d3Z-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-9" value="Output&amp;nbsp;&lt;div&gt;directory&amp;nbsp;&lt;/div&gt;&lt;div&gt;exists?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="210" y="380" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-14" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-11" target="D6qvsPv5HUMZqZDP2d3Z-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-11" value="Create output directory" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="200" y="530" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-13" value="Save results to text file" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="30" y="250" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-19" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-17" target="D6qvsPv5HUMZqZDP2d3Z-18">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-17" value="OK button clicked?" style="rhombus;whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="363" y="230" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-18" value="Close results window" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="353" y="390" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-20" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-17" target="D6qvsPv5HUMZqZDP2d3Z-22">
<mxGeometry x="-0.6728" relative="1" as="geometry">
<Array as="points">
<mxPoint x="414" y="150" />
</Array>
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-22" value="Input loop start" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="200" y="120" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="D6qvsPv5HUMZqZDP2d3Z-23" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.502;entryY=0.045;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="D6qvsPv5HUMZqZDP2d3Z-22" target="D6qvsPv5HUMZqZDP2d3Z-4">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@@ -0,0 +1,242 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.15 Chrome/134.0.6998.205 Electron/35.2.1 Safari/537.36" version="26.2.15">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="2066" dy="1219" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="1654" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="RMgAkj6IqEivbKdGbQ9N-0" value="Retrieve details of platform from DB if applicable" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.start_1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="532" y="10" width="116" height="80" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-2" value="Any field edited?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="540" y="120" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-0" target="RMgAkj6IqEivbKdGbQ9N-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-58" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-4">
<mxGeometry x="-0.3442" y="-10" relative="1" as="geometry">
<mxPoint x="510" y="320" as="targetPoint" />
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-4" value="Any checkbox toggled?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="540" y="270" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-5" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-2" target="RMgAkj6IqEivbKdGbQ9N-4">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-6" value="Save updated platform details to list" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="528" y="900" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-52" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-7" target="RMgAkj6IqEivbKdGbQ9N-51">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-7" value="Add row clicked?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="540" y="430" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-61" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.747;exitY=0.74;exitDx=0;exitDy=0;exitPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-8">
<mxGeometry x="-0.847" relative="1" as="geometry">
<mxPoint x="820" y="930" as="targetPoint" />
<Array as="points">
<mxPoint x="670" y="674" />
<mxPoint x="670" y="930" />
</Array>
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-8" value="Remove row clicked?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="540" y="600" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-13" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-9" target="RMgAkj6IqEivbKdGbQ9N-6">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-9" value="Save button clicked?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="540" y="750" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-10" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-4" target="RMgAkj6IqEivbKdGbQ9N-7">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-11" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-7" target="RMgAkj6IqEivbKdGbQ9N-8">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-12" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-8" target="RMgAkj6IqEivbKdGbQ9N-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-19" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-15" target="RMgAkj6IqEivbKdGbQ9N-18">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-15" value="All&amp;nbsp;&lt;div&gt;required fields non zero?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="386" y="120" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-17" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-2" target="RMgAkj6IqEivbKdGbQ9N-15">
<mxGeometry x="0.1111" y="-10" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-22" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-18" target="RMgAkj6IqEivbKdGbQ9N-20">
<mxGeometry relative="1" as="geometry">
<mxPoint x="276" y="320" as="targetPoint" />
<Array as="points">
<mxPoint x="276" y="320" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-18" value="Mark main input not valid" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="216" y="140" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-23" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.37;exitY=0.89;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-20" target="RMgAkj6IqEivbKdGbQ9N-18">
<mxGeometry x="-0.4497" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-24" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-20" target="RMgAkj6IqEivbKdGbQ9N-25">
<mxGeometry relative="1" as="geometry">
<mxPoint x="436" y="400" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-20" value="Are&amp;nbsp;&lt;div&gt;all ACTIVE optional fields non-zero?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="386" y="270" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-21" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-15" target="RMgAkj6IqEivbKdGbQ9N-20">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-27" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-25" target="RMgAkj6IqEivbKdGbQ9N-26">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-25" value="Each row of&lt;div&gt;fund_plat_fee&lt;/div&gt;&lt;div&gt;bigger than&amp;nbsp;&lt;/div&gt;&lt;div&gt;the previous?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;fontSize=11;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="378.5" y="420" width="115" height="120" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-26" value="Mark fund platform fee input not valid" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="216" y="450" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-30" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-29" target="RMgAkj6IqEivbKdGbQ9N-26">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-29" value="Each&amp;nbsp;&lt;div&gt;fee field in fund_plat fee&lt;div&gt;non zero?&lt;/div&gt;&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;fontSize=11;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="386" y="590" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-31" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-25" target="RMgAkj6IqEivbKdGbQ9N-29">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-35" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-32" target="RMgAkj6IqEivbKdGbQ9N-34">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-32" value="Maximum&amp;nbsp;&lt;div&gt;number of rows&lt;/div&gt;&lt;div&gt;(6) reached?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;fontSize=11;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="386" y="750" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-33" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-29" target="RMgAkj6IqEivbKdGbQ9N-32">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-34" value="Disale add row button" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="376" y="900" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-39" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-37" target="RMgAkj6IqEivbKdGbQ9N-38">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-66" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.75;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-37" target="RMgAkj6IqEivbKdGbQ9N-50">
<mxGeometry x="-0.7078" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-37" value="Fund&lt;div&gt;platform fee input marked valid?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;fontSize=11;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="226" y="750" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-43" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-38" target="RMgAkj6IqEivbKdGbQ9N-42">
<mxGeometry relative="1" as="geometry">
<mxPoint x="276.0000000000002" y="1000" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-38" value="Enable add row button" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="216" y="900" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-40" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-32" target="RMgAkj6IqEivbKdGbQ9N-37">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-46" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-42" target="RMgAkj6IqEivbKdGbQ9N-44">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-47" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.198;entryY=0.298;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-42" target="RMgAkj6IqEivbKdGbQ9N-2">
<mxGeometry x="-0.9531" relative="1" as="geometry">
<mxPoint x="536" y="120" as="targetPoint" />
<Array as="points">
<mxPoint x="120" y="1060" />
<mxPoint x="120" y="110" />
<mxPoint x="560" y="110" />
</Array>
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-42" value="Is main input marked valid?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;fontSize=11;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="226" y="1010" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-44" value="Enable save button" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="216" y="1160" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-45" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-34" target="RMgAkj6IqEivbKdGbQ9N-42">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="436" y="1060" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-50" value="Disable save button" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="58" y="900" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-54" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-51" target="RMgAkj6IqEivbKdGbQ9N-53">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-51" value="Add new row of widgets to grid layout and list of widgets" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="690" y="450" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-56" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-53" target="RMgAkj6IqEivbKdGbQ9N-55">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-53" value="Expand grid layout to accommodate new row" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="690" y="560" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-57" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-55">
<mxGeometry relative="1" as="geometry">
<mxPoint x="510" y="170" as="targetPoint" />
<Array as="points">
<mxPoint x="750" y="991" />
<mxPoint x="751" y="991" />
<mxPoint x="751" y="1220" />
<mxPoint x="510" y="1220" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-55" value="Set new rows label to reflect the value of the previous box. Also update max fee label" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="690" y="670" width="120" height="80" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-60" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-9" target="RMgAkj6IqEivbKdGbQ9N-2">
<mxGeometry x="-0.9279" relative="1" as="geometry">
<Array as="points">
<mxPoint x="880" y="800" />
<mxPoint x="880" y="170" />
</Array>
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-64" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-62" target="RMgAkj6IqEivbKdGbQ9N-63">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-62" value="Remove each widget in the last row from the grid layout" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="820" y="900" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-65" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="RMgAkj6IqEivbKdGbQ9N-63">
<mxGeometry relative="1" as="geometry">
<mxPoint x="750" y="1120" as="targetPoint" />
<Array as="points">
<mxPoint x="880" y="1095" />
<mxPoint x="881" y="1095" />
<mxPoint x="881" y="1120" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="RMgAkj6IqEivbKdGbQ9N-63" value="Contract the grid layout to fit smaller number of rows" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="820" y="1010" width="120" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

View File

@@ -0,0 +1,176 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="753" dy="830" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-0" value="Get list of platforms from&amp;nbsp;&lt;div&gt;&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;DB&lt;/span&gt;&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.start_1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="363" y="50" width="100" height="60" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-10" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-1" target="uiKHp9CyL3H5hJtIc4hJ-9">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-1" value="Add platform clicked?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="363" y="160" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-0" target="uiKHp9CyL3H5hJtIc4hJ-1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-3">
<mxGeometry relative="1" as="geometry">
<mxPoint x="510" y="360" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-3" value="Remove&lt;div&gt;platform&lt;/div&gt;&lt;div&gt;clicked?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="363" y="310" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-4" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-1" target="uiKHp9CyL3H5hJtIc4hJ-3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-16" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-5" target="uiKHp9CyL3H5hJtIc4hJ-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-5" value="Edit platform clicked?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="363" y="460" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-6" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-3" target="uiKHp9CyL3H5hJtIc4hJ-5">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-27" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-7" target="uiKHp9CyL3H5hJtIc4hJ-26">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-7" value="Save button clicked?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="363" y="610" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-8" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-5" target="uiKHp9CyL3H5hJtIc4hJ-7">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-9" value="Show name dialog" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="190" y="130" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-13" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-11" target="uiKHp9CyL3H5hJtIc4hJ-14">
<mxGeometry relative="1" as="geometry">
<mxPoint x="249.75862068965523" y="370" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-18" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.247;entryY=0.262;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-11" target="uiKHp9CyL3H5hJtIc4hJ-1">
<mxGeometry x="-0.572" relative="1" as="geometry">
<mxPoint x="350" y="140" as="targetPoint" />
<Array as="points">
<mxPoint x="160" y="290" />
<mxPoint x="160" y="120" />
<mxPoint x="388" y="120" />
</Array>
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-11" value="Dialog&lt;div&gt;accepted?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="200" y="240" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-12" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-9" target="uiKHp9CyL3H5hJtIc4hJ-11">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-14" target="uiKHp9CyL3H5hJtIc4hJ-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-14" value="Add new platform to list" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="190" y="390" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-15" value="Show platform editor" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="190" y="500" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-25" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-20" target="uiKHp9CyL3H5hJtIc4hJ-24">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-20" value="Platform&lt;div&gt;editor saved?&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="200" y="610" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-21" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-15" target="uiKHp9CyL3H5hJtIc4hJ-20">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-23" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-20" target="uiKHp9CyL3H5hJtIc4hJ-1">
<mxGeometry x="-0.9007" relative="1" as="geometry">
<Array as="points">
<mxPoint x="250" y="1010" />
<mxPoint x="660" y="1010" />
<mxPoint x="660" y="210" />
</Array>
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-24" value="Delete new platform from list" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="30" y="630" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-26" value="Write updated platform list to DB" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="353" y="760" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-32" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-30" target="uiKHp9CyL3H5hJtIc4hJ-31">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-39" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-30">
<mxGeometry relative="1" as="geometry">
<mxPoint x="660" y="360" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-30" value="Is platform&lt;div&gt;present in&amp;nbsp;&lt;div&gt;on-disk DB&lt;/div&gt;&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="510" y="310" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-31" value="Show warning dialog" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="500" y="460" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-36" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-33" target="uiKHp9CyL3H5hJtIc4hJ-35">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-37" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-33">
<mxGeometry relative="1" as="geometry">
<mxPoint x="660" y="620" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-33" value="User accepted dialog?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="510" y="570" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-34" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-31" target="uiKHp9CyL3H5hJtIc4hJ-33">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-38" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-35">
<mxGeometry relative="1" as="geometry">
<mxPoint x="660" y="820" as="targetPoint" />
<Array as="points">
<mxPoint x="560" y="820" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-35" value="Delete platform from DB" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="500" y="720" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-42" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-40" target="uiKHp9CyL3H5hJtIc4hJ-41">
<mxGeometry x="-0.0811" y="-10" relative="1" as="geometry">
<mxPoint as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-44" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-40">
<mxGeometry relative="1" as="geometry">
<mxPoint x="660" y="990" as="targetPoint" />
<Array as="points">
<mxPoint x="413" y="990" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-40" value="Enable&amp;nbsp;&lt;div&gt;checkbox&amp;nbsp;&lt;/div&gt;&lt;div&gt;toggled&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="363" y="870" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-43" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-41">
<mxGeometry relative="1" as="geometry">
<mxPoint x="660" y="920.344827586207" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-41" value="Update platforms enable state in list" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="500" y="890" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="uiKHp9CyL3H5hJtIc4hJ-45" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="uiKHp9CyL3H5hJtIc4hJ-26" target="uiKHp9CyL3H5hJtIc4hJ-40">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View File

@@ -0,0 +1,83 @@
<mxfile host="Electron" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
<diagram id="C5RBs43oDa-KdzZeNtuy" name="Page-1">
<mxGraphModel dx="910" dy="1003" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="WIyWlLk6GJQsqaUBKTNV-1" parent="WIyWlLk6GJQsqaUBKTNV-0" />
<mxCell id="4t4bEUU0-kKJdhU_jB_B-0" value="Display/update graph of results" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.start_1;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="220" y="60" width="100" height="60" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-4" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0;exitY=0.5;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="4t4bEUU0-kKJdhU_jB_B-1" target="4t4bEUU0-kKJdhU_jB_B-0">
<mxGeometry relative="1" as="geometry">
<mxPoint x="180" y="90" as="targetPoint" />
<Array as="points">
<mxPoint x="180" y="220" />
<mxPoint x="180" y="90" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-6" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="4t4bEUU0-kKJdhU_jB_B-1" target="4t4bEUU0-kKJdhU_jB_B-7">
<mxGeometry relative="1" as="geometry">
<mxPoint x="270" y="320" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-1" value="Slider moved?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="220" y="170" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="4t4bEUU0-kKJdhU_jB_B-0" target="4t4bEUU0-kKJdhU_jB_B-1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-11" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="4t4bEUU0-kKJdhU_jB_B-7" target="4t4bEUU0-kKJdhU_jB_B-10">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="330" y="370" />
<mxPoint x="330" y="230" />
<mxPoint x="430" y="230" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-7" value="Output&lt;div&gt;graph button&lt;div&gt;clicked?&lt;/div&gt;&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="220" y="320" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-12" value="Yes" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="4t4bEUU0-kKJdhU_jB_B-8" target="4t4bEUU0-kKJdhU_jB_B-10">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="350" y="520" />
<mxPoint x="350" y="280" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-8" value="Output&amp;nbsp;&lt;div&gt;CSV button&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;clicked?&lt;/span&gt;&lt;/div&gt;" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="220" y="470" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-9" value="No" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="4t4bEUU0-kKJdhU_jB_B-7" target="4t4bEUU0-kKJdhU_jB_B-8">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-10" value="Show file dialog" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="370" y="250" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="4t4bEUU0-kKJdhU_jB_B-13" target="4t4bEUU0-kKJdhU_jB_B-15">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-13" value="File writable?" style="strokeWidth=2;html=1;shape=mxgraph.flowchart.decision;whiteSpace=wrap;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="380" y="360" width="100" height="100" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="4t4bEUU0-kKJdhU_jB_B-10" target="4t4bEUU0-kKJdhU_jB_B-13">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="WIyWlLk6GJQsqaUBKTNV-1" source="4t4bEUU0-kKJdhU_jB_B-15" target="4t4bEUU0-kKJdhU_jB_B-1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="530" y="90" as="targetPoint" />
<Array as="points">
<mxPoint x="530" y="540" />
<mxPoint x="530" y="220" />
</Array>
</mxGeometry>
</mxCell>
<mxCell id="4t4bEUU0-kKJdhU_jB_B-15" value="Save results to CSV or PNG file" style="whiteSpace=wrap;html=1;strokeWidth=2;" vertex="1" parent="WIyWlLk6GJQsqaUBKTNV-1">
<mxGeometry x="370" y="510" width="120" height="60" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -10,6 +10,18 @@
<height>100</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>100</height>
</size>
</property>
<property name="windowTitle">
<string>Name Platform</string>
</property>

View File

@@ -25,9 +25,6 @@
<property name="windowTitle">
<string>SIPPCompare</string>
</property>
<property name="tabShape">
<enum>QTabWidget::TabShape::Rounded</enum>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QWidget" name="formLayoutWidget">
<property name="geometry">
@@ -35,7 +32,7 @@
<x>10</x>
<y>0</y>
<width>401</width>
<height>184</height>
<height>188</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
@@ -70,9 +67,6 @@
<pointsize>11</pointsize>
</font>
</property>
<property name="frame">
<bool>true</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::ButtonSymbols::NoButtons</enum>
</property>
@@ -145,18 +139,6 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="fund_trades_combo">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QPushButton" name="calc_but">
<property name="enabled">
@@ -173,14 +155,35 @@
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="share_trades_combo">
<widget class="FastEditQSpinBox" name="share_trades_box">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="editable">
<bool>true</bool>
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
</property>
<property name="prefix">
<string/>
</property>
<property name="maximum">
<number>999</number>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="FastEditQSpinBox" name="fund_trades_box">
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="correctionMode">
<enum>QAbstractSpinBox::CorrectionMode::CorrectToNearestValue</enum>
</property>
<property name="prefix">
<string/>
</property>
</widget>
</item>
@@ -188,9 +191,6 @@
</widget>
</widget>
<widget class="QStatusBar" name="statusbar">
<property name="enabled">
<bool>true</bool>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
@@ -235,11 +235,18 @@
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>FastEditQSpinBox</class>
<extends>QSpinBox</extends>
<header>widgets/fastedit_spinbox</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>value_input</tabstop>
<tabstop>mix_slider</tabstop>
<tabstop>share_trades_combo</tabstop>
<tabstop>fund_trades_combo</tabstop>
<tabstop>share_trades_box</tabstop>
<tabstop>fund_trades_box</tabstop>
<tabstop>calc_but</tabstop>
</tabstops>
<resources/>

View File

@@ -7,9 +7,21 @@
<x>0</x>
<y>0</y>
<width>1330</width>
<height>630</height>
<height>685</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>1330</width>
<height>685</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>1330</width>
<height>685</height>
</size>
</property>
<property name="windowTitle">
<string>Results</string>
</property>
@@ -23,6 +35,85 @@
</rect>
</property>
</widget>
<widget class="QPushButton" name="save_graph_but">
<property name="geometry">
<rect>
<x>1231</x>
<y>642</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Save graph</string>
</property>
</widget>
<widget class="QSlider" name="time_slider">
<property name="geometry">
<rect>
<x>370</x>
<y>635</y>
<width>581</width>
<height>41</height>
</rect>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="tickPosition">
<enum>QSlider::TickPosition::TicksAbove</enum>
</property>
<property name="tickInterval">
<number>1</number>
</property>
</widget>
<widget class="QPushButton" name="save_csv_but">
<property name="geometry">
<rect>
<x>1134</x>
<y>642</y>
<width>91</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Save CSV</string>
</property>
</widget>
<widget class="QLabel" name="time_lab">
<property name="geometry">
<rect>
<x>10</x>
<y>640</y>
<width>341</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Fees over 1 year(s) (assuming no change in value)</string>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
@@ -32,6 +123,11 @@
<container>1</container>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>time_slider</tabstop>
<tabstop>save_csv_but</tabstop>
<tabstop>save_graph_but</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@@ -2,27 +2,36 @@
<ui version="4.0">
<class>PlatformEdit</class>
<widget class="QWidget" name="PlatformEdit">
<property name="windowModality">
<enum>Qt::WindowModality::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>630</width>
<height>567</height>
<height>580</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>630</width>
<height>580</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>630</width>
<height>580</height>
</size>
</property>
<property name="windowTitle">
<string>Platform Editor</string>
</property>
<widget class="QWidget" name="gridLayoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<x>13</x>
<y>20</y>
<width>611</width>
<height>241</height>
<width>616</width>
<height>242</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
@@ -42,10 +51,13 @@
<number>10</number>
</property>
<property name="verticalSpacing">
<number>5</number>
<number>6</number>
</property>
<item row="0" column="3">
<widget class="QCheckBox" name="plat_name_check">
<property name="text">
<string> </string>
</property>
<property name="checked">
<bool>true</bool>
</property>
@@ -218,7 +230,7 @@
</font>
</property>
<property name="text">
<string>Fund dealing fee*</string>
<string>Fund dealing fee</string>
</property>
</widget>
</item>
@@ -324,7 +336,7 @@
<property name="geometry">
<rect>
<x>482</x>
<y>534</y>
<y>545</y>
<width>141</width>
<height>24</height>
</rect>
@@ -342,7 +354,7 @@
<property name="geometry">
<rect>
<x>8</x>
<y>262</y>
<y>549</y>
<width>191</width>
<height>21</height>
</rect>
@@ -354,7 +366,7 @@
<widget class="QLabel" name="active_lab">
<property name="geometry">
<rect>
<x>577</x>
<x>572</x>
<y>10</y>
<width>61</width>
<height>16</height>
@@ -370,16 +382,28 @@
<widget class="QWidget" name="gridLayoutWidget_2">
<property name="geometry">
<rect>
<x>11</x>
<y>309</y>
<width>611</width>
<height>31</height>
<x>19</x>
<y>307</y>
<width>591</width>
<height>40</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="verticalSpacing">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="3">
<widget class="FastEditQDoubleSpinBox" name="first_tier_fee_box">
<property name="font">
@@ -455,7 +479,7 @@
<property name="geometry">
<rect>
<x>532</x>
<y>481</y>
<y>487</y>
<width>91</width>
<height>24</height>
</rect>
@@ -476,7 +500,7 @@
<property name="geometry">
<rect>
<x>440</x>
<y>481</y>
<y>487</y>
<width>91</width>
<height>24</height>
</rect>
@@ -493,8 +517,8 @@
<widget class="QLabel" name="val_above_lab">
<property name="geometry">
<rect>
<x>6</x>
<y>479</y>
<x>10</x>
<y>486</y>
<width>421</width>
<height>21</height>
</rect>
@@ -508,16 +532,34 @@
<string>on the value above £ there is no charge</string>
</property>
</widget>
<widget class="QLabel" name="fund_plat_fee_lab">
<property name="geometry">
<rect>
<x>10</x>
<y>285</y>
<width>151</width>
<height>16</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>11</pointsize>
</font>
</property>
<property name="text">
<string>Fund platform fee*</string>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>FastEditQDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<class>FastEditQSpinBox</class>
<extends>QSpinBox</extends>
<header>widgets/fastedit_spinbox</header>
</customwidget>
<customwidget>
<class>FastEditQSpinBox</class>
<extends>QSpinBox</extends>
<class>FastEditQDoubleSpinBox</class>
<extends>QDoubleSpinBox</extends>
<header>widgets/fastedit_spinbox</header>
</customwidget>
</customwidgets>

View File

@@ -2,17 +2,26 @@
<ui version="4.0">
<class>PlatformList</class>
<widget class="QWidget" name="PlatformList">
<property name="windowModality">
<enum>Qt::WindowModality::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>264</width>
<width>263</width>
<height>473</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>263</width>
<height>473</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>263</width>
<height>473</height>
</size>
</property>
<property name="windowTitle">
<string>Platform List</string>
</property>
@@ -50,6 +59,9 @@
</property>
</widget>
<widget class="QPushButton" name="del_plat_but">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>135</x>
@@ -86,6 +98,9 @@
</property>
</widget>
<widget class="QPushButton" name="edit_plat_but">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>11</x>
@@ -104,6 +119,9 @@
</property>
</widget>
<widget class="QCheckBox" name="plat_enabled_check">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>12</x>
@@ -122,6 +140,14 @@
</property>
</widget>
</widget>
<tabstops>
<tabstop>platListWidget</tabstop>
<tabstop>add_plat_but</tabstop>
<tabstop>del_plat_but</tabstop>
<tabstop>edit_plat_but</tabstop>
<tabstop>plist_save_but</tabstop>
<tabstop>plat_enabled_check</tabstop>
</tabstops>
<resources/>
<connections>
<connection>

View File

@@ -80,6 +80,7 @@ class DBHandler:
return plat_name_list
# Write updated platform data to DB when changes are saved
def write_platforms(self, plat_list: list[Platform]):
for i in range(len(plat_list)):
platforms_data = [
@@ -242,7 +243,20 @@ class DBHandler:
return user_details_dict
def toggle_platform_state(self, index: int, state: bool):
state_data = [state, index]
self.cur.execute("UPDATE tblPlatforms SET IsEnabled = ? WHERE PlatformID = ?", state_data)
# Remove a platform from the DB - update the IDs to keep them sequential
def remove_platform(self, index: int):
tbl_list = ["tblPlatforms", "tblFlatPlatFees", "tblFlatDealFees", "tblFundPlatFee"]
for tbl in tbl_list:
self.cur.execute(f"DELETE FROM {tbl} WHERE PlatformID = {index}")
res = self.cur.execute("SELECT PlatformID from tblPlatforms").fetchall()
n = len(res)
for i in range(n):
for tbl in tbl_list:
self.cur.execute(f"""
UPDATE {tbl}
SET PlatformID = {index + i}
WHERE PlatformID = {index + 1 + i}
""")
self.conn.commit()

View File

@@ -1,3 +1,16 @@
## Nuitka compilation options (Windows only)
# nuitka-project: --mode=onefile
# nuitka-project: --enable-plugin=pyqt6
# nuitka-project: --include-module=widgets.mpl_widget
# nuitka-project: --include-data-files=icon2.ico=icon2.ico
# nuitka-project: --include-data-dir=gui=gui
# nuitka-project: --windows-console-mode=disable
# nuitka-project: --windows-icon-from-ico=icon2.ico
# nuitka-project: --product-name=SIPPCompare
# nuitka-project: --file-description=SIPPCompare
# nuitka-project: --product-version=1.1
# nuitka-project: --output-dir=build
# nuitka-project: --output-filename=SIPPCompare
import sys
from PyQt6.QtWidgets import QApplication

View File

@@ -1,33 +1,22 @@
from PyQt6 import uic
from PyQt6.QtCore import QTimer
from PyQt6.QtGui import QIntValidator, QIcon
from PyQt6.QtWidgets import QMainWindow
from PyQt6.QtWidgets import QMainWindow, QApplication
import resource_finder
from db_handler import DBHandler
from output_window import OutputWindow
from platform_list import PlatformList
from output_window import OutputWindow
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")))
# Initialise class variables
# Inputs
self.optional_boxes = []
self.fund_plat_fee = 0.0
self.plat_name = ""
self.fund_deal_fee = 0.0
self.share_plat_fee = 0.0
self.share_plat_max_fee = 0.0
self.share_deal_fee = 0.0
self.share_deal_reduce_trades = 0.0
self.share_deal_reduce_amount = 0.0
## Initialise class variables
# Results
self.fund_plat_fees = 0.0
self.fund_deal_fees = 0.0
@@ -38,29 +27,28 @@ class SIPPCompare(QMainWindow):
# Create window objects
self.db = DBHandler()
self.platform_list_win = PlatformList(self.db)
self.output_win = OutputWindow()
if len(self.platform_list_win.plat_name_list) == 0:
QTimer.singleShot(1, self.platform_list_win.show)
self.output_win = None
# Handle events
self.calc_but.clicked.connect(self.calculate_fees)
# Menu bar entry (File -> Edit Platforms)
## Handle events
self.calc_but.clicked.connect(self.indicate_loading)
# Menu bar entry (File -> Platform List)
self.actionList_Platforms.triggered.connect(self.show_platform_list)
# Update percentage mix label when slider moved
self.mix_slider.valueChanged.connect(self.update_slider_lab)
self.value_input.valueChanged.connect(self.check_valid)
self.share_trades_combo.currentTextChanged.connect(self.check_valid)
self.fund_trades_combo.currentTextChanged.connect(self.check_valid)
# Validate input
self.share_trades_box.valueChanged.connect(self.check_valid)
self.fund_trades_box.valueChanged.connect(self.check_valid)
# Set validators
self.share_trades_combo.setValidator(QIntValidator(0, 999))
self.fund_trades_combo.setValidator(QIntValidator(0, 99))
# Restore last session
## Restore last session
prev_session_data = self.db.retrieve_user_details()
if "NO_RECORD" not in prev_session_data:
self.value_input.setValue(prev_session_data["pension_val"])
self.mix_slider.setValue(prev_session_data["slider_val"])
self.share_trades_combo.setCurrentText(str(prev_session_data["share_trades"]))
self.fund_trades_combo.setCurrentText(str(prev_session_data["fund_trades"]))
self.share_trades_box.setValue(prev_session_data["share_trades"])
self.fund_trades_box.setValue(prev_session_data["fund_trades"])
self.calc_but.setFocus()
# Display slider position as mix between two nums (funds/shares)
@@ -69,15 +57,18 @@ class SIPPCompare(QMainWindow):
mix_lab_str = f"Investment mix (funds {slider_val}% / shares {100 - slider_val}%)"
self.mix_lab.setText(mix_lab_str)
# Ensure that trade fields aren't blank and pension value > 0
def check_valid(self):
if self.share_trades_combo.currentText() != "" \
and self.fund_trades_combo.currentText() != "" \
and self.value_input.value() != 0:
if self.value_input.value() != 0:
self.calc_but.setEnabled(True)
else:
self.calc_but.setEnabled(False)
# Calculate fees
def indicate_loading(self):
self.calc_but.setText("Working...")
QTimer.singleShot(1, self.calculate_fees)
# Calculate fees for all active platforms
def calculate_fees(self):
# Set to empty list each time to avoid persistence
self.results = []
@@ -85,21 +76,27 @@ class SIPPCompare(QMainWindow):
# 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_value = (slider_val / 100) * value_num
fund_trades_num = int(self.fund_trades_box.value())
share_trades_num = int(self.share_trades_box.value())
shares_value = (1 - (slider_val / 100)) * value_num
index = 0
for platform in self.platform_list_win.plat_list:
if not platform.enabled:
continue
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 plat_name is None or plat_name == "":
plat_name = f"Unnamed [ID: {index}]"
if platform.fund_deal_fee is not None:
fund_deal_fees = fund_trades_num * platform.fund_deal_fee
funds_value = (slider_val / 100) * value_num
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]
@@ -126,15 +123,24 @@ class SIPPCompare(QMainWindow):
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])
index += 1
# Save details entered by user for next session
self.db.write_user_details(value_num, slider_val, share_trades_num, fund_trades_num)
self.show_output_win()
# 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.results)
if self.output_win is None:
self.output_win = OutputWindow()
years = self.output_win.get_slider_position()
self.output_win.display_output(self.results, years)
self.calc_but.setText("Calculate")
self.output_win.activateWindow()
self.output_win.raise_()
self.output_win.show()
QApplication.alert(self.output_win)
def show_platform_list(self):
self.platform_list_win.show()

View File

@@ -1,13 +1,33 @@
import datetime
import os
from datetime import datetime
from PyQt6 import uic
from PyQt6.QtGui import QIcon
from PyQt6.QtWidgets import QWidget
from PyQt6.QtGui import QIcon, QFont
from PyQt6.QtWidgets import QWidget, QFileDialog, QMessageBox, QDialogButtonBox
import resource_finder
class SaveFailure(QMessageBox):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowIcon(QIcon(resource_finder.get_res_path("icon2.ico")))
self.setWindowTitle("Save failure")
self.setIcon(QMessageBox.Icon.Critical)
font = QFont()
font.setPointSize(11)
self.setFont(font)
self.setText("Failed to save file")
self.setDetailedText(
"This could be due to a permissions issue, or the file being in use by another process"
)
self.setStandardButtons(QMessageBox.StandardButton.Ok)
font.setPointSize(10)
self.findChild(QDialogButtonBox).setFont(font)
class OutputWindow(QWidget):
def __init__(self):
super().__init__()
@@ -15,17 +35,106 @@ 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")))
def display_output(self, results: list):
ax = self.graphWidget.canvas.axes
ax.clear()
ax.cla()
self.graphWidget.canvas.draw_idle()
# Define class variables
self.save_err_dialog = SaveFailure()
self.canvas = self.graphWidget.canvas
self.ax = self.canvas.axes
self.fig = self.canvas.figure
self.results = []
# Handle events
self.save_graph_but.clicked.connect(self.save_graph)
self.save_csv_but.clicked.connect(self.save_csv)
self.time_slider.valueChanged.connect(self.change_time)
def get_slider_position(self) -> int:
return self.time_slider.value()
def display_output(self, results: list, years: int):
self.results = results
self.ax.clear()
self.ax.cla()
self.canvas.draw_idle()
names = []
values = []
for result in results:
names.append(result[4])
values.append(sum(result[:4]))
values.append(sum(result[:4]) * years)
h_bars = ax.barh(names, values)
ax.bar_label(h_bars, label_type='center', labels=[f"£{x:,.2f}" for x in h_bars.datavalues])
names = sorted(names, key=lambda x: values[names.index(x)], reverse=True)
values = sorted(values, reverse=True)
h_bars = self.ax.barh(names, values)
self.ax.bar_label(h_bars, label_type='center', labels=[f"£{x:,.2f}" for x in h_bars.datavalues])
def save_graph(self):
file_picker = QFileDialog(self)
file_picker.setFileMode(QFileDialog.FileMode.AnyFile)
file_picker.setDefaultSuffix("png")
file_picker.setWindowTitle("Save results as PNG")
file_picker.setAcceptMode(QFileDialog.AcceptMode.AcceptSave)
file_picker.setNameFilter("*.png")
file_path = ""
cur_time = datetime.now()
filename_str = f"{file_path}/SIPPCompare-{cur_time.year}.{cur_time.month}.{cur_time.day}.png"
file_picker.selectFile(filename_str)
if file_picker.exec():
file_path = file_picker.selectedFiles()[0]
try:
self.fig.savefig(file_path, dpi=150)
except OSError:
self.save_err_dialog.exec()
def save_csv(self):
# TODO: Sort CSV output, either alphabetically or by total fees
file_picker = QFileDialog(self)
file_picker.setFileMode(QFileDialog.FileMode.AnyFile)
file_picker.setDefaultSuffix("csv")
file_picker.setWindowTitle("Save results as CSV")
file_picker.setAcceptMode(QFileDialog.AcceptMode.AcceptSave)
file_picker.setNameFilter("*.csv")
file_path = ""
cur_time = datetime.now()
filename_str = f"{file_path}/SIPPCompare-{cur_time.year}.{cur_time.month}.{cur_time.day}.csv"
file_picker.selectFile(filename_str)
if file_picker.exec():
file_path = file_picker.selectedFiles()[0]
try:
csvfile = open(file_path, "wt")
csv_string = (
"Platform Name,Fund Platform Fee,Share Platform Fee,Fund Dealing Fee,"
"Share Dealing Fee,Total Platform Fees,Total Dealing Fees,Total Fund Fees,"
"Total Share Fees,Total Fees"
)
for result in self.results:
csv_string += '\n'
pn = result[4]
fpf = result[0]
spf = result[2]
fdf = result[1]
sdf = result[3]
tpf = fpf + spf
tdf = sdf + fdf
tff = fpf + fdf
tsf = spf + sdf
tf = tff + tsf
csv_string += (
f"{pn},\"£{fpf:,.2f}\",\"£{spf:,.2f}\",\"£{fdf:,.2f}\",\"£{sdf:,.2f}\","
f"\"£{tpf:,.2f}\",\"£{tdf:,.2f}\",\"£{tff:,.2f}\",\"£{tsf:,.2f}\",\"£{tf:,.2f}\""
)
csvfile.write(csv_string)
csvfile.close()
except OSError:
self.save_err_dialog.exec()
def change_time(self):
years: int = self.time_slider.value()
self.time_lab.setText(f"Fees over {years} year(s) (assuming no change in value)")
self.display_output(self.results, years)

View File

@@ -1,7 +1,7 @@
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.QtWidgets import QLabel, QDialog
import resource_finder
from db_handler import DBHandler
@@ -9,7 +9,7 @@ from data_struct import Platform
from widgets.fastedit_spinbox import FastEditQDoubleSpinBox
class PlatformEdit(QWidget):
class PlatformEdit(QDialog):
def __init__(self, plat: Platform):
super().__init__()
# Import Qt Designer UI XML file
@@ -18,7 +18,6 @@ class PlatformEdit(QWidget):
# Initialise class variables
self.plat = plat
self.fund_plat_fee = self.plat.fund_plat_fee
self.widgets_list_list = []
if len(self.plat.fund_plat_fee[0]) > 1:
self.fund_fee_rows = len(self.plat.fund_plat_fee[0]) - 1
@@ -65,7 +64,7 @@ class PlatformEdit(QWidget):
if self.plat.fund_deal_fee is None:
self.check_boxes_ticked[1] = False
self.plat_fund_deal_fee_check.setChecked(False)
self.fund_deal_fee_check.setChecked(False)
else:
self.check_boxes_ticked[1] = True
self.fund_deal_fee_check.setChecked(True)
@@ -178,6 +177,8 @@ class PlatformEdit(QWidget):
else:
self.plat.share_deal_reduce_amount = None
self.accept()
# This method does multiple things in order to validate the user's inputs:
# 1) Check all required fields have a non-zero value
# 2) If an optional checkbox is toggled: toggle editing of the corresponding field
@@ -254,9 +255,18 @@ class PlatformEdit(QWidget):
if self.fund_fee_rows > 1:
max_band = self.widgets_list_list[self.fund_fee_rows - 2][1].value()
if self.fund_fee_rows > 2:
prev_band = self.widgets_list_list[self.fund_fee_rows - 3][1].value()
else:
prev_band = self.first_tier_box.value()
else:
max_band = self.first_tier_box.value()
self.val_above_lab.setText(f"on the value above £{int(max_band)} there is no charge")
prev_band = self.first_tier_box.value()
if max_band > prev_band:
self.val_above_lab.setText(f"on the value above £{max_band:.2f} there is no charge")
else:
self.val_above_lab.setText(f"on the value above £{prev_band:.2f} there is no charge")
def add_row(self, loading: bool = False):
if loading:
@@ -299,7 +309,7 @@ class PlatformEdit(QWidget):
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))
self.gridLayoutWidget_2.setGeometry(QRect(19, 307, 591, grid_height))
for i in range(len(widgets)):
if loading:
self.gridLayout_2.addWidget(widgets[i], x + 1, i, 1, 1)
@@ -317,8 +327,6 @@ class PlatformEdit(QWidget):
prev_box_row = cur_box_pos[0] - 1
prev_box_item = self.gridLayout_2.itemAtPosition(prev_box_row, cur_box_pos[1]).widget()
#if loading:
# prev_box_item.setValue(self.plat.fund_plat_fee[0][x+1])
cur_label_item = self.gridLayout_2.itemAtPosition(cur_label_pos[0], cur_label_pos[1]).widget()
cur_label_item.setText(f"between £{int(prev_box_item.value())} and")
@@ -339,7 +347,7 @@ class PlatformEdit(QWidget):
widget.hide()
self.widgets_list_list.pop()
self.fund_fee_rows -= 1
self.gridLayoutWidget_2.setGeometry(11, 309, 611, int(round(28.5 * self.fund_fee_rows, 0)))
self.gridLayoutWidget_2.setGeometry(19, 307, 591, int(round(28.5 * self.fund_fee_rows, 0)))
if self.fund_fee_rows < 2:
self.del_row_but.setEnabled(False)
@@ -349,3 +357,7 @@ class PlatformEdit(QWidget):
self.check_valid()
self.update_tier_labels()
def closeEvent(self, event):
event.ignore()
self.reject()

View File

@@ -1,7 +1,7 @@
from PyQt6 import uic
from PyQt6.QtCore import QRegularExpression
from PyQt6.QtGui import QIcon, QRegularExpressionValidator
from PyQt6.QtWidgets import QWidget, QListWidgetItem, QDialog
from PyQt6.QtGui import QIcon, QRegularExpressionValidator, QFont
from PyQt6.QtWidgets import QWidget, QListWidgetItem, QDialog, QDialogButtonBox, QMessageBox
import resource_finder
from db_handler import DBHandler
@@ -34,6 +34,25 @@ class PlatformRename(QDialog):
event.ignore()
self.reject()
class RemoveConfirm(QMessageBox):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowIcon(QIcon(resource_finder.get_res_path("icon2.ico")))
self.setWindowTitle("Remove platform?")
self.setIcon(QMessageBox.Icon.Warning)
font = QFont()
font.setPointSize(11)
self.setFont(font)
self.setText("Are you sure you want to remove this platform?")
self.setInformativeText("This action is immediate and permanent")
self.setStandardButtons(QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.Cancel)
self.setDefaultButton(QMessageBox.StandardButton.Cancel)
font.setPointSize(10)
self.findChild(QDialogButtonBox).setFont(font)
class PlatformList(QWidget):
def __init__(self, db: DBHandler):
super().__init__()
@@ -41,23 +60,16 @@ class PlatformList(QWidget):
uic.loadUi(resource_finder.get_res_path("gui/platform_list.ui"), self)
self.setWindowIcon(QIcon(resource_finder.get_res_path("icon2.ico")))
# Initialise class variables
self.db = db
self.plat_edit_win = None
self.plat_list_dialog = PlatformRename()
self.plat_list_dialog = None
self.del_plat_dialog = RemoveConfirm()
self.plat_list = []
self.plat_name_list = []
self.new_plat_name = ""
self.update_plat_list()
for i in range(len(self.plat_name_list)):
plat_name = self.plat_name_list[i]
item = QListWidgetItem()
if plat_name is not None:
item.setText(plat_name)
else:
item.setText(f"Unnamed [ID: {i}]")
self.platListWidget.addItem(item)
self.db_indices = [x for x in range(len(self.plat_name_list))]
# Handle events
self.add_plat_but.clicked.connect(self.add_platform)
@@ -70,8 +82,21 @@ class PlatformList(QWidget):
def update_plat_list(self):
self.plat_name_list = self.db.retrieve_plat_list()
self.plat_list = self.db.retrieve_platforms()
self.platListWidget.clear()
for i in range(len(self.plat_name_list)):
plat_name = self.plat_name_list[i]
item = QListWidgetItem()
if plat_name is not None:
item.setText(plat_name)
else:
item.setText(f"Unnamed [ID: {i}]")
self.platListWidget.addItem(item)
self.platListWidget.setCurrentRow(0)
def add_platform(self):
self.plat_list_dialog = PlatformRename()
name_dialog_res = self.plat_list_dialog.exec()
if name_dialog_res == QDialog.DialogCode.Accepted:
name = self.plat_list_dialog.new_name
@@ -87,28 +112,74 @@ class PlatformList(QWidget):
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()
plat_edit_res = self.plat_edit_win.exec()
if plat_edit_res == QDialog.DialogCode.Rejected:
self.plat_list.pop()
self.platListWidget.takeItem(self.platListWidget.count() - 1)
self.platListWidget.setCurrentRow(index - 1)
else:
index = len(self.plat_list) - 1
if self.plat_list[index].plat_name is not None:
item = self.platListWidget.takeItem(index)
item.setText(self.plat_list[index].plat_name)
self.platListWidget.insertItem(index, item)
self.platListWidget.setCurrentRow(index)
def get_enabled_state(self):
index = self.platListWidget.currentRow()
is_enabled = self.plat_list[index].enabled
if is_enabled:
self.plat_enabled_check.setChecked(True)
if len(self.plat_list) > 0:
is_enabled = self.plat_list[index].enabled
if is_enabled:
self.plat_enabled_check.setChecked(True)
else:
self.plat_enabled_check.setChecked(False)
else:
self.plat_enabled_check.setChecked(False)
if index in self.db_indices:
self.del_plat_but.setEnabled(True)
else:
self.del_plat_but.setEnabled(False)
valid_selection = False
for plat in self.plat_list:
if plat.plat_id == index:
valid_selection = True
if valid_selection:
self.edit_plat_but.setEnabled(True)
self.plat_enabled_check.setEnabled(True)
else:
self.edit_plat_but.setEnabled(False)
self.plat_enabled_check.setEnabled(False)
def edit_platform(self):
index = self.platListWidget.currentRow()
self.plat_edit_win = PlatformEdit(self.plat_list[index])
self.plat_edit_win.show()
plat_edit_res = self.plat_edit_win.exec()
if plat_edit_res == QDialog.DialogCode.Accepted:
item = self.platListWidget.takeItem(index)
item.setText(self.plat_list[index].plat_name)
self.platListWidget.insertItem(index, item)
self.platListWidget.setCurrentRow(index)
def save_platforms(self):
self.db.write_platforms(self.plat_list)
self.update_plat_list()
self.db_indices = [x for x in range(len(self.plat_name_list))]
def toggle_platform_state(self):
index = self.platListWidget.currentRow()
state = self.plat_enabled_check.isChecked()
self.db.toggle_platform_state(index, state)
if len(self.plat_list) > 0 and index >= 0:
self.plat_list[index].enabled = state
def remove_platform(self):
return None
index = self.platListWidget.currentRow()
del_dialog_res = self.del_plat_dialog.exec()
if del_dialog_res == QMessageBox.StandardButton.Yes:
self.db.remove_platform(index)
self.update_plat_list()
def showEvent(self, event):
self.get_enabled_state()

View File

@@ -2,12 +2,24 @@ import os.path
import sys
# If using PyInstaller, use it's temporary path, otherwise use cwd
# Credit: https://stackoverflow.com/questions/7674790/bundling-data-files-with-pyinstaller-onefile/13790741#13790741
# Returns the correct path for Nuitka onefile mode, standalone mode or normal Python
# Credit: https://nuitka.net/user-documentation/common-issue-solutions.html#onefile-finding-files
def get_res_path(relative_path):
try:
base_path = sys._MEIPASS
except AttributeError:
base_path = os.path.abspath(".")
path_a = ""
return os.path.join(base_path, relative_path)
try:
path_a = os.path.join(sys.__compiled__.containing_dir, relative_path)
except AttributeError:
pass
path_b = os.path.join(os.path.dirname(__file__), relative_path)
path_c = os.path.join(os.path.dirname(sys.argv[0]), relative_path)
if os.path.isfile(path_a):
return path_a
elif os.path.isfile(path_b):
return path_b
elif os.path.isfile(path_c):
return path_c
else:
return os.path.join(os.path.abspath("."), relative_path)

View File

@@ -7,6 +7,7 @@ class FastEditQDoubleSpinBox(QDoubleSpinBox):
QTimer.singleShot(0, self.selectAll)
super(FastEditQDoubleSpinBox, self).focusInEvent(e)
class FastEditQSpinBox(QSpinBox):
def focusInEvent(self, e):
QTimer.singleShot(0, self.selectAll)

View File

@@ -6,8 +6,8 @@ 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))
self.canvas = FigureCanvasQTAgg(Figure(figsize=(15, 8), dpi=100))
vertical_layout = QVBoxLayout()
vertical_layout.addWidget(self.canvas)
self.canvas.axes = self.canvas.figure.add_subplot(1, 1, 1)
self.setLayout(vertical_layout)
self.setLayout(vertical_layout)