diff --git a/banking_breakdown/__main__.py b/banking_breakdown/__main__.py index 94d1178..bbbfb09 100644 --- a/banking_breakdown/__main__.py +++ b/banking_breakdown/__main__.py @@ -12,6 +12,9 @@ def categorize_func(args): if args.i is not None: df = get_stripped_statement(args.i) + import signal + signal.signal(signal.SIGINT, signal.SIG_DFL) + ui.show_main_window(df=df) diff --git a/banking_breakdown/statement_parser.py b/banking_breakdown/statement_parser.py index fce14df..0fd5c0c 100644 --- a/banking_breakdown/statement_parser.py +++ b/banking_breakdown/statement_parser.py @@ -82,16 +82,18 @@ import numpy as np def get_stripped_statement(filename: str) -> pd.DataFrame: - df = pd.read_csv(filename, delimiter=';', decimal=",") - df["Valutadatum"] = pd.to_datetime(df["Valutadatum"], format='%d.%m.%Y') + # df = pd.read_csv(filename, delimiter=';', decimal=",") + df = pd.read_csv(filename, delimiter=';') + df["Valutadatum"] = (pd.to_datetime(df["Valutadatum"], format='%d.%m.%Y') + .dt.strftime('%Y-%m-%d')) result = pd.DataFrame({'t': df["Valutadatum"], 'other party': df["Name Zahlungsbeteiligter"], 'value': df["Betrag"], - 'balance afterwards': df["Saldo nach Buchung"], + 'balance': df["Saldo nach Buchung"], + 'category': [''] * len(df["Valutadatum"]), 'description': df["Buchungstext"], 'purpose': df["Verwendungszweck"] }) - result['category'] = [''] * len(result.index) return result diff --git a/banking_breakdown/ui/__init__.py b/banking_breakdown/ui/__init__.py index 0817bc1..d1f5653 100644 --- a/banking_breakdown/ui/__init__.py +++ b/banking_breakdown/ui/__init__.py @@ -18,15 +18,15 @@ def show_main_window(categories: typing.Sequence[str] = None, if df is not None: window.set_statement_data(df) - window.add_warning_text("The column 't' does not exist. Please rename the" - " column containing the dates of the transactions" - " to 't'.") - window.add_warning_text("The column 'balance' does not exist. Please" - " rename the column containing the balance after" - " each transaction to 'balance'") - window.add_warning_text("The column 'value' does not exist. Please rename" - " the column containing the values of the" - " transactions to 'value'.") + # window.add_warning_text("The column 't' does not exist. Please rename the" + # " column containing the dates of the transactions" + # " to 't'.") + # window.add_warning_text("The column 'balance' does not exist. Please" + # " rename the column containing the balance after" + # " each transaction to 'balance'") + # window.add_warning_text("The column 'value' does not exist. Please rename" + # " the column containing the values of the" + # " transactions to 'value'.") window.show() app.exec() diff --git a/banking_breakdown/ui/generated_wrapper.py b/banking_breakdown/ui/generated_wrapper.py index 5e7efa2..87d3321 100644 --- a/banking_breakdown/ui/generated_wrapper.py +++ b/banking_breakdown/ui/generated_wrapper.py @@ -2,10 +2,11 @@ import typing from functools import partial import pandas as pd -from PyQt6.QtGui import QPixmap -from PyQt6.QtWidgets import QMainWindow, QTableView, QHBoxLayout, QLabel -from PyQt6 import uic, QtGui, QtCore -from PyQt6.QtCore import Qt +from PyQt6.QtGui import QPixmap, QAction +from PyQt6.QtWidgets import QMainWindow, QTableView, QHBoxLayout, QLabel, \ + QMenu, QHeaderView, QLineEdit +from PyQt6 import uic, QtGui, QtCore, QtWidgets +from PyQt6.QtCore import Qt, QSortFilterProxyModel from banking_breakdown.ui.main_window import Ui_MainWindow @@ -69,11 +70,6 @@ class GeneratedWindowWrapper(QMainWindow): self._window = Ui_MainWindow() self._window.setupUi(self) - # Set window behavior - - self._window.statementTableView.setSelectionBehavior( - QTableView.SelectionBehavior.SelectRows) - # Populate categories self._category_model = QtGui.QStandardItemModel() @@ -84,6 +80,17 @@ class GeneratedWindowWrapper(QMainWindow): self._window.createCategoryButton.clicked.connect( self._handle_create_click) + header = self._window.transactionTableView.horizontalHeader() + header.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu) + header.customContextMenuRequested.connect(self._header_right_clicked) + + def _header_right_clicked(self, pos): + context = QMenu(self) + context.addAction(QAction("test 1", self)) + context.addAction(QAction("test 2", self)) + context.addAction(QAction("test 3", self)) + context.exec(self.sender().mapToGlobal(pos)) + def add_categories(self, categories: typing.Sequence[str]): for category in categories: item = QtGui.QStandardItem(category) @@ -91,7 +98,11 @@ class GeneratedWindowWrapper(QMainWindow): def set_statement_data(self, df: pd.DataFrame): model = PandasModel(df) - self._window.statementTableView.setModel(model) + proxyModel = QSortFilterProxyModel(self) + proxyModel.setSourceModel(model) + self._window.transactionTableView.setModel(proxyModel) + + self._window.transactionTableView.resizeColumnsToContents() def _handle_create_click(self): self.add_categories(['asdf']) diff --git a/banking_breakdown/ui/main_window.py b/banking_breakdown/ui/main_window.py index 25cd2b1..3d20425 100644 --- a/banking_breakdown/ui/main_window.py +++ b/banking_breakdown/ui/main_window.py @@ -12,22 +12,21 @@ from PyQt6 import QtCore, QtGui, QtWidgets class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName("MainWindow") - MainWindow.resize(800, 600) + MainWindow.resize(1300, 731) self.centralwidget = QtWidgets.QWidget(parent=MainWindow) self.centralwidget.setObjectName("centralwidget") - self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.centralwidget) - self.verticalLayout_5.setSpacing(0) - self.verticalLayout_5.setObjectName("verticalLayout_5") - self.horizontalLayout_5 = QtWidgets.QHBoxLayout() - self.horizontalLayout_5.setObjectName("horizontalLayout_5") - self.warningWidget = QtWidgets.QWidget(parent=self.centralwidget) - self.warningWidget.setMaximumSize(QtCore.QSize(600, 16777215)) - self.warningWidget.setObjectName("warningWidget") - self.warningLayout = QtWidgets.QVBoxLayout(self.warningWidget) - self.warningLayout.setContentsMargins(-1, 0, -1, 9) + self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.centralwidget) + self.verticalLayout_4.setSpacing(0) + self.verticalLayout_4.setObjectName("verticalLayout_4") + self.horizontalLayout_6 = QtWidgets.QHBoxLayout() + self.horizontalLayout_6.setObjectName("horizontalLayout_6") + self.widget = QtWidgets.QWidget(parent=self.centralwidget) + self.widget.setObjectName("widget") + self.warningLayout = QtWidgets.QVBoxLayout(self.widget) + self.warningLayout.setContentsMargins(-1, 0, -1, 0) self.warningLayout.setObjectName("warningLayout") - self.horizontalLayout_5.addWidget(self.warningWidget) - self.verticalLayout_5.addLayout(self.horizontalLayout_5) + self.horizontalLayout_6.addWidget(self.widget) + self.verticalLayout_4.addLayout(self.horizontalLayout_6) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.groupBox = QtWidgets.QGroupBox(parent=self.centralwidget) @@ -37,7 +36,6 @@ class Ui_MainWindow(object): self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") self.createCategoryButton = QtWidgets.QPushButton(parent=self.groupBox) - self.createCategoryButton.setStatusTip("") self.createCategoryButton.setObjectName("createCategoryButton") self.horizontalLayout.addWidget(self.createCategoryButton) self.deleteCategoryButton = QtWidgets.QPushButton(parent=self.groupBox) @@ -61,23 +59,28 @@ class Ui_MainWindow(object): self.groupBox_2.setObjectName("groupBox_2") self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox_2) self.verticalLayout.setObjectName("verticalLayout") - self.statementTableView = QtWidgets.QTableView(parent=self.groupBox_2) - self.statementTableView.setSortingEnabled(False) - self.statementTableView.setWordWrap(True) - self.statementTableView.setObjectName("statementTableView") - self.statementTableView.horizontalHeader().setSortIndicatorShown(False) - self.verticalLayout.addWidget(self.statementTableView) + self.transactionTableView = QtWidgets.QTableView(parent=self.groupBox_2) + self.transactionTableView.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows) + self.transactionTableView.setObjectName("transactionTableView") + self.transactionTableView.horizontalHeader().setStretchLastSection(True) + self.verticalLayout.addWidget(self.transactionTableView) self.horizontalLayout_3.addWidget(self.groupBox_2) self.horizontalLayout_3.setStretch(1, 1) - self.verticalLayout_5.addLayout(self.horizontalLayout_3) + self.verticalLayout_4.addLayout(self.horizontalLayout_3) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtWidgets.QMenuBar(parent=MainWindow) - self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23)) + self.menubar.setGeometry(QtCore.QRect(0, 0, 1300, 23)) self.menubar.setObjectName("menubar") + self.menuFile = QtWidgets.QMenu(parent=self.menubar) + self.menuFile.setObjectName("menuFile") MainWindow.setMenuBar(self.menubar) self.statusbar = QtWidgets.QStatusBar(parent=MainWindow) self.statusbar.setObjectName("statusbar") MainWindow.setStatusBar(self.statusbar) + self.actionSave = QtGui.QAction(parent=MainWindow) + self.actionSave.setObjectName("actionSave") + self.menuFile.addAction(self.actionSave) + self.menubar.addAction(self.menuFile.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) @@ -86,10 +89,10 @@ class Ui_MainWindow(object): _translate = QtCore.QCoreApplication.translate MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) self.groupBox.setTitle(_translate("MainWindow", "Categories")) - self.createCategoryButton.setToolTip(_translate("MainWindow", "Create new category")) self.createCategoryButton.setText(_translate("MainWindow", "Create")) - self.deleteCategoryButton.setToolTip(_translate("MainWindow", "Delete selected category")) self.deleteCategoryButton.setText(_translate("MainWindow", "Delete")) - self.applyCategoryButton.setToolTip(_translate("MainWindow", "Apply selected category to selected transactions")) self.applyCategoryButton.setText(_translate("MainWindow", "Apply")) - self.groupBox_2.setTitle(_translate("MainWindow", "Bank statement")) + self.groupBox_2.setTitle(_translate("MainWindow", "Transactions")) + self.menuFile.setTitle(_translate("MainWindow", "File")) + self.actionSave.setText(_translate("MainWindow", "Save")) + self.actionSave.setShortcut(_translate("MainWindow", "Ctrl+S")) diff --git a/res/main_window.ui b/res/main_window.ui index 5d0c4ee..d8b1848 100644 --- a/res/main_window.ui +++ b/res/main_window.ui @@ -6,34 +6,28 @@ 0 0 - 800 - 600 + 1300 + 731 MainWindow - + 0 - + - - - - 600 - 16777215 - - + 0 - 9 + 0 @@ -52,12 +46,6 @@ - - Create new category - - - - Create @@ -65,9 +53,6 @@ - - Delete selected category - Delete @@ -99,9 +84,6 @@ - - Apply selected category to selected transactions - Apply @@ -115,19 +97,16 @@ - Bank statement + Transactions - - - false + + + QAbstractItemView::SelectRows - + true - - - false @@ -143,12 +122,27 @@ 0 0 - 800 + 1300 23 + + + File + + + + + + + Save + + + Ctrl+S + +