Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge main into workflows #27

Closed
wants to merge 41 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
98d2e0b
Merge pull request #9 from mitchcamza/COS3711-03-01
mitchcamza Jul 21, 2024
23f2e2e
Merge pull request #10 from mitchcamza/workflows
mitchcamza Jul 21, 2024
ce6afea
Merge pull request #25 from mitchcamza/workflows
mitchcamza Jul 28, 2024
b6c25d4
Merge branch 'main' into COS3711-03-01
mitchcamza Jul 28, 2024
4bea3a7
Create test.yml
mitchcamza Jul 28, 2024
a933d71
Update build.yml
mitchcamza Jul 28, 2024
a8c3634
Update test.yml
mitchcamza Jul 28, 2024
90bc23f
Define Book class; Write unit tests for Book
mitchcamza Jul 28, 2024
f032021
Merge pull request #29 from mitchcamza/dev
mitchcamza Jul 28, 2024
5f9d36b
Update build config
mitchcamza Jul 28, 2024
3eb18e1
Define BookInput class; Add icons; Update class diagram
mitchcamza Aug 2, 2024
d577b48
Add input validation for author first and last name
mitchcamza Aug 5, 2024
8ebed7e
Merge pull request #34 from mitchcamza/feature/book-input
mitchcamza Aug 5, 2024
33997ad
Define BookTableModel class; Create unit test for BookTableModel
mitchcamza Aug 5, 2024
dbe99f4
Define BookProxyModel class; Write unit tests for BookProxyModel class
mitchcamza Aug 5, 2024
7284a3b
Implement BookTableView in MainWindow; Implement clearFilter() method
mitchcamza Aug 5, 2024
73c181d
Merge pull request #35 from mitchcamza/feature/model-view
mitchcamza Aug 5, 2024
31be375
Merge branch 'main' into dev
mitchcamza Aug 5, 2024
0be0077
Merge pull request #36 from mitchcamza/dev
mitchcamza Aug 5, 2024
20d460d
Define BookFactory class for creating Book objects; Write unit test f…
mitchcamza Aug 7, 2024
3c10334
Add unit test for BookFactory
mitchcamza Aug 7, 2024
5a6f194
Update CMakeLists.txt project sources: add BookFactory
mitchcamza Aug 7, 2024
4f65963
Define BookTableModel::saveBook()
mitchcamza Aug 7, 2024
4544301
Update BookInput validation; Replace isbn validation with input mask;…
mitchcamza Aug 7, 2024
a2e9c0a
Merge pull request #37 from mitchcamza/feature/book-factory
mitchcamza Aug 7, 2024
46aa788
Merge pull request #38 from mitchcamza/feature/model-view
mitchcamza Aug 7, 2024
b2d7671
Revert "Feature/book factory"
mitchcamza Aug 7, 2024
dd56837
Merge pull request #39 from mitchcamza/revert-37-feature/book-factory
mitchcamza Aug 7, 2024
2af97b6
Revert "Define BookTableModel::saveBook()"
mitchcamza Aug 7, 2024
68a6f80
Merge pull request #40 from mitchcamza/revert-38-feature/model-view
mitchcamza Aug 7, 2024
9cd65ee
Merge pull request #41 from mitchcamza/feature/book-factory
mitchcamza Aug 7, 2024
8b4bdc4
Merge pull request #42 from mitchcamza/feature/model-view
mitchcamza Aug 7, 2024
608eb94
Merge branch 'dev' into feature/book-input
mitchcamza Aug 7, 2024
2805106
Merge pull request #43 from mitchcamza/feature/book-input
mitchcamza Aug 7, 2024
ee32753
Merge pull request #44 from mitchcamza/dev
mitchcamza Aug 7, 2024
d3dfedb
Update TestBookTableModel testData and testSetData methods
mitchcamza Aug 7, 2024
1278d6e
Merge pull request #45 from mitchcamza/feature/model-view
mitchcamza Aug 7, 2024
7d9cee6
Merge pull request #46 from mitchcamza/dev
mitchcamza Aug 7, 2024
4c88b85
Update test.yml
mitchcamza Aug 8, 2024
b73092a
Merge pull request #47 from COS3711/main
mitchcamza Aug 8, 2024
58cba50
Update build.yml
mitchcamza Aug 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Define BookInput class; Add icons; Update class diagram
mitchcamza committed Aug 2, 2024
commit 3eb18e10e109241c4e2c8edb77a0175496c91e67
40 changes: 20 additions & 20 deletions COS3711-03-01/COS3711-03-01.drawio
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
<mxfile host="Electron" modified="2024-07-28T20:07:41.802Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.6.4 Chrome/124.0.6367.207 Electron/30.0.6 Safari/537.36" etag="cwJQNhiL4IcJnoZKe6Cd" version="24.6.4" type="device">
<diagram id="6iuWq0UelAJ61aAoiBDy" name="Library Managament System">
<mxGraphModel dx="1337" dy="1349" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<mxfile host="Electron" modified="2024-07-30T16:36:34.755Z" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.6.4 Chrome/124.0.6367.207 Electron/30.0.6 Safari/537.36" etag="k-16yr9vJ6ULwAqXtUkk" version="24.6.4" type="device">
<diagram id="6iuWq0UelAJ61aAoiBDy" name="Book Shelf">
<mxGraphModel dx="1696" dy="1716" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="0" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="gvHln3FCuM-_E14BoruI-1" value="Book&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;" parent="1" vertex="1">
<mxGeometry x="-30" y="-340" width="360" height="290" as="geometry" />
<mxGeometry x="-30" y="-340" width="360" height="260" as="geometry" />
</mxCell>
<mxCell id="gvHln3FCuM-_E14BoruI-2" value="- title: QString&lt;div&gt;- authors: QStringList&lt;/div&gt;&lt;div&gt;- isbn: QString&lt;/div&gt;&lt;div&gt;- publicationDate: QDate&lt;/div&gt;" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;whiteSpace=wrap;html=1;labelBackgroundColor=none;" parent="gvHln3FCuM-_E14BoruI-1" vertex="1">
<mxGeometry y="26" width="360" height="64" as="geometry" />
</mxCell>
<mxCell id="gvHln3FCuM-_E14BoruI-3" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;labelBackgroundColor=none;" parent="gvHln3FCuM-_E14BoruI-1" vertex="1">
<mxGeometry y="90" width="360" height="8" as="geometry" />
</mxCell>
<mxCell id="gvHln3FCuM-_E14BoruI-4" value="+ Book()&lt;div&gt;+ Book(t: QString, a: QStringList, i: QString, p: QDate)&lt;/div&gt;&lt;div&gt;+ setTitle(t: QString)&lt;/div&gt;&lt;div&gt;+ setAuthors(a: QStringList)&lt;/div&gt;&lt;div&gt;+ setIsbn(i: QString)&lt;/div&gt;&lt;div&gt;+ setPublicationDate(p: QDate)&lt;/div&gt;&lt;div&gt;+ getTitle(): QString&lt;/div&gt;&lt;div&gt;+ getAuthors(): QStringList&lt;/div&gt;&lt;div&gt;+ getIsbn(): QString&lt;/div&gt;&lt;div&gt;+ getPublicationDate(): QDate&lt;/div&gt;&lt;div&gt;+ obtainBookInfo()&lt;/div&gt;&lt;div&gt;+ saveBook(b: Book&amp;amp;)&lt;/div&gt;" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;whiteSpace=wrap;html=1;labelBackgroundColor=none;" parent="gvHln3FCuM-_E14BoruI-1" vertex="1">
<mxGeometry y="98" width="360" height="192" as="geometry" />
<mxCell id="gvHln3FCuM-_E14BoruI-4" value="+ Book()&lt;div&gt;+ Book(t: QString, a: QStringList, i: QString, p: QDate)&lt;/div&gt;&lt;div&gt;+ setTitle(t: QString)&lt;/div&gt;&lt;div&gt;+ setAuthors(a: QStringList)&lt;/div&gt;&lt;div&gt;+ setIsbn(i: QString)&lt;/div&gt;&lt;div&gt;+ setPublicationDate(p: QDate)&lt;/div&gt;&lt;div&gt;+ getTitle(): QString&lt;/div&gt;&lt;div&gt;+ getAuthors(): QStringList&lt;/div&gt;&lt;div&gt;+ getIsbn(): QString&lt;/div&gt;&lt;div&gt;+ getPublicationDate(): QDate&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;whiteSpace=wrap;html=1;labelBackgroundColor=none;" parent="gvHln3FCuM-_E14BoruI-1" vertex="1">
<mxGeometry y="98" width="360" height="162" as="geometry" />
</mxCell>
<mxCell id="gvHln3FCuM-_E14BoruI-26" value="&lt;div&gt;Author&lt;/div&gt;" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;" parent="1" vertex="1">
<mxGeometry x="-500" y="-340" width="360" height="150" as="geometry" />
@@ -28,18 +28,6 @@
<mxCell id="gvHln3FCuM-_E14BoruI-29" value="&lt;div&gt;+ Author(firstName: QString, lastName: QString)&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;+ getFirstName(): QString&lt;/span&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;+ getLastName(): QString&lt;br&gt;&lt;/div&gt;&lt;div&gt;+ toString(): QString&lt;/div&gt;" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;whiteSpace=wrap;html=1;labelBackgroundColor=none;" parent="gvHln3FCuM-_E14BoruI-26" vertex="1">
<mxGeometry y="78" width="360" height="72" as="geometry" />
</mxCell>
<mxCell id="gvHln3FCuM-_E14BoruI-30" value="" style="endArrow=diamondThin;endFill=1;endSize=24;html=1;rounded=0;" parent="1" source="gvHln3FCuM-_E14BoruI-26" target="gvHln3FCuM-_E14BoruI-1" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-490" y="434.96" as="sourcePoint" />
<mxPoint x="116.07999999999993" y="69.99999999999997" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="gvHln3FCuM-_E14BoruI-32" value="" style="endArrow=diamondThin;endFill=1;endSize=24;html=1;rounded=0;" parent="1" source="gvHln3FCuM-_E14BoruI-65" target="gvHln3FCuM-_E14BoruI-1" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-130" y="228.9622641509436" as="sourcePoint" />
<mxPoint x="490" y="540" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="gvHln3FCuM-_E14BoruI-35" value="" style="endArrow=diamondThin;endFill=1;endSize=24;html=1;rounded=0;" parent="1" source="gvHln3FCuM-_E14BoruI-61" target="gvHln3FCuM-_E14BoruI-51" edge="1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="1510" y="135.608695652174" as="sourcePoint" />
@@ -77,7 +65,7 @@
<mxGeometry y="68" width="360" height="62" as="geometry" />
</mxCell>
<mxCell id="gvHln3FCuM-_E14BoruI-65" value="&lt;div&gt;BookInput&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="swimlane;fontStyle=1;align=center;verticalAlign=top;childLayout=stackLayout;horizontal=1;startSize=26;horizontalStack=0;resizeParent=1;resizeParentMax=0;resizeLast=0;collapsible=1;marginBottom=0;whiteSpace=wrap;html=1;labelBackgroundColor=none;" parent="1" vertex="1">
<mxGeometry x="-540" y="-70" width="410" height="250" as="geometry" />
<mxGeometry x="1740" y="130" width="410" height="250" as="geometry" />
</mxCell>
<mxCell id="gvHln3FCuM-_E14BoruI-66" value="- lineEditTitle: QLineEdit&lt;div&gt;- lineEditAuthors: QLineEdit&lt;/div&gt;&lt;div&gt;- lineEditIsbn: QLineEdit&lt;/div&gt;&lt;div&gt;- dateEditPublicationDate: QDateEdit&lt;/div&gt;&lt;div&gt;- pushButtonAdd: QPushButton&lt;/div&gt;&lt;div&gt;- pushButtonCancel: QPushButton&lt;/div&gt;" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;whiteSpace=wrap;html=1;labelBackgroundColor=none;" parent="gvHln3FCuM-_E14BoruI-65" vertex="1">
<mxGeometry y="26" width="410" height="94" as="geometry" />
@@ -130,7 +118,7 @@
<mxCell id="we9DT2KBn4o6eFFRd77e-7" value="" style="line;strokeWidth=1;fillColor=none;align=left;verticalAlign=middle;spacingTop=-1;spacingLeft=3;spacingRight=3;rotatable=0;labelPosition=right;points=[];portConstraint=eastwest;labelBackgroundColor=none;" vertex="1" parent="we9DT2KBn4o6eFFRd77e-5">
<mxGeometry y="210" width="500" height="8" as="geometry" />
</mxCell>
<mxCell id="we9DT2KBn4o6eFFRd77e-8" value="&lt;div&gt;&lt;div&gt;+ MainWindow(parent: QWidget)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;+ ~MainWindow()&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;+ setupUI()&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;- on_actionAddBook_triggered()&lt;/div&gt;&lt;div&gt;- on_actionExportBooks_triggered()&lt;/div&gt;&lt;div&gt;- on_actionClearFilterTriggered()&lt;/div&gt;" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;whiteSpace=wrap;html=1;labelBackgroundColor=none;" vertex="1" parent="we9DT2KBn4o6eFFRd77e-5">
<mxCell id="we9DT2KBn4o6eFFRd77e-8" value="&lt;div&gt;&lt;div&gt;+ MainWindow(parent: QWidget)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;+ ~MainWindow()&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;+ setupUI()&lt;div&gt;&lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;- addBook()&lt;/div&gt;&lt;div&gt;- exportBooks()&lt;/div&gt;&lt;div&gt;- clearFilter()&lt;/div&gt;" style="text;strokeColor=none;fillColor=none;align=left;verticalAlign=top;spacingLeft=4;spacingRight=4;overflow=hidden;rotatable=0;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;whiteSpace=wrap;html=1;labelBackgroundColor=none;" vertex="1" parent="we9DT2KBn4o6eFFRd77e-5">
<mxGeometry y="218" width="500" height="142" as="geometry" />
</mxCell>
<mxCell id="we9DT2KBn4o6eFFRd77e-9" value="" style="endArrow=diamondThin;endFill=1;endSize=24;html=1;rounded=0;" edge="1" parent="1" source="gvHln3FCuM-_E14BoruI-74" target="we9DT2KBn4o6eFFRd77e-5">
@@ -181,6 +169,18 @@
<mxPoint x="540" y="-320" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="8dgmckmYpp2PSS6kHg5K-1" value="" style="endArrow=diamondThin;endFill=0;endSize=24;html=1;rounded=0;" edge="1" parent="1" source="gvHln3FCuM-_E14BoruI-26" target="gvHln3FCuM-_E14BoruI-1">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="-160" y="-260" as="sourcePoint" />
<mxPoint y="-260" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="8dgmckmYpp2PSS6kHg5K-2" value="" style="endArrow=diamondThin;endFill=0;endSize=24;html=1;rounded=0;" edge="1" parent="1" source="gvHln3FCuM-_E14BoruI-65" target="we9DT2KBn4o6eFFRd77e-8">
<mxGeometry width="160" relative="1" as="geometry">
<mxPoint x="2290" y="10" as="sourcePoint" />
<mxPoint x="2450" y="10" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
12 changes: 5 additions & 7 deletions COS3711-03-01/src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -13,13 +13,11 @@ find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)

set(PROJECT_SOURCES
main.cpp
mainwindow.cpp
mainwindow.h
author.cpp
author.h
book.h
book.cpp
resources.qrc
mainwindow.h mainwindow.cpp
author.h author.cpp
book.h book.cpp
bookinput.h bookinput.cpp
)

# Create library
186 changes: 186 additions & 0 deletions COS3711-03-01/src/bookinput.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#include "bookinput.h"

#include <QDateEdit>
#include <QGridLayout>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QMessageBox>
#include <QPushButton>
#include <QRegularExpression>
#include <QRegularExpressionMatch>


BookInput::BookInput(QWidget *parent)
: QDialog{parent},
mainLayout(new QGridLayout(this)),
gridLayoutBook(new QGridLayout()),
gridLayoutAuthor(new QGridLayout()),
groupBoxBook(new QGroupBox("Book", this)),
groupBoxAuthor(new QGroupBox("Author", this)),
lineEditTitle(new QLineEdit(this)),
lineEditIsbn(new QLineEdit(this)),
dateEditPublicationDate(new QDateEdit(this)),
lineEditFirstName(new QLineEdit(this)),
lineEditLastName(new QLineEdit(this)),
pushButtonAddAuthor(new QPushButton("Add", this)),
listWidgetAuthors(new QListWidget(this)),
pushButtonRemoveAuthor(new QPushButton(QIcon(":/icons/removeAuthor"), "", this)),
pushButtonSave(new QPushButton("Save", this)),
pushButtonCancel(new QPushButton("Cancel", this))
{
setupUI();

// Connect signals and slots
connect(pushButtonAddAuthor, &QPushButton::clicked, this, &BookInput::addAuthor);
connect(pushButtonRemoveAuthor, &QPushButton::clicked, this, &BookInput::removeAuthor);
connect(pushButtonSave, &QPushButton::clicked, this, &BookInput::saveBook);
connect(pushButtonCancel, &QPushButton::clicked, this, &BookInput::close);
}

BookInput::~BookInput()
{

}

void BookInput::addAuthor()
{
QString author = lineEditLastName->text().toUpper() + ", " + lineEditFirstName->text().toUpper();
listWidgetAuthors->addItem(author);

// Clear lineEdits and set focus
lineEditFirstName->clear();
lineEditLastName->clear();
lineEditFirstName->setFocus();
}

void BookInput::removeAuthor()
{
listWidgetAuthors->takeItem(listWidgetAuthors->currentRow());
}

void BookInput::saveBook()
{
if (!isValidInput())
{
return;
}

// TODO: add book and author to model
}

void BookInput::cancel()
{
close();
}

void BookInput::setupUI()
{
// Window Attrbiutes
setWindowTitle("New Book");
setWindowModality(Qt::ApplicationModal);
resize(410, 472);

setupBookGroup();
setupAuthorGroup();
setupButtons();
}

void BookInput::setupBookGroup()
{
// Title
QLabel *labelTitle = new QLabel("Title", this);
lineEditTitle->setToolTip("The book's title");
gridLayoutBook->addWidget(labelTitle, 0, 0);
gridLayoutBook->addWidget(lineEditTitle, 0, 1, 1, 3);

// ISBN
QLabel *labelIsbn = new QLabel("ISBN", this);
gridLayoutBook->addWidget(labelIsbn, 1, 0);
gridLayoutBook->addWidget(lineEditIsbn, 1, 1, 1, 3);

// Publication Date
QLabel *labelPublicationDate = new QLabel("Date Published", this);
dateEditPublicationDate->setDate(QDate::currentDate());
dateEditPublicationDate->setCalendarPopup(true);
dateEditPublicationDate->setMaximumDate(QDate::currentDate());
gridLayoutBook->addWidget(labelPublicationDate, 2, 0);
gridLayoutBook->addWidget(dateEditPublicationDate, 2, 1);

groupBoxBook->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
groupBoxBook->setLayout(gridLayoutBook);
mainLayout->addWidget(groupBoxBook, 0, 0, 1, 4);
}

void BookInput::setupAuthorGroup()
{
// First name
QLabel *labelFirstName = new QLabel("First Name");
lineEditFirstName->setToolTip("Author's first name");
gridLayoutAuthor->addWidget(labelFirstName, 0, 0);
gridLayoutAuthor->addWidget(lineEditFirstName,0 , 1, 1, 3);

// Last name
QLabel *labelLastName = new QLabel("Last Name");
lineEditLastName->setToolTip("Author's last name");
gridLayoutAuthor->addWidget(labelLastName, 1, 0);
gridLayoutAuthor->addWidget(lineEditLastName, 1, 1, 1, 3);

// Add author button
gridLayoutAuthor->addWidget(pushButtonAddAuthor, 2, 0, 1, 4);

// List widget
gridLayoutAuthor->addWidget(listWidgetAuthors, 3, 0, 1, 4);

// Remove author button
pushButtonRemoveAuthor->setFixedSize(30, 30);
gridLayoutAuthor->addWidget(pushButtonRemoveAuthor, 3, 4, 1, 1);
// pushButtonRemoveAuthor->setIcon(QIcon(":/icons/removeAuthor"));
pushButtonRemoveAuthor->setIconSize(pushButtonRemoveAuthor->size());
gridLayoutAuthor->addWidget(pushButtonRemoveAuthor, 3, 4, Qt::AlignRight, 1);

// Group box and layout
groupBoxAuthor->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
groupBoxAuthor->setLayout(gridLayoutAuthor);
mainLayout->addWidget(groupBoxAuthor, 1, 0, 1, 4);
}

void BookInput::setupButtons()
{
pushButtonSave->setToolTip("Save the book to the list");
mainLayout->addWidget(pushButtonSave, 3, 0, 1, 4);
mainLayout->addWidget(pushButtonCancel, 4, 0, 1, 4);
}

bool BookInput::isValidInput()
{
// Check if title is empty
if (lineEditTitle->text().isEmpty())
{
QMessageBox::warning(this, "Input Error", "Please enter a title for the book.");
lineEditTitle->setFocus();
return false;
}

// Check if ISBN is empty or invalid
static QRegularExpression isbnRegex("\\d{3}-\\d{1,5}-\\d{1,7}-\\d{1,7}-\\d{1}");
QRegularExpressionMatch isbnMatch = isbnRegex.match(lineEditIsbn->text());
if (lineEditIsbn->text().isEmpty() || !isbnMatch.hasMatch())
{
QMessageBox::warning(this, "Input Error", "Please enter a valid ISBN (format: 978-3-16-148410-0).");
lineEditIsbn->setFocus();
return false;
}

// Check if at least one author is added
if (listWidgetAuthors->count() == 0)
{
QMessageBox::warning(this, "Input Error", "Please add at least one author.");
lineEditFirstName->setFocus();
return false;
}

// If all checks pass
return true;
}
53 changes: 53 additions & 0 deletions COS3711-03-01/src/bookinput.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#ifndef BOOKINPUT_H
#define BOOKINPUT_H

#include <QDialog>

class QDateEdit;
class QGridLayout;
class QGroupBox;
class QLineEdit;
class QListWidget;
class QPushButton;


class BookInput : public QDialog
{
Q_OBJECT
public:
explicit BookInput(QWidget *parent = nullptr);
// TODO: inject model into constructor

~BookInput();

private slots:
void addAuthor();
void removeAuthor();
void saveBook();
void cancel();

private:
void setupUI();
void setupBookGroup();
void setupAuthorGroup();
void setupButtons();
bool isValidInput();

QLineEdit *lineEditTitle;
QLineEdit *lineEditIsbn;
QDateEdit *dateEditPublicationDate;
QLineEdit *lineEditFirstName;
QLineEdit *lineEditLastName;
QPushButton *pushButtonAddAuthor;
QListWidget *listWidgetAuthors;
QPushButton *pushButtonRemoveAuthor;
QPushButton *pushButtonSave;
QPushButton *pushButtonCancel;
QGridLayout *mainLayout;
QGridLayout *gridLayoutBook;
QGridLayout *gridLayoutAuthor;
QGroupBox *groupBoxBook;
QGroupBox *groupBoxAuthor;
};

#endif // BOOKINPUT_H
1 change: 1 addition & 0 deletions COS3711-03-01/src/icons/exit_to_app_24dp.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading