Compare commits
	
		
			No commits in common. "50227b9a2bbb6a185d82df3ed4e898f5a97d4427" and "0b960cbae6c648dcb3db5c1923dfc6fa1270c9f2" have entirely different histories.
		
	
	
		
			50227b9a2b
			...
			0b960cbae6
		
	
		
@ -1,47 +0,0 @@
 | 
				
			|||||||
<?xml version="1.0" encoding="UTF-8"?>
 | 
					 | 
				
			||||||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
 | 
					 | 
				
			||||||
    <xs:element name="books">
 | 
					 | 
				
			||||||
        <xs:complexType>
 | 
					 | 
				
			||||||
            <xs:sequence>
 | 
					 | 
				
			||||||
                <xs:element name="book" maxOccurs="unbounded">
 | 
					 | 
				
			||||||
                    <xs:complexType>
 | 
					 | 
				
			||||||
                        <xs:sequence>
 | 
					 | 
				
			||||||
                            <xs:element name="title"> <!-- Book title-->
 | 
					 | 
				
			||||||
                                <xs:simpleType>
 | 
					 | 
				
			||||||
                                    <!-- Allow for a string 2-100 characters long -->
 | 
					 | 
				
			||||||
                                    <xs:restriction base="xs:string">
 | 
					 | 
				
			||||||
                                        <xs:minLength value="2" />
 | 
					 | 
				
			||||||
                                        <xs:maxLength value="100" />
 | 
					 | 
				
			||||||
                                    </xs:restriction>
 | 
					 | 
				
			||||||
                                </xs:simpleType>
 | 
					 | 
				
			||||||
                            </xs:element>
 | 
					 | 
				
			||||||
                            <xs:element name="description" type="xs:string" /> <!-- Description -->
 | 
					 | 
				
			||||||
                            <xs:element name="year_published"> <!-- Year published -->
 | 
					 | 
				
			||||||
                                <xs:simpleType>
 | 
					 | 
				
			||||||
                                    <xs:restriction base="xs:gYear" />
 | 
					 | 
				
			||||||
                                </xs:simpleType>
 | 
					 | 
				
			||||||
                            </xs:element>
 | 
					 | 
				
			||||||
                            <xs:element name="isbn"> <!-- ISBN -->
 | 
					 | 
				
			||||||
                                <xs:simpleType>
 | 
					 | 
				
			||||||
                                    <!-- Strictly limit to either 10 or 13 digits -->
 | 
					 | 
				
			||||||
                                    <xs:restriction base="xs:string">
 | 
					 | 
				
			||||||
                                        <xs:pattern value="\d{10}" />
 | 
					 | 
				
			||||||
                                        <xs:pattern value="\d{13}" />
 | 
					 | 
				
			||||||
                                    </xs:restriction>
 | 
					 | 
				
			||||||
                                </xs:simpleType>
 | 
					 | 
				
			||||||
                            </xs:element>
 | 
					 | 
				
			||||||
                            <xs:element name="categories"> <!-- Categories list -->
 | 
					 | 
				
			||||||
                                <xs:complexType>
 | 
					 | 
				
			||||||
                                    <xs:sequence>
 | 
					 | 
				
			||||||
                                        <xs:element name="category" type="xs:string" maxOccurs="unbounded" />
 | 
					 | 
				
			||||||
                                    </xs:sequence>
 | 
					 | 
				
			||||||
                                </xs:complexType>
 | 
					 | 
				
			||||||
                            </xs:element>
 | 
					 | 
				
			||||||
                        </xs:sequence>
 | 
					 | 
				
			||||||
                    </xs:complexType>
 | 
					 | 
				
			||||||
                </xs:element>
 | 
					 | 
				
			||||||
            </xs:sequence>
 | 
					 | 
				
			||||||
        </xs:complexType>
 | 
					 | 
				
			||||||
    </xs:element>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</xs:schema>
 | 
					 | 
				
			||||||
@ -1,66 +1,40 @@
 | 
				
			|||||||
from PySide6.QtWidgets import (
 | 
					from PySide6.QtGui import QGuiApplication, QAction
 | 
				
			||||||
    QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox, QFormLayout
 | 
					from PySide6.QtQml import QQmlApplicationEngine
 | 
				
			||||||
)
 | 
					from PySide6 import QtWidgets, QtCore
 | 
				
			||||||
from models.book import Book, BookStatusEnum
 | 
					from PySide6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from models.book_overview import BooksOverview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BookEditor(QDialog):
 | 
					class BookEditor(QDialog):
 | 
				
			||||||
    def __init__(self, book: Book, parent=None):
 | 
					    def __init__(self, book_overview: BooksOverview, parent=None):
 | 
				
			||||||
        super().__init__(parent)
 | 
					        super().__init__(parent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.book = book
 | 
					        self.setWindowTitle("Edit a book")
 | 
				
			||||||
        self.setWindowTitle("Edit Book")
 | 
					 | 
				
			||||||
        self.setMinimumSize(400, 300)
 | 
					        self.setMinimumSize(400, 300)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Create main layout
 | 
					        # Create layout
 | 
				
			||||||
        layout = QVBoxLayout(self)
 | 
					        layout = QVBoxLayout(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Form layout for book fields
 | 
					        data_mode_layout = QHBoxLayout()
 | 
				
			||||||
        form_layout = QFormLayout()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Title field
 | 
					        self.data_mode_label = QLabel("Data mode:")
 | 
				
			||||||
        self.title_input = QLineEdit(self.book.title)
 | 
					        data_mode_layout.addWidget(self.data_mode_label)
 | 
				
			||||||
        form_layout.addRow("Title:", self.title_input)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Description field
 | 
					 | 
				
			||||||
        self.description_input = QTextEdit(self.book.description)
 | 
					 | 
				
			||||||
        form_layout.addRow("Description:", self.description_input)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Year published field
 | 
					 | 
				
			||||||
        self.year_input = QLineEdit(self.book.year_published)
 | 
					 | 
				
			||||||
        form_layout.addRow("Year Published:", self.year_input)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # ISBN field
 | 
					 | 
				
			||||||
        self.isbn_input = QLineEdit(self.book.isbn)
 | 
					 | 
				
			||||||
        form_layout.addRow("ISBN:", self.isbn_input)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Status dropdown
 | 
					 | 
				
			||||||
        self.status_input = QComboBox()
 | 
					 | 
				
			||||||
        self.status_input.addItems([status.value for status in BookStatusEnum])
 | 
					 | 
				
			||||||
        self.status_input.setCurrentText(self.book.status.value)
 | 
					 | 
				
			||||||
        form_layout.addRow("Status:", self.status_input)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        layout.addLayout(form_layout)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Buttons
 | 
					        # Buttons
 | 
				
			||||||
        button_layout = QHBoxLayout()
 | 
					        button_layout = QtWidgets.QHBoxLayout()
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        self.save_button = QPushButton("Save")
 | 
					        self.save_button = QtWidgets.QPushButton("Save")
 | 
				
			||||||
        self.save_button.clicked.connect(self.save_book)
 | 
					        self.save_button.clicked.connect(self.save_book)
 | 
				
			||||||
        button_layout.addWidget(self.save_button)
 | 
					        button_layout.addWidget(self.save_button)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.cancel_button = QPushButton("Discard")
 | 
					        self.cancel_button = QtWidgets.QPushButton("Discard")
 | 
				
			||||||
        self.cancel_button.clicked.connect(self.reject)
 | 
					        self.cancel_button.clicked.connect(self.reject)
 | 
				
			||||||
        button_layout.addWidget(self.cancel_button)
 | 
					        button_layout.addWidget(self.cancel_button)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        layout.addLayout(button_layout)
 | 
					        layout.addLayout(button_layout)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def save_book(self):
 | 
					 | 
				
			||||||
        # Update book object with input values
 | 
					 | 
				
			||||||
        self.book.title = self.title_input.text()
 | 
					 | 
				
			||||||
        self.book.description = self.description_input.toPlainText()
 | 
					 | 
				
			||||||
        self.book.year_published = self.year_input.text()
 | 
					 | 
				
			||||||
        self.book.isbn = self.isbn_input.text()
 | 
					 | 
				
			||||||
        self.book.status = BookStatusEnum(self.status_input.currentText())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Accept the dialog and close
 | 
					    def save_book(self):
 | 
				
			||||||
        self.accept()
 | 
					        pass
 | 
				
			||||||
@ -1,32 +1,27 @@
 | 
				
			|||||||
from PySide6.QtGui import QGuiApplication, QAction, Qt
 | 
					from PySide6.QtGui import QGuiApplication, QAction, Qt
 | 
				
			||||||
from PySide6.QtQml import QQmlApplicationEngine
 | 
					from PySide6.QtQml import QQmlApplicationEngine
 | 
				
			||||||
from PySide6.QtWidgets import QHBoxLayout, QVBoxLayout, QLabel, QWidget, QMenu, QSizePolicy, QLayout, QMessageBox
 | 
					from PySide6.QtWidgets import QHBoxLayout, QVBoxLayout, QLabel, QWidget, QMenu, QSizePolicy, QLayout
 | 
				
			||||||
from PySide6.QtCore import qDebug
 | 
					from PySide6.QtCore import qDebug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ui.book_editor.book_editor import BookEditor
 | 
					from ui.book_editor.book_editor import BookEditor
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from models.book import BookStatusEnum, Book
 | 
					from models.book import BookStatusEnum
 | 
				
			||||||
from models.book_overview import BooksOverview
 | 
					from models.book_overview import BooksOverview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from utils.database import DatabaseManager
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
STATUS_TO_COLOR_MAP = {
 | 
					STATUS_TO_COLOR_MAP = {
 | 
				
			||||||
    BookStatusEnum.available: "#3c702e",
 | 
					    BookStatusEnum.available: "#3c702e",
 | 
				
			||||||
    BookStatusEnum.borrowed: "#702525",
 | 
					    BookStatusEnum.borrowed: "#702525",
 | 
				
			||||||
    BookStatusEnum.reserved: "#bc7613"
 | 
					    BookStatusEnum.reserved: "#bc7613"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
class BookCard(QWidget):
 | 
					class BookCard(QWidget):
 | 
				
			||||||
    def __init__(self, book_overview: BooksOverview):
 | 
					    def __init__(self, book_overview: BooksOverview):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.book_overview = book_overview
 | 
					        self.book_overview = book_overview
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.setAttribute(Qt.WidgetAttribute.WA_Hover,
 | 
					        self.setAttribute(Qt.WidgetAttribute.WA_Hover, True)  # Enable hover events
 | 
				
			||||||
                          True)  # Enable hover events
 | 
					        self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)  # Enable styling for background
 | 
				
			||||||
        # Enable styling for background
 | 
					 | 
				
			||||||
        self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Set initial stylesheet with hover behavior
 | 
					        # Set initial stylesheet with hover behavior
 | 
				
			||||||
        self.setStyleSheet("""
 | 
					        self.setStyleSheet("""
 | 
				
			||||||
@ -38,8 +33,7 @@ class BookCard(QWidget):
 | 
				
			|||||||
        # Layout setup
 | 
					        # Layout setup
 | 
				
			||||||
        layout = QHBoxLayout(self)
 | 
					        layout = QHBoxLayout(self)
 | 
				
			||||||
        layout.setSizeConstraint(QLayout.SizeConstraint.SetMinimumSize)
 | 
					        layout.setSizeConstraint(QLayout.SizeConstraint.SetMinimumSize)
 | 
				
			||||||
        self.setSizePolicy(QSizePolicy.Policy.Preferred,
 | 
					        self.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
 | 
				
			||||||
                           QSizePolicy.Policy.Fixed)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        layout.setContentsMargins(10, 10, 10, 10)
 | 
					        layout.setContentsMargins(10, 10, 10, 10)
 | 
				
			||||||
        layout.setSpacing(10)
 | 
					        layout.setSpacing(10)
 | 
				
			||||||
@ -60,8 +54,7 @@ class BookCard(QWidget):
 | 
				
			|||||||
        layout.addLayout(right_side)
 | 
					        layout.addLayout(right_side)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        status_label = QLabel(str(book_overview.status.value.capitalize()))
 | 
					        status_label = QLabel(str(book_overview.status.value.capitalize()))
 | 
				
			||||||
        status_label.setStyleSheet(f"color: {
 | 
					        status_label.setStyleSheet(f"color: {STATUS_TO_COLOR_MAP[book_overview.status]}; font-size: 20px; font-weight: bold;")
 | 
				
			||||||
                                   STATUS_TO_COLOR_MAP[book_overview.status]}; font-size: 20px; font-weight: bold;")
 | 
					 | 
				
			||||||
        status_label.setAlignment(Qt.AlignmentFlag.AlignRight)
 | 
					        status_label.setAlignment(Qt.AlignmentFlag.AlignRight)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        right_side.addWidget(status_label)
 | 
					        right_side.addWidget(status_label)
 | 
				
			||||||
@ -94,29 +87,15 @@ class BookCard(QWidget):
 | 
				
			|||||||
            action_mark_returned = context_menu.addAction("Mark as Returned")
 | 
					            action_mark_returned = context_menu.addAction("Mark as Returned")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if self.book_overview.status == BookStatusEnum.reserved:
 | 
					        if self.book_overview.status == BookStatusEnum.reserved:
 | 
				
			||||||
            action_remove_reservation = context_menu.addAction(
 | 
					            action_remove_reservation = context_menu.addAction("Remove reservation")
 | 
				
			||||||
                "Remove reservation")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        action = context_menu.exec_(self.mapToGlobal(event.pos()))
 | 
					        action = context_menu.exec_(self.mapToGlobal(event.pos()))
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        if action == action_edit_book:
 | 
					        if action == action_edit_book:
 | 
				
			||||||
            with DatabaseManager.get_session() as session:
 | 
					            BookEditor(self.book_overview).exec()
 | 
				
			||||||
                book_id = self.book_overview.id
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                book = session.query(Book).filter(
 | 
					 | 
				
			||||||
                    Book.id == book_id).one_or_none()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if book:
 | 
					 | 
				
			||||||
                    BookEditor(book).exec()
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    QMessageBox.critical(self,
 | 
					 | 
				
			||||||
                                         "Error",
 | 
					 | 
				
			||||||
                                         "The book you requested could not be found. Try again later",
 | 
					 | 
				
			||||||
                                         QMessageBox.StandardButton.Ok,
 | 
					 | 
				
			||||||
                                         QMessageBox.StandardButton.NoButton)
 | 
					 | 
				
			||||||
        elif action == action_edit_author:
 | 
					        elif action == action_edit_author:
 | 
				
			||||||
            print("Edit Author selected")
 | 
					            print("Edit Author selected")
 | 
				
			||||||
        elif action == action_mark_returned:
 | 
					        elif action == action_mark_returned:
 | 
				
			||||||
            print("Mark as Returned selected")
 | 
					            print("Mark as Returned selected")
 | 
				
			||||||
        elif action == action_remove_reservation:
 | 
					        elif action == action_remove_reservation:
 | 
				
			||||||
            print("Remove reservation selected")
 | 
					            print("Remove reservation selected")
 | 
				
			||||||
@ -56,35 +56,10 @@ class LibraryWindow(QtWidgets.QMainWindow):
 | 
				
			|||||||
        # File menu
 | 
					        # File menu
 | 
				
			||||||
        file_menu = menu_bar.addMenu("File")
 | 
					        file_menu = menu_bar.addMenu("File")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # New submenu
 | 
					        import_action = QAction("Import books", self)
 | 
				
			||||||
        new_submenu = QtWidgets.QMenu(self)
 | 
					        import_action.triggered.connect(self.import_data)
 | 
				
			||||||
        new_submenu.setTitle("New")
 | 
					        file_menu.addAction(import_action)
 | 
				
			||||||
        file_menu.addMenu(new_submenu)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # New book action
 | 
					 | 
				
			||||||
        new_book_action = QAction("New book", self)
 | 
					 | 
				
			||||||
        new_book_action.triggered.connect(self.new_book)
 | 
					 | 
				
			||||||
        new_submenu.addAction(new_book_action)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # New book action
 | 
					 | 
				
			||||||
        new_member_action = QAction("New member", self)
 | 
					 | 
				
			||||||
        new_member_action.triggered.connect(self.new_member)
 | 
					 | 
				
			||||||
        new_submenu.addAction(new_member_action)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Import submenu
 | 
					 | 
				
			||||||
        import_submenu = QtWidgets.QMenu(self)
 | 
					 | 
				
			||||||
        import_submenu.setTitle("Import")
 | 
					 | 
				
			||||||
        file_menu.addMenu(import_submenu)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        import_books_action = QAction("Import books", self)
 | 
					 | 
				
			||||||
        import_books_action.triggered.connect(self.import_data)
 | 
					 | 
				
			||||||
        import_submenu.addAction(import_books_action)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        import_members_action = QAction("Import members", self)
 | 
					 | 
				
			||||||
        import_members_action.triggered.connect(self.import_data)
 | 
					 | 
				
			||||||
        import_submenu.addAction(import_members_action)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        # Export action
 | 
					 | 
				
			||||||
        export_action = QAction("Export overview", self)
 | 
					        export_action = QAction("Export overview", self)
 | 
				
			||||||
        export_action.triggered.connect(self.export_data)
 | 
					        export_action.triggered.connect(self.export_data)
 | 
				
			||||||
        file_menu.addAction(export_action)
 | 
					        file_menu.addAction(export_action)
 | 
				
			||||||
@ -117,11 +92,8 @@ class LibraryWindow(QtWidgets.QMainWindow):
 | 
				
			|||||||
        if dialog.exec() == QtWidgets.QDialog.Accepted:
 | 
					        if dialog.exec() == QtWidgets.QDialog.Accepted:
 | 
				
			||||||
            print("Settings were saved.")
 | 
					            print("Settings were saved.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def new_book(self):
 | 
					    def open_file(self):
 | 
				
			||||||
        pass
 | 
					        QtWidgets.QMessageBox.information(self, "Open File", "Open an existing file.")
 | 
				
			||||||
 | 
					 | 
				
			||||||
    def new_member(self):
 | 
					 | 
				
			||||||
        pass
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def import_data(self):
 | 
					    def import_data(self):
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user