Skip to content

Commit 608eb94

Browse files
authored
Merge branch 'dev' into feature/book-input
2 parents 4544301 + 8b4bdc4 commit 608eb94

19 files changed

+579
-73
lines changed

.github/workflows/test.yml

+1-9
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ on:
88

99
jobs:
1010
test:
11-
needs: Build
12-
if: ${{ github.event.workflow_run.conclusion == 'success' }}
1311
runs-on: ubuntu-latest
12+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
1413

1514
steps:
1615
- name: Checkout Repository
@@ -21,13 +20,6 @@ jobs:
2120
sudo apt-get update
2221
sudo apt-get install -y libgl1-mesa-dev qt6-base-dev qt6-tools-dev qt6-tools-dev-tools cmake g++
2322
24-
- name: Build project
25-
run: |
26-
mkdir -p build
27-
cd build
28-
cmake ..
29-
make
30-
3123
- name: Build and run unit tests
3224
run: |
3325
cd build

COS3711-03-01/COS3711-03-01.drawio

+13-25
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
<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">
1+
<mxfile host="Electron" modified="2024-08-06T13:08:42.070Z" 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="2MUYOWNRhgzR3xg8WMUV" version="24.6.4" type="device">
22
<diagram id="6iuWq0UelAJ61aAoiBDy" name="Book Shelf">
3-
<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">
3+
<mxGraphModel dx="1288" dy="1299" 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">
44
<root>
55
<mxCell id="0" />
66
<mxCell id="1" parent="0" />
@@ -97,42 +97,24 @@
9797
<mxCell id="gvHln3FCuM-_E14BoruI-77" value="+ BookProxyModel(parent: QObject)&lt;div&gt;+ setFilterText(filterText: 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-74" vertex="1">
9898
<mxGeometry y="34" width="500" height="56" as="geometry" />
9999
</mxCell>
100-
<mxCell id="gvHln3FCuM-_E14BoruI-78" value="&lt;div&gt;BookView&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">
101-
<mxGeometry x="1050" y="-610" width="400" height="98" as="geometry" />
102-
</mxCell>
103-
<mxCell id="gvHln3FCuM-_E14BoruI-79" value="- tableView: QTableView&lt;div&gt;- model: BookTableModel&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-78" vertex="1">
104-
<mxGeometry y="26" width="400" height="34" as="geometry" />
105-
</mxCell>
106-
<mxCell id="gvHln3FCuM-_E14BoruI-80" 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-78" vertex="1">
107-
<mxGeometry y="60" width="400" height="8" as="geometry" />
108-
</mxCell>
109-
<mxCell id="gvHln3FCuM-_E14BoruI-81" value="&lt;div&gt;+ addBook(title: QString, authors: QString, isbn: QString, date: 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-78" vertex="1">
110-
<mxGeometry y="68" width="400" height="30" as="geometry" />
111-
</mxCell>
112100
<mxCell id="we9DT2KBn4o6eFFRd77e-5" value="&lt;div&gt;MainWindow&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;" vertex="1" parent="1">
113-
<mxGeometry x="1670" y="-375" width="500" height="360" as="geometry" />
101+
<mxGeometry x="1670" y="-410" width="500" height="310" as="geometry" />
114102
</mxCell>
115-
<mxCell id="we9DT2KBn4o6eFFRd77e-6" value="&lt;div&gt;- bookView: BookView&lt;/div&gt;&lt;div&gt;- bookModel: BookModel&lt;/div&gt;&lt;div&gt;- menuBar: QMenuBar&lt;/div&gt;&lt;div&gt;- statusBar: QStatusBar&lt;/div&gt;&lt;div&gt;- toolBar: QToolBar&lt;/div&gt;&lt;div&gt;- actionAddBook: QAction&lt;/div&gt;&lt;div&gt;- actionExportBooks: QAction&lt;/div&gt;&lt;div&gt;- actionSearchBook: QAction&lt;/div&gt;&lt;div&gt;- actionCloseApplicationWindow(): QAction&lt;/div&gt;&lt;div&gt;- lineEditSearch: QLineEdit&lt;/div&gt;&lt;div&gt;- pushButtonClear: QPushButton&lt;/div&gt;&lt;div&gt;- proxyModel: BookFilterProxyModel&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">
116-
<mxGeometry y="26" width="500" height="184" as="geometry" />
103+
<mxCell id="we9DT2KBn4o6eFFRd77e-6" value="&lt;div&gt;&lt;span style=&quot;background-color: initial;&quot;&gt;- bookModel: BookModel&lt;/span&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;- proxyModel: BookFilterProxyModel&lt;/div&gt;&lt;div&gt;- bookTableView: QTableView&lt;br&gt;&lt;/div&gt;&lt;div&gt;- actionAddBook: QAction&lt;/div&gt;&lt;div&gt;- actionExportBooks: QAction&lt;/div&gt;&lt;div&gt;- actionClose: QAction&lt;/div&gt;&lt;div&gt;- lineEditSearch: QLineEdit&lt;/div&gt;&lt;div&gt;- pushButtonClear: QPushButton&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;" vertex="1" parent="we9DT2KBn4o6eFFRd77e-5">
104+
<mxGeometry y="26" width="500" height="134" as="geometry" />
117105
</mxCell>
118106
<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">
119-
<mxGeometry y="210" width="500" height="8" as="geometry" />
107+
<mxGeometry y="160" width="500" height="8" as="geometry" />
120108
</mxCell>
121109
<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">
122-
<mxGeometry y="218" width="500" height="142" as="geometry" />
110+
<mxGeometry y="168" width="500" height="142" as="geometry" />
123111
</mxCell>
124112
<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">
125113
<mxGeometry width="160" relative="1" as="geometry">
126114
<mxPoint x="660" y="-470" as="sourcePoint" />
127115
<mxPoint x="820" y="-470" as="targetPoint" />
128116
</mxGeometry>
129117
</mxCell>
130-
<mxCell id="we9DT2KBn4o6eFFRd77e-10" value="" style="endArrow=diamondThin;endFill=1;endSize=24;html=1;rounded=0;" edge="1" parent="1" source="gvHln3FCuM-_E14BoruI-78" target="we9DT2KBn4o6eFFRd77e-5">
131-
<mxGeometry width="160" relative="1" as="geometry">
132-
<mxPoint x="1340" y="-680" as="sourcePoint" />
133-
<mxPoint x="1500" y="-680" as="targetPoint" />
134-
</mxGeometry>
135-
</mxCell>
136118
<mxCell id="we9DT2KBn4o6eFFRd77e-11" value="" style="endArrow=diamondThin;endFill=0;endSize=24;html=1;rounded=0;" edge="1" parent="1" source="gvHln3FCuM-_E14BoruI-51" target="gvHln3FCuM-_E14BoruI-74">
137119
<mxGeometry width="160" relative="1" as="geometry">
138120
<mxPoint x="780" y="490" as="sourcePoint" />
@@ -181,6 +163,12 @@
181163
<mxPoint x="2450" y="10" as="targetPoint" />
182164
</mxGeometry>
183165
</mxCell>
166+
<mxCell id="8dgmckmYpp2PSS6kHg5K-3" value="Use" style="endArrow=open;endSize=12;dashed=1;html=1;rounded=0;" edge="1" parent="1" source="gvHln3FCuM-_E14BoruI-65" target="we9DT2KBn4o6eFFRd77e-14">
167+
<mxGeometry width="160" relative="1" as="geometry">
168+
<mxPoint x="1370" y="70" as="sourcePoint" />
169+
<mxPoint x="1530" y="70" as="targetPoint" />
170+
</mxGeometry>
171+
</mxCell>
184172
</root>
185173
</mxGraphModel>
186174
</diagram>

COS3711-03-01/src/CMakeLists.txt

+4-1
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,13 @@ set(PROJECT_SOURCES
1818
author.h author.cpp
1919
book.h book.cpp
2020
bookinput.h bookinput.cpp
21+
booktablemodel.h booktablemodel.cpp
22+
bookproxymodel.h bookproxymodel.cpp
2123
)
2224

2325
# Create library
24-
add_library(MyProjectLib ${PROJECT_SOURCES})
26+
add_library(MyProjectLib ${PROJECT_SOURCES}
27+
bookfactory.h bookfactory.cpp)
2528

2629
# Include directories for the library
2730
target_include_directories(MyProjectLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

COS3711-03-01/src/bookfactory.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "bookfactory.h"
2+
#include "book.h"
3+
4+
5+
BookFactory::BookFactory() {}
6+
7+
BookFactory &BookFactory::getInstance()
8+
{
9+
static BookFactory bookFactoryInstance;
10+
return bookFactoryInstance;
11+
}
12+
13+
Book *BookFactory::createBook(const QString &title, const QStringList &authors, const QString &isbn, const QDate &publicationDate)
14+
{
15+
if (title.isEmpty() || authors.isEmpty() || isbn.isEmpty() || !publicationDate.isValid())
16+
{
17+
return nullptr;
18+
}
19+
return new Book(title, authors, isbn, publicationDate);
20+
}

COS3711-03-01/src/bookfactory.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef BOOKFACTORY_H
2+
#define BOOKFACTORY_H
3+
4+
class Book;
5+
class QDate;
6+
class QString;
7+
8+
#include <QStringList>
9+
10+
11+
class BookFactory
12+
{
13+
public:
14+
static BookFactory &getInstance();
15+
Book *createBook(const QString &title, const QStringList &authors, const QString &isbn, const QDate &publicationDate);
16+
17+
private:
18+
BookFactory();
19+
BookFactory(const BookFactory&) = delete;
20+
BookFactory &operator=(const BookFactory&) = delete;
21+
};
22+
23+
#endif // BOOKFACTORY_H

COS3711-03-01/src/bookproxymodel.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "bookproxymodel.h"
2+
3+
#include <QRegularExpression>
4+
5+
6+
BookProxyModel::BookProxyModel(QObject *parent)
7+
: QSortFilterProxyModel{parent}
8+
{}
9+
10+
void BookProxyModel::setFilter(const QString &filterText)
11+
{
12+
QRegularExpression titleRegex(filterText, QRegularExpression::CaseInsensitiveOption);
13+
setFilterRegularExpression(titleRegex);
14+
}

COS3711-03-01/src/bookproxymodel.h

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef BOOKPROXYMODEL_H
2+
#define BOOKPROXYMODEL_H
3+
4+
#include <QSortFilterProxyModel>
5+
6+
class BookProxyModel : public QSortFilterProxyModel
7+
{
8+
Q_OBJECT
9+
public:
10+
explicit BookProxyModel(QObject *parent = nullptr);
11+
12+
public slots:
13+
void setFilter(const QString &filterText);
14+
};
15+
16+
#endif // BOOKPROXYMODEL_H

COS3711-03-01/src/booktablemodel.cpp

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#include "booktablemodel.h"
2+
#include "book.h"
3+
4+
5+
BookTableModel::BookTableModel(QObject *parent)
6+
: QAbstractTableModel{parent}
7+
{}
8+
9+
BookTableModel::~BookTableModel()
10+
{
11+
qDeleteAll(bookList);
12+
}
13+
14+
int BookTableModel::rowCount(const QModelIndex &parent) const
15+
{
16+
if (parent.isValid())
17+
{
18+
return 0;
19+
}
20+
return bookList.size();
21+
}
22+
23+
int BookTableModel::columnCount(const QModelIndex &parent) const
24+
{
25+
26+
if (parent.isValid())
27+
{
28+
return 0;
29+
}
30+
return 4; // title, authors, publication date, isbn
31+
}
32+
33+
QVariant BookTableModel::data(const QModelIndex &index, int role) const
34+
{
35+
if (!index.isValid())
36+
{
37+
return QVariant();
38+
}
39+
40+
if (role == Qt::DisplayRole)
41+
{
42+
int col = index.column();
43+
int row = index.row();
44+
45+
if (col == 0) { return bookList.at(row)->getTitle(); }
46+
if (col == 1)
47+
{
48+
if (bookList.at(row)->getAuthors().count() == 1)
49+
{
50+
return bookList.at(row)->getAuthors();
51+
}
52+
else if (bookList.at(row)->getAuthors().count() > 1)
53+
{
54+
return bookList.at(row)->getAuthors().join("; ");
55+
}
56+
}
57+
if (col == 2) { return bookList.at(row)->getPublicationDate(); }
58+
if (col == 3) { return bookList.at(row)->getIsbn(); }
59+
}
60+
return QVariant();
61+
}
62+
63+
QVariant BookTableModel::headerData(int section, Qt::Orientation orientation, int role) const
64+
{
65+
if (role != Qt::DisplayRole)
66+
{
67+
return QVariant();
68+
}
69+
70+
if (orientation == Qt::Horizontal)
71+
{
72+
switch(section)
73+
{
74+
case 0:
75+
return QString("Title");
76+
break;
77+
case 1:
78+
return QString("Author");
79+
break;
80+
case 2:
81+
return QString("Publication Date");
82+
break;
83+
case 3:
84+
return QString("ISBN");
85+
break;
86+
}
87+
}
88+
return QVariant();
89+
}
90+
91+
bool BookTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
92+
{
93+
if (index.isValid() && role == Qt::EditRole)
94+
{
95+
int col = index.column();
96+
int row = index.row();
97+
98+
switch (col)
99+
{
100+
case 0:
101+
bookList.at(row)->setTitle(value.toString());
102+
break;
103+
case 1:
104+
bookList.at(row)->setAuthors(value.toStringList());
105+
break;
106+
case 2:
107+
bookList.at(row)->setPublicationDate(value.toDate());
108+
break;
109+
case 3:
110+
bookList.at(row)->setIsbn(value.toString());
111+
break;
112+
}
113+
emit dataChanged(index, index, { role });
114+
return true;
115+
}
116+
return false;
117+
}
118+
119+
Qt::ItemFlags BookTableModel::flags(const QModelIndex &index) const
120+
{
121+
if (index.isValid())
122+
{
123+
return (Qt::ItemIsEnabled | Qt::ItemIsSelectable);
124+
}
125+
else
126+
{
127+
return Qt::NoItemFlags;
128+
}
129+
}
130+
131+
void BookTableModel::addBook(Book *book)
132+
{
133+
int row = bookList.size();
134+
beginInsertRows(QModelIndex(), row, row);
135+
bookList.append(book);
136+
endInsertRows();
137+
}

COS3711-03-01/src/booktablemodel.h

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#ifndef BOOKTABLEMODEL_H
2+
#define BOOKTABLEMODEL_H
3+
4+
#include <QAbstractTableModel>
5+
6+
class Book;
7+
8+
9+
class BookTableModel : public QAbstractTableModel
10+
{
11+
public:
12+
explicit BookTableModel(QObject *parent = nullptr);
13+
~BookTableModel();
14+
int rowCount(const QModelIndex &parent) const override;
15+
int columnCount(const QModelIndex &parent) const override;
16+
QVariant data(const QModelIndex &index, int role) const override;
17+
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
18+
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
19+
Qt::ItemFlags flags(const QModelIndex &index) const override;
20+
21+
void addBook(Book *book);
22+
23+
private:
24+
QList<Book*> bookList;
25+
26+
};
27+
28+
#endif // BOOKTABLEMODEL_H

0 commit comments

Comments
 (0)