Compare commits
2 Commits
0b960cbae6
...
50227b9a2b
Author | SHA1 | Date | |
---|---|---|---|
50227b9a2b | |||
48d1a28783 |
47
src/book_import_scheme.xsd
Normal file
47
src/book_import_scheme.xsd
Normal file
@ -0,0 +1,47 @@
|
||||
<?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,40 +1,66 @@
|
||||
from PySide6.QtGui import QGuiApplication, QAction
|
||||
from PySide6.QtQml import QQmlApplicationEngine
|
||||
from PySide6 import QtWidgets, QtCore
|
||||
from PySide6.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QLabel
|
||||
|
||||
from models.book_overview import BooksOverview
|
||||
from PySide6.QtWidgets import (
|
||||
QDialog, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox, QFormLayout
|
||||
)
|
||||
from models.book import Book, BookStatusEnum
|
||||
|
||||
class BookEditor(QDialog):
|
||||
def __init__(self, book_overview: BooksOverview, parent=None):
|
||||
def __init__(self, book: Book, parent=None):
|
||||
super().__init__(parent)
|
||||
|
||||
self.setWindowTitle("Edit a book")
|
||||
self.book = book
|
||||
self.setWindowTitle("Edit Book")
|
||||
self.setMinimumSize(400, 300)
|
||||
|
||||
# Create layout
|
||||
# Create main layout
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
data_mode_layout = QHBoxLayout()
|
||||
# Form layout for book fields
|
||||
form_layout = QFormLayout()
|
||||
|
||||
self.data_mode_label = QLabel("Data mode:")
|
||||
data_mode_layout.addWidget(self.data_mode_label)
|
||||
# Title field
|
||||
self.title_input = QLineEdit(self.book.title)
|
||||
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
|
||||
button_layout = QtWidgets.QHBoxLayout()
|
||||
|
||||
self.save_button = QtWidgets.QPushButton("Save")
|
||||
button_layout = QHBoxLayout()
|
||||
|
||||
self.save_button = QPushButton("Save")
|
||||
self.save_button.clicked.connect(self.save_book)
|
||||
button_layout.addWidget(self.save_button)
|
||||
|
||||
self.cancel_button = QtWidgets.QPushButton("Discard")
|
||||
self.cancel_button = QPushButton("Discard")
|
||||
self.cancel_button.clicked.connect(self.reject)
|
||||
button_layout.addWidget(self.cancel_button)
|
||||
|
||||
layout.addLayout(button_layout)
|
||||
|
||||
|
||||
def save_book(self):
|
||||
pass
|
||||
# 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
|
||||
self.accept()
|
||||
|
@ -1,27 +1,32 @@
|
||||
from PySide6.QtGui import QGuiApplication, QAction, Qt
|
||||
from PySide6.QtQml import QQmlApplicationEngine
|
||||
from PySide6.QtWidgets import QHBoxLayout, QVBoxLayout, QLabel, QWidget, QMenu, QSizePolicy, QLayout
|
||||
from PySide6.QtWidgets import QHBoxLayout, QVBoxLayout, QLabel, QWidget, QMenu, QSizePolicy, QLayout, QMessageBox
|
||||
from PySide6.QtCore import qDebug
|
||||
|
||||
from ui.book_editor.book_editor import BookEditor
|
||||
|
||||
from models.book import BookStatusEnum
|
||||
from models.book import BookStatusEnum, Book
|
||||
from models.book_overview import BooksOverview
|
||||
|
||||
from utils.database import DatabaseManager
|
||||
|
||||
STATUS_TO_COLOR_MAP = {
|
||||
BookStatusEnum.available: "#3c702e",
|
||||
BookStatusEnum.borrowed: "#702525",
|
||||
BookStatusEnum.reserved: "#bc7613"
|
||||
}
|
||||
|
||||
|
||||
class BookCard(QWidget):
|
||||
def __init__(self, book_overview: BooksOverview):
|
||||
super().__init__()
|
||||
|
||||
self.book_overview = book_overview
|
||||
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_Hover, True) # Enable hover events
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True) # Enable styling for background
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_Hover,
|
||||
True) # Enable hover events
|
||||
# Enable styling for background
|
||||
self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
|
||||
|
||||
# Set initial stylesheet with hover behavior
|
||||
self.setStyleSheet("""
|
||||
@ -33,7 +38,8 @@ class BookCard(QWidget):
|
||||
# Layout setup
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setSizeConstraint(QLayout.SizeConstraint.SetMinimumSize)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
||||
self.setSizePolicy(QSizePolicy.Policy.Preferred,
|
||||
QSizePolicy.Policy.Fixed)
|
||||
|
||||
layout.setContentsMargins(10, 10, 10, 10)
|
||||
layout.setSpacing(10)
|
||||
@ -54,7 +60,8 @@ class BookCard(QWidget):
|
||||
layout.addLayout(right_side)
|
||||
|
||||
status_label = QLabel(str(book_overview.status.value.capitalize()))
|
||||
status_label.setStyleSheet(f"color: {STATUS_TO_COLOR_MAP[book_overview.status]}; font-size: 20px; font-weight: bold;")
|
||||
status_label.setStyleSheet(f"color: {
|
||||
STATUS_TO_COLOR_MAP[book_overview.status]}; font-size: 20px; font-weight: bold;")
|
||||
status_label.setAlignment(Qt.AlignmentFlag.AlignRight)
|
||||
|
||||
right_side.addWidget(status_label)
|
||||
@ -87,15 +94,29 @@ class BookCard(QWidget):
|
||||
action_mark_returned = context_menu.addAction("Mark as Returned")
|
||||
|
||||
if self.book_overview.status == BookStatusEnum.reserved:
|
||||
action_remove_reservation = context_menu.addAction("Remove reservation")
|
||||
action_remove_reservation = context_menu.addAction(
|
||||
"Remove reservation")
|
||||
|
||||
action = context_menu.exec_(self.mapToGlobal(event.pos()))
|
||||
|
||||
|
||||
if action == action_edit_book:
|
||||
BookEditor(self.book_overview).exec()
|
||||
with DatabaseManager.get_session() as session:
|
||||
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:
|
||||
print("Edit Author selected")
|
||||
elif action == action_mark_returned:
|
||||
print("Mark as Returned selected")
|
||||
elif action == action_remove_reservation:
|
||||
print("Remove reservation selected")
|
||||
print("Remove reservation selected")
|
||||
|
@ -56,10 +56,35 @@ class LibraryWindow(QtWidgets.QMainWindow):
|
||||
# File menu
|
||||
file_menu = menu_bar.addMenu("File")
|
||||
|
||||
import_action = QAction("Import books", self)
|
||||
import_action.triggered.connect(self.import_data)
|
||||
file_menu.addAction(import_action)
|
||||
# New submenu
|
||||
new_submenu = QtWidgets.QMenu(self)
|
||||
new_submenu.setTitle("New")
|
||||
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.triggered.connect(self.export_data)
|
||||
file_menu.addAction(export_action)
|
||||
@ -92,8 +117,11 @@ class LibraryWindow(QtWidgets.QMainWindow):
|
||||
if dialog.exec() == QtWidgets.QDialog.Accepted:
|
||||
print("Settings were saved.")
|
||||
|
||||
def open_file(self):
|
||||
QtWidgets.QMessageBox.information(self, "Open File", "Open an existing file.")
|
||||
def new_book(self):
|
||||
pass
|
||||
|
||||
def new_member(self):
|
||||
pass
|
||||
|
||||
def import_data(self):
|
||||
pass
|
||||
|
Loading…
x
Reference in New Issue
Block a user