Скачиваний:
11
Добавлен:
15.08.2023
Размер:
431.42 Кб
Скачать

Объекты:

1. Объект двусвязного списка – list<pair<int, FootbalPlayer>> table[hashGroups]

4.7 FootbalPlayer – класс описания футбольного игрока

Поля класса:

1. Номер игрока – size_t number

2. Возраст игрока – size_t age

3. Рейтинг игрока – string rate

4. Имя игрока – string name

5. Команда игрока – string team

Методы класса:

1. Сеттер номера игрока – setPlayerNumber(size_t _number)

2. Сеттер возраста игрока – setPlayerAge(size_t _age)

3. Сеттер рейтинга игрока – setPlayerRate(string _rate)

4. Сеттер имени игрока – setPlayerName(string _name)

5. Сеттер команды игрока – setPlayerTeam(string _team)

6. Геттер номера игрока - getPlayerNumber()

7. Геттер возраста игрока - getPlayerAge()

8. Геттер рейтинга игрока – getPlayerRate()

9. Геттер имени игрока – getPlayerName()

10. Геттер команды игрока – getPlayerTeam()

Перегрузка:

1. Оператор <<

5 Разработка интерфейса

Основное окно программы (размер окна не меняется)

(Рисунок 1) – главный экран программы

На главном экране содержатся пункты «Файл», «Изменить», панель инструментов и рабочая область.

Во вкладке «Файл» находятся функции для чтения/сохранения/создания файлов базы данных, а также выход из редактора.

Вкладка «Изменить» содержит в себе основной инструментарий для взаимодействия с базой данных.

Все инструменты из вкладок продублированы на панель инструментов.

Основную рабочую область занимает визуальное представление базы данных.

Так же, прямо под рабочей областью имеется строка статуса, указывающая на количество элементов в таблице.

6 Инструкция пользователю Создание | чтение базы данных:

После запуска программы вы можете создать новую базу данных нажав на иконку , находящуюся на панели инструментов, нажатием соответствующей кнопки во вкладке «Файл» или комбинацией клавиш ctrl+N . Вы так же можете открыть уже существующую базу данных, кликнув на иконку , которая также находится на панели инструментов, во вкладке «Файл» и доступна по нажатию комбинации клавиш ctrl+O

Чтобы добавить новый элемент в базу данных – нажмите на иконку , после вам чего откроется окно добавление нового элемента в базу данных, где следует ввести номер, возраст, рейтинг, имя и команду вашего

игрока.

После того как вы закончили ввод всех нужных данных – нажмите на кнопку «ОК», это автоматически добавит элемент в базу данных.

Изменение базы данных:

Для изменения объекта базы данных – нажмите на иконку и введите новые данные в открывшемся окне.

После нажатия на кнопку «ОК» запись в базе данных автоматически изменится.

Сохранение базы данных:

Создадим базу данных из нескольких игроков и сохраним её нажатием на иконку , в открывшемся окне можно ввести имя файла.

Слияние баз данных:

Чтобы начать слияние баз данных – нажмите на иконку или выберете соответствующий пункт в меню «Изменить», в предложенном окне выберете файл базы данных, который хотите совместить с имеющийся базой данных и нажмите «открыть»

По окончании процесса – базы сольются в одну.

Поиск по базе данных:

Вы можете с лёгкостью найти нужный вам элемент базы данных, нажав на иконку или комбинацией ctrl+f , в предложенном окне введите поисковой запрос и нажмите «ОК».

Найденный элемент отметится жёлтым цветом и пропадёт через некоторое время.

Удаление элемента из базы данных:

Чтобы удалить элемент из базы данных – выделите строчку кликните на строчку таблицы, которую вы хотите удалить и нажмите на иконку , или комбинацию клавиш ctrl+D, на вопрос об удалении ответить «да» после чего элемент автоматически удалится из базы данных.

Информация о программе:

Чтобы получить информацию о программе – нажмите на иконку на панели инструментов, вам откроется окно со всей информацией.

Комбинации горячих клавиш:

Открыть файл

Ctrl+O

Добавить объект

Ctrl+A

Удалить объект

Ctrl+D

Слияние баз данных

Ctrl+M

Создать новый файл

Ctrl+N

Информация о программе

Ctrl+H

Редактировать элемент

Ctrl+E

7 Код программы

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)

project(CourseWork_OOP LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOUIC ON)

set(CMAKE_AUTOMOC ON)

set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 11)

set(CMAKE_CXX_STANDARD_REQUIRED ON)

# QtCreator supports the following variables for Android, which are identical to qmake Android variables.

# Check http://doc.qt.io/qt-5/deployment-android.html for more information.

# They need to be set before the find_package(Qt5 ...) call.

#if(ANDROID)

# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android")

# if (ANDROID_ABI STREQUAL "armeabi-v7a")

# set(ANDROID_EXTRA_LIBS

# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so

# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so)

# endif()

#endif()

find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED)

find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED)

if(ANDROID)

add_library(CourseWork_OOP SHARED

main.cpp

FootbalPlayer.cpp

FootbalPlayer.h

HashTable.cpp

HashTable.h

FDB.cpp

FDB.h

dbwindow.cpp

dbwindow.h

dbwindow.ui

icons.qrc

newitemdialog.cpp

newitemdialog.h

newitemdialog.ui

fininddb.h

fininddb.cpp

fininddb.ui

)

else()

add_executable(CourseWork_OOP

main.cpp

FootbalPlayer.cpp

FootbalPlayer.h

HashTable.cpp

HashTable.h

FDB.cpp

FDB.h

dbwindow.cpp

dbwindow.h

dbwindow.ui

icons.qrc

newitemdialog.cpp

newitemdialog.h

newitemdialog.ui

fininddb.h

fininddb.cpp

fininddb.ui

editdialog.cpp

editdialog.h

editdialog.ui

)

endif()

target_link_libraries(CourseWork_OOP PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

dbWindow.h

#ifndef DBWINDOW_H

#define DBWINDOW_H

#include <QMainWindow>

#include <QFile>

#include <QFileDialog>

#include <QTextStream>

#include <QMessageBox>

#include "HashTable.h"

#include "FDB.h"

#include "FootbalPlayer.h"

QT_BEGIN_NAMESPACE

namespace Ui { class dbWindow; }

QT_END_NAMESPACE

class dbWindow : public QMainWindow

{

Q_OBJECT

public:

// main database

FDB fdb;

// redraw database when it gets update

void reDrawTable();

// constructor

dbWindow(QWidget *parent = nullptr);

// destructor

~dbWindow();

private:

// ui object

Ui::dbWindow *ui;

protected:

// initialize window

void initWindow();

// load FootbalPlayer class to data base

void ldDbToTable();

// return true if something edit

bool isEdit = false;

private slots:

// New file button

void on_actionNew_triggered();

// Open file button

void on_actionOpen_triggered();

// Save bfile button

void on_actionSave_triggered();

// Add new element in database button

void on_actionAdd_new_item_triggered();

// Sets new item to table from add item dialog

void setNewTableItemFromDialog(int number, int age, string rate, string name, string team);

// Try to fimd item in table by name,number,age,team,rating

void findItemInWidgetTable(QString wantedLine);

// Delte particular item from database

void on_actionDelete_item_triggered();

// Merge two databases betwwn

void on_actionMerge_triggered();

// Find item button

void on_actionFind_triggered();

// Show some programm button

void on_actionHelp_triggered();

// Edit item button

void on_actionEdit_item_triggered();

void on_actionExit_triggered();

public slots:

// Take info from edit form

void replaceTableItem(int number, int age, string rate, string name, string team);

signals:

// Signal goes to edit form

void sendToEditForm(int number, int age, string rate, string name, string team);

private:

// Shows item amount in table

void showItemAmountStatus();

};

#endif // DBWINDOW_H

dbwindow.ui

<?xml version="1.0" encoding="UTF-8"?>

<ui version="4.0">

<class>dbWindow</class>

<widget class="QMainWindow" name="dbWindow">

<property name="geometry">

<rect>

<x>0</x>

<y>0</y>

<width>793</width>

<height>600</height>

</rect>

</property>

<property name="sizePolicy">

<sizepolicy hsizetype="Fixed" vsizetype="Fixed">

<horstretch>0</horstretch>

<verstretch>0</verstretch>

</sizepolicy>

</property>

<property name="minimumSize">

<size>

<width>793</width>

<height>600</height>

</size>

</property>

<property name="maximumSize">

<size>

<width>793</width>

<height>600</height>

</size>

</property>

<property name="font">

<font>

<family>Verdana</family>

</font>

</property>

<property name="windowTitle">

<string>FootballDatabase</string>

</property>

<widget class="QWidget" name="centralwidget">

<widget class="QWidget" name="verticalLayoutWidget">

<property name="geometry">

<rect>

<x>0</x>

<y>0</y>

<width>741</width>

<height>531</height>

</rect>

</property>

<layout class="QVBoxLayout" name="verticalLayout">

<item>

<widget class="QTableWidget" name="tableWidget"/>

</item>

</layout>

</widget>

<widget class="QWidget" name="verticalLayoutWidget_3">

<property name="geometry">

<rect>

<x>0</x>

<y>530</y>

<width>741</width>

<height>24</height>

</rect>

</property>

<layout class="QVBoxLayout" name="verticalLayout_3">

<item>

<widget class="QLineEdit" name="lineEdit">

<property name="cursor">

<cursorShape>ArrowCursor</cursorShape>

</property>

<property name="readOnly">

<bool>true</bool>

</property>

</widget>

</item>

</layout>

</widget>

</widget>

<widget class="QMenuBar" name="menubar">

<property name="geometry">

<rect>

<x>0</x>

<y>0</y>

<width>793</width>

<height>20</height>

</rect>

</property>

<widget class="QMenu" name="menuFile">

<property name="title">

<string>File</string>

</property>

<addaction name="actionNew"/>

<addaction name="actionOpen"/>

<addaction name="actionSave"/>

<addaction name="actionHelp"/>

<addaction name="actionExit"/>

</widget>

<widget class="QMenu" name="menuEdit">

<property name="title">

<string>Edit</string>

</property>

<addaction name="actionAdd_new_item"/>

<addaction name="actionDelete_item"/>

<addaction name="actionEdit_item"/>

<addaction name="actionFind"/>

<addaction name="actionMerge"/>

<addaction name="actionUndo"/>

<addaction name="actionRedo"/>

</widget>

<addaction name="menuFile"/>

<addaction name="menuEdit"/>

</widget>

<widget class="QStatusBar" name="statusbar"/>

<widget class="QToolBar" name="toolBar">

<property name="sizePolicy">

<sizepolicy hsizetype="Fixed" vsizetype="Preferred">

<horstretch>0</horstretch>

<verstretch>0</verstretch>

</sizepolicy>

</property>

<property name="windowTitle">

<string>toolBar</string>

</property>

<property name="allowedAreas">

<set>Qt::LeftToolBarArea|Qt::RightToolBarArea</set>

</property>

<attribute name="toolBarArea">

<enum>LeftToolBarArea</enum>

</attribute>

<attribute name="toolBarBreak">

<bool>false</bool>

</attribute>

<addaction name="actionNew"/>

<addaction name="actionOpen"/>

<addaction name="actionSave"/>

<addaction name="actionUndo"/>

<addaction name="actionRedo"/>

<addaction name="actionAdd_new_item"/>

<addaction name="actionDelete_item"/>

<addaction name="actionEdit_item"/>

<addaction name="actionMerge"/>

<addaction name="actionFind"/>

<addaction name="actionHelp"/>

</widget>

<action name="actionOpen">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/open.png</normaloff>:/icons/open.png</iconset>

</property>

<property name="text">

<string>Open</string>

</property>

<property name="shortcut">

<string>Ctrl+O</string>

</property>

</action>

<action name="actionSave">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/save.png</normaloff>:/icons/save.png</iconset>

</property>

<property name="text">

<string>Save</string>

</property>

<property name="shortcut">

<string>Ctrl+S</string>

</property>

</action>

<action name="actionExit">

<property name="text">

<string>Exit</string>

</property>

</action>

<action name="actionAdd_new_item">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/additem.png</normaloff>:/icons/additem.png</iconset>

</property>

<property name="text">

<string>Insert new item</string>

</property>

<property name="shortcut">

<string>Ctrl+A</string>

</property>

</action>

<action name="actionDelete_item">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/removeitem.png</normaloff>:/icons/removeitem.png</iconset>

</property>

<property name="text">

<string>Remove item</string>

</property>

<property name="shortcut">

<string>Ctrl+D</string>

</property>

</action>

<action name="actionMerge">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/merge.png</normaloff>:/icons/merge.png</iconset>

</property>

<property name="text">

<string>Merge</string>

</property>

<property name="shortcut">

<string>Ctrl+M</string>

</property>

</action>

<action name="actionFind">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/find.png</normaloff>:/icons/find.png</iconset>

</property>

<property name="text">

<string>Find</string>

</property>

<property name="shortcut">

<string>Ctrl+F</string>

</property>

</action>

<action name="actionUndo">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/undo.png</normaloff>:/icons/undo.png</iconset>

</property>

<property name="text">

<string>Undo</string>

</property>

<property name="shortcut">

<string>Ctrl+Z</string>

</property>

</action>

<action name="actionRedo">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/redo.png</normaloff>:/icons/redo.png</iconset>

</property>

<property name="text">

<string>Redo</string>

</property>

<property name="shortcut">

<string>Ctrl+Shift+Z</string>

</property>

</action>

<action name="actionNew">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/new.png</normaloff>:/icons/new.png</iconset>

</property>

<property name="text">

<string>New</string>

</property>

<property name="shortcut">

<string>Ctrl+N</string>

</property>

</action>

<action name="actionHelp">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/help.png</normaloff>:/icons/help.png</iconset>

</property>

<property name="text">

<string>Help</string>

</property>

<property name="shortcut">

<string>Ctrl+H</string>

</property>

</action>

<action name="actionEdit_item">

<property name="icon">

<iconset resource="icons.qrc">

<normaloff>:/icons/edit.png</normaloff>:/icons/edit.png</iconset>

</property>

<property name="text">

<string>Edit item</string>

</property>

<property name="shortcut">

<string>Ctrl+E</string>

</property>

</action>

</widget>

<resources>

<include location="icons.qrc"/>

</resources>

<connections/>

</ui>

dbwindow.cpp

#include "dbwindow.h"

#include "./ui_dbwindow.h"

#include <QDebug>

#include <QHelpEvent>

#include "newitemdialog.h"

#include "fininddb.h"

#include "editdialog.h"

// REDRAW TABLE WHEN IT GETS UPDATE

void dbWindow::reDrawTable()

{

for (size_t i{}; i < ui->tableWidget->rowCount(); i++)

{

// GIVES ARGUMENT FOR EACH CELL INDIVIDUALLY

ui->tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(fdb.DataBase.getPlayerNumber(fdb.DataBase.get_index(i)))));

ui->tableWidget->setItem(i, 1, new QTableWidgetItem(QString::number(fdb.DataBase.getPlayerAge(fdb.DataBase.get_index(i)))));

ui->tableWidget->setItem(i, 2, new QTableWidgetItem(QString::fromStdString(fdb.DataBase.getPlayerRating(fdb.DataBase.get_index(i)))));

ui->tableWidget->setItem(i, 3, new QTableWidgetItem(QString::fromStdString(fdb.DataBase.getPlayerName(fdb.DataBase.get_index(i)))));

ui->tableWidget->setItem(i, 4, new QTableWidgetItem(QString::fromStdString(fdb.DataBase.getPlayerTeam(fdb.DataBase.get_index(i)))));

// AUTOMATICALLY RESIZE ALL COLUMNS TO TEXT SIZE IN THERE

ui->tableWidget->resizeColumnsToContents();

}

}

dbWindow::dbWindow(QWidget *parent)

: QMainWindow(parent)

, ui(new Ui::dbWindow)

{

initWindow();

}

dbWindow::~dbWindow()

{

delete ui;

}

// SOME LOADS ON WINDOW INITIALISATION

void dbWindow::initWindow()

{

ui->setupUi(this);

ui->tableWidget->setColumnCount(5); // CONSTANT CPLUMN COUNT ONLY

ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "Номер" << "Возраст" << "Рейтинг" << "Имя" << "Команда"); // COLUMNS NAME

ui->tableWidget->horizontalHeader()->setStretchLastSection(true); // STRETCHING ALL LAST CELLS TO TABLE BORDER

ui->tableWidget->resizeColumnsToContents(); // RESIZE ALL CELLS TO TEXT SIZE IN THERE

}

// LOAD ITEMS FROM DATABASE CONTAINER TO DATABASE TABLE WIDGET

void dbWindow::ldDbToTable()

{

QString param;

ui->tableWidget->setRowCount(fdb.DataBase.index_amount()); // SETS THE SAME ROW AMOUNT WITH DATABASE INDEX COUNTER

for (size_t i{}; i < ui->tableWidget->rowCount(); i++)

{

// SETS ITEMS TO TABLE WIDGET FROM ACTUAL DATABASE IN INDIVIDUAL CELLS

ui->tableWidget->setItem(i, 0, new QTableWidgetItem(QString::number(fdb.DataBase.getPlayerNumber(fdb.DataBase.get_index(i))))); // NUMBER

ui->tableWidget->setItem(i, 1, new QTableWidgetItem(QString::number(fdb.DataBase.getPlayerAge(fdb.DataBase.get_index(i))))); // AGE

param = param.fromStdString(fdb.DataBase.getPlayerRating(fdb.DataBase.get_index(i)));

ui->tableWidget->setItem(i, 2, new QTableWidgetItem(param)); // RATING

param.clear();

param = param.fromStdString(fdb.DataBase.getPlayerName(fdb.DataBase.get_index(i))); // NAME

ui->tableWidget->setItem(i, 3, new QTableWidgetItem(param));

param.clear();

param = param.fromStdString(fdb.DataBase.getPlayerTeam(fdb.DataBase.get_index(i))); // TEAM

ui->tableWidget->setItem(i, 4, new QTableWidgetItem(param));

param.clear();

ui->tableWidget->scrollToBottom(); // TRYING SCROLL TO BOTTOM... DOESN'T WORK -_- TODO: MAKE SCROLL TO BOTTOM WORK

ui->tableWidget->resizeColumnsToContents(); // RESIZE CELLS TO IT'S TEXT ONCE AGEAN

}

}

// NEW FILE BUTTON

void dbWindow::on_actionNew_triggered()

{

// JUST MAKING IT FUNCTION WORK IF NOTHING HAS BEEN READACTED

if (isEdit == false)

{

fdb.DataBase.clear();

ui->tableWidget->setRowCount(0);

ui->tableWidget->clearContents();

}

// OR ASK "IS YOU WANT TO SAVE YOUR PROGRESS"

else

{

QMessageBox::StandardButton reply = QMessageBox::question(this, "Delete", "Весь несохранённый прогресс будет утерян, хотите продолжить?", QMessageBox::Yes|QMessageBox::No);

if (reply == QMessageBox::Yes)

{

// CLEAR ALL DATA IF ANSWER = YES

fdb.DataBase.clear();

ui->tableWidget->setRowCount(0);

ui->tableWidget->clearContents();

}

// DO NOTHING IF ANSWER = NO

}

// SHOW ITEM AMOUNT TO THE STATUS LINE

showItemAmountStatus();

}

// TRY TO OPEN FILE

void dbWindow::on_actionOpen_triggered()

{

//tr("Database files (*.fdb, *.efdb, *.txt)") - DOESN'T WORK FOR SOME REASON

QString filename = QFileDialog::getOpenFileName(this, tr("Open file"), ""); // GETS FILE PATH FROM EXPLORER

string utf8text = filename.toUtf8().constData(); // COVERT QSTRING TO STD::STRING

fdb.open_n_place(utf8text);

ldDbToTable(); // LOAD OPEN DATABASE ITEMS TO PROGRAM

showItemAmountStatus(); // SHOW ITEM AMOUNT STATUS

}

// TRY SAVE FILE

void dbWindow::on_actionSave_triggered()

{

//, tr("Database files (*.fdb, *.efdb)") - DOESN'T WORK TOO (EXPLORER JUST DOESN'T SEE ANY FILES)

QString filename = QFileDialog::getSaveFileName(this, tr("Save file as"), "untitled-1.fdb"); // SUJJESTED NAME - "UNTITLED-1.FDB"

string utf8text = filename.toUtf8().constData();

fdb.writeToDB(utf8text);

isEdit = false; // TELLS PROGRAM THAT SOMETHING HAS BEEN EDIT

}

// ADD NEW ITEM BUTTON

void dbWindow::on_actionAdd_new_item_triggered()

{

// NEW ITEM WINDOW OBJECT

newItemDialog *NewWin;

NewWin = new newItemDialog(this);

// CONNECT SLOT AND NEWITEMDIALOG SIGNAL

connect(NewWin, &newItemDialog::acceptClicked, this, &dbWindow::setNewTableItemFromDialog);

NewWin->setModal(false);

NewWin->exec();

}

void dbWindow::setNewTableItemFromDialog(int number, int age, string rate, string name, string team)

{

ui->tableWidget->setRowCount(ui->tableWidget->rowCount()+1);

fdb.DataBase.insertItem(number, FootbalPlayer(number, age, rate, name, team));

ui->tableWidget->setItem(ui->tableWidget->rowCount()+1, 0, new QTableWidgetItem(QString::number(fdb.DataBase.getPlayerNumber(number))));

ui->tableWidget->setItem(ui->tableWidget->rowCount()+1, 1, new QTableWidgetItem(QString::number(fdb.DataBase.getPlayerAge(number))));

ui->tableWidget->setItem(ui->tableWidget->rowCount()+1, 2, new QTableWidgetItem(QString::fromStdString(fdb.DataBase.getPlayerRating(number))));

ui->tableWidget->setItem(ui->tableWidget->rowCount()+1, 3, new QTableWidgetItem(QString::fromStdString(fdb.DataBase.getPlayerName(number))));

ui->tableWidget->setItem(ui->tableWidget->rowCount()+1, 4, new QTableWidgetItem(QString::fromStdString(fdb.DataBase.getPlayerTeam(number))));

ui->tableWidget->clearContents();

ui->tableWidget->setRowCount(fdb.DataBase.index_amount());

reDrawTable();

showItemAmountStatus();

isEdit = true;

}

void dbWindow::findItemInWidgetTable(QString wantedLine)

{

for(size_t i{}; i < ui->tableWidget->rowCount(); i++)

for (size_t j{}; j < ui->tableWidget->columnCount(); j++)

{

if (ui->tableWidget->item(i,j)->text() == wantedLine)

{

ui->tableWidget->item(i,j)->setBackgroundColor(Qt::yellow);

}

}

}

void dbWindow::on_actionDelete_item_triggered()

{

QMessageBox::StandardButton reply = QMessageBox::question(this, "Delete", "Вы действительно хотите удалить этот слот?", QMessageBox::Yes|QMessageBox::No);

if (reply == QMessageBox::Yes)

{

if (ui->tableWidget->selectionModel()->hasSelection())

{

//ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectItems);

//ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);

fdb.DataBase.removeItem(ui->tableWidget->item(ui->tableWidget->selectionModel()->selectedIndexes()[0].row(), 0)->text().toInt());

ui->tableWidget->setRowCount(ui->tableWidget->rowCount()-1);

reDrawTable();

}

else

{

QMessageBox::warning(this, "warning", "Выберете слот для удаления!");

}

}

showItemAmountStatus();

isEdit = true;

}

void dbWindow::on_actionMerge_triggered()

{

QString filename = QFileDialog::getOpenFileName(this, tr("Open file"), "");

string utf8text = filename.toUtf8().constData();

QMessageBox::StandardButton reply = QMessageBox::question(this, "Delete", "Вы действительно хотите совместить базы данных?", QMessageBox::Yes|QMessageBox::No);

if (reply == QMessageBox::Yes)

{

fdb.merge(utf8text);

ldDbToTable();

}

showItemAmountStatus();

isEdit = true;

}

void dbWindow::on_actionFind_triggered()

{

fininddb *findWind;

findWind = new fininddb(this);

connect(findWind, &fininddb::okClicked, this, &dbWindow::findItemInWidgetTable);

findWind->setModal(false);

findWind->exec();

}

void dbWindow::showItemAmountStatus()

{

ui->lineEdit->setText("Количество элементов: " + QString::number(ui->tableWidget->rowCount()));

}

void dbWindow::on_actionHelp_triggered()

{

QMessageBox::about(0, "О программе", "Данная программа была разработана студентом группы ИКПИ-92 - Козловом Никитой\n "

"Для курсовой работы по объектно-ориентированному программированию" );

}

void dbWindow::on_actionEdit_item_triggered()

{

editdialog *edit;

edit = new editdialog(this);

connect(edit, &editdialog::sendEditToTable, this, &dbWindow::replaceTableItem);

edit->setModal(false);

edit->exec();

}

void dbWindow::replaceTableItem(int number, int age, string rate, string name, string team)

{

fdb.DataBase.replaceItem(number, FootbalPlayer(number, age, rate, name, team));

reDrawTable();

}

void dbWindow::on_actionExit_triggered()

{

dbWindow::close();

}

editdialog.h

#ifndef EDITDIALOG_H

#define EDITDIALOG_H

#include <QDialog>

#include <string>

#include "FDB.h"

namespace Ui {

class editdialog;

}

class editdialog : public QDialog

{

Q_OBJECT

public:

// Constructor

explicit editdialog(QWidget *parent = nullptr);

// Destructor

~editdialog();

private slots:

// Accept button click

void on_buttonBox_accepted();

// Takes arguments for lines from main form

void takeFromMainForm(int number, int age, string rate, string name, string team);

signals:

void sendEditToTable(int number, int age, string rate, string name, string team);

private:

// Ui objects

Ui::editdialog *ui;

};

#endif // EDITDIALOG_H

editdialog.ui

<?xml version="1.0" encoding="UTF-8"?>

<ui version="4.0">

<class>editdialog</class>

<widget class="QDialog" name="editdialog">

<property name="geometry">

<rect>

<x>0</x>

<y>0</y>

<width>364</width>

<height>266</height>

</rect>

</property>

<property name="sizePolicy">

<sizepolicy hsizetype="Fixed" vsizetype="Fixed">

<horstretch>0</horstretch>

<verstretch>0</verstretch>

</sizepolicy>

</property>

<property name="minimumSize">

<size>

<width>364</width>

<height>266</height>

</size>

</property>

<property name="maximumSize">

<size>

<width>364</width>

<height>266</height>

</size>

</property>

<property name="windowTitle">

<string>Dialog</string>

</property>

<widget class="QDialogButtonBox" name="buttonBox">

<property name="geometry">

<rect>

<x>10</x>

<y>220</y>

<width>341</width>

<height>32</height>

</rect>

</property>

<property name="orientation">

<enum>Qt::Horizontal</enum>

</property>

<property name="standardButtons">

<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>

</property>

<property name="centerButtons">

<bool>true</bool>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit">

<property name="geometry">

<rect>

<x>80</x>

<y>20</y>

<width>251</width>

<height>21</height>

</rect>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_2">

<property name="geometry">

<rect>

<x>80</x>

<y>60</y>

<width>251</width>

<height>21</height>

</rect>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_3">

<property name="geometry">

<rect>

<x>80</x>

<y>100</y>

<width>41</width>

<height>21</height>

</rect>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_4">

<property name="geometry">

<rect>

<x>140</x>

<y>100</y>

<width>41</width>

<height>21</height>

</rect>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_5">

<property name="geometry">

<rect>

<x>80</x>

<y>130</y>

<width>251</width>

<height>21</height>

</rect>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_6">

<property name="geometry">

<rect>

<x>80</x>

<y>170</y>

<width>251</width>

<height>21</height>

</rect>

</property>

</widget>

<widget class="QLabel" name="label">

<property name="geometry">

<rect>

<x>30</x>

<y>20</y>

<width>47</width>

<height>14</height>

</rect>

</property>

<property name="text">

<string>Номер</string>

</property>

</widget>

<widget class="QLabel" name="label_2">

<property name="geometry">

<rect>

<x>30</x>

<y>60</y>

<width>47</width>

<height>14</height>

</rect>

</property>

<property name="text">

<string>Возраст</string>

</property>

</widget>

<widget class="QLabel" name="label_3">

<property name="geometry">

<rect>

<x>30</x>

<y>100</y>

<width>47</width>

<height>14</height>

</rect>

</property>

<property name="text">

<string>Рейтинг</string>

</property>

</widget>

<widget class="QLabel" name="label_4">

<property name="geometry">

<rect>

<x>130</x>

<y>100</y>

<width>16</width>

<height>16</height>

</rect>

</property>

<property name="text">

<string>:</string>

</property>

</widget>

<widget class="QLabel" name="label_5">

<property name="geometry">

<rect>

<x>30</x>

<y>130</y>

<width>47</width>

<height>14</height>

</rect>

</property>

<property name="text">

<string>ФИО</string>

</property>

</widget>

<widget class="QLabel" name="label_6">

<property name="geometry">

<rect>

<x>30</x>

<y>170</y>

<width>47</width>

<height>14</height>

</rect>

</property>

<property name="text">

<string>Команда</string>

</property>

</widget>

</widget>

<resources/>

<connections>

<connection>

<sender>buttonBox</sender>

<signal>accepted()</signal>

<receiver>editdialog</receiver>

<slot>accept()</slot>

<hints>

<hint type="sourcelabel">

<x>248</x>

<y>254</y>

</hint>

<hint type="destinationlabel">

<x>157</x>

<y>274</y>

</hint>

</hints>

</connection>

<connection>

<sender>buttonBox</sender>

<signal>rejected()</signal>

<receiver>editdialog</receiver>

<slot>reject()</slot>

<hints>

<hint type="sourcelabel">

<x>316</x>

<y>260</y>

</hint>

<hint type="destinationlabel">

<x>286</x>

<y>274</y>

</hint>

</hints>

</connection>

</connections>

</ui>

editdialog.cpp

#include "editdialog.h"

#include "ui_editdialog.h"

editdialog::editdialog(QWidget *parent) :

QDialog(parent),

ui(new Ui::editdialog)

{

ui->setupUi(this);

}

editdialog::~editdialog()

{

delete ui;

}

void editdialog::on_buttonBox_accepted()

{

emit sendEditToTable(ui->lineEdit->text().toInt(), ui->lineEdit_2->text().toInt(),

ui->lineEdit_3->text().toStdString()+":"+ui->lineEdit_4->text().toStdString(),

ui->lineEdit_5->text().toStdString(), ui->lineEdit_6->text().toStdString());

}

void editdialog::takeFromMainForm(int number, int age, string rate, string name, string team)

{

ui->label->setText(QString::number(number));

ui->label_2->setText(QString::number(age));

ui->label_3->setText(0);

ui->label_4->setText(0);

ui->label_5->setText(QString::fromStdString(name));

ui->label_6->setText(QString::fromStdString(team));

}

finindb.h

#ifndef FININDDB_H

#define FININDDB_H

#include <QDialog>

namespace Ui {

class fininddb;

}

class fininddb : public QDialog

{

Q_OBJECT

signals:

// Ok button click signal

void okClicked(QString wantedLine);

public:

// Constructor

explicit fininddb(QWidget *parent = nullptr);

// Destructor

~fininddb();

private slots:

// Ok button event

void on_buttonBox_accepted();

private:

// Ui object

Ui::fininddb *ui;

};

#endif // FININDDB_H

finindb.ui

<?xml version="1.0" encoding="UTF-8"?>

<ui version="4.0">

<class>fininddb</class>

<widget class="QDialog" name="fininddb">

<property name="geometry">

<rect>

<x>0</x>

<y>0</y>

<width>324</width>

<height>137</height>

</rect>

</property>

<property name="minimumSize">

<size>

<width>324</width>

<height>137</height>

</size>

</property>

<property name="maximumSize">

<size>

<width>324</width>

<height>137</height>

</size>

</property>

<property name="windowTitle">

<string>Dialog</string>

</property>

<widget class="QDialogButtonBox" name="buttonBox">

<property name="geometry">

<rect>

<x>-30</x>

<y>60</y>

<width>341</width>

<height>32</height>

</rect>

</property>

<property name="orientation">

<enum>Qt::Horizontal</enum>

</property>

<property name="standardButtons">

<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit">

<property name="geometry">

<rect>

<x>60</x>

<y>20</y>

<width>251</width>

<height>21</height>

</rect>

</property>

</widget>

<widget class="QLabel" name="label">

<property name="geometry">

<rect>

<x>10</x>

<y>20</y>

<width>47</width>

<height>14</height>

</rect>

</property>

<property name="text">

<string>Найти:</string>

</property>

</widget>

</widget>

<resources/>

<connections>

<connection>

<sender>buttonBox</sender>

<signal>accepted()</signal>

<receiver>fininddb</receiver>

<slot>accept()</slot>

<hints>

<hint type="sourcelabel">

<x>248</x>

<y>254</y>

</hint>

<hint type="destinationlabel">

<x>157</x>

<y>274</y>

</hint>

</hints>

</connection>

<connection>

<sender>buttonBox</sender>

<signal>rejected()</signal>

<receiver>fininddb</receiver>

<slot>reject()</slot>

<hints>

<hint type="sourcelabel">

<x>316</x>

<y>260</y>

</hint>

<hint type="destinationlabel">

<x>286</x>

<y>274</y>

</hint>

</hints>

</connection>

</connections>

</ui>

finindb.cpp

#include "fininddb.h"

#include "ui_fininddb.h"

fininddb::fininddb(QWidget *parent) :

QDialog(parent),

ui(new Ui::fininddb)

{

ui->setupUi(this);

}

fininddb::~fininddb()

{

delete ui;

}

void fininddb::on_buttonBox_accepted()

{

emit okClicked(ui->lineEdit->text());

}

newitemdialog.h

#ifndef NEWITEMDIALOG_H

#define NEWITEMDIALOG_H

#include <QDialog>

#include "dbwindow.h"

namespace Ui {

class newItemDialog;

}

class newItemDialog : public QDialog

{

Q_OBJECT

public:

explicit newItemDialog(QWidget *parent = nullptr);

~newItemDialog();

signals:

void acceptClicked(int number, int age, string rating, string name, string team);

private slots:

void on_buttonBox_accepted();

private:

Ui::newItemDialog *ui;

int number;

int age;

string rating;

string name;

string team;

};

#endif // NEWITEMDIALOG_H

newitemdialog.ui

<?xml version="1.0" encoding="UTF-8"?>

<ui version="4.0">

<class>newItemDialog</class>

<widget class="QDialog" name="newItemDialog">

<property name="geometry">

<rect>

<x>0</x>

<y>0</y>

<width>364</width>

<height>266</height>

</rect>

</property>

<property name="sizePolicy">

<sizepolicy hsizetype="Minimum" vsizetype="Fixed">

<horstretch>0</horstretch>

<verstretch>0</verstretch>

</sizepolicy>

</property>

<property name="minimumSize">

<size>

<width>364</width>

<height>266</height>

</size>

</property>

<property name="maximumSize">

<size>

<width>364</width>

<height>266</height>

</size>

</property>

<property name="windowTitle">

<string>Add item</string>

</property>

<widget class="QDialogButtonBox" name="buttonBox">

<property name="geometry">

<rect>

<x>10</x>

<y>220</y>

<width>341</width>

<height>32</height>

</rect>

</property>

<property name="orientation">

<enum>Qt::Horizontal</enum>

</property>

<property name="standardButtons">

<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>

</property>

<property name="centerButtons">

<bool>true</bool>

</property>

</widget>

<widget class="QLabel" name="label">

<property name="geometry">

<rect>

<x>30</x>

<y>20</y>

<width>41</width>

<height>16</height>

</rect>

</property>

<property name="text">

<string>Номер </string>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit">

<property name="geometry">

<rect>

<x>80</x>

<y>20</y>

<width>251</width>

<height>21</height>

</rect>

</property>

<property name="text">

<string>0</string>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_2">

<property name="geometry">

<rect>

<x>80</x>

<y>60</y>

<width>251</width>

<height>21</height>

</rect>

</property>

<property name="text">

<string>0</string>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_3">

<property name="geometry">

<rect>

<x>80</x>

<y>100</y>

<width>41</width>

<height>21</height>

</rect>

</property>

<property name="text">

<string>Win</string>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_4">

<property name="geometry">

<rect>

<x>130</x>

<y>100</y>

<width>41</width>

<height>21</height>

</rect>

</property>

<property name="text">

<string>Losses</string>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_5">

<property name="geometry">

<rect>

<x>80</x>

<y>140</y>

<width>251</width>

<height>21</height>

</rect>

</property>

<property name="text">

<string>Ivanov Ivan Ivanovich</string>

</property>

</widget>

<widget class="QLineEdit" name="lineEdit_6">

<property name="geometry">

<rect>

<x>80</x>

<y>180</y>

<width>251</width>

<height>21</height>

</rect>

</property>

<property name="text">

<string>Zenit</string>

</property>

</widget>

<widget class="QLabel" name="label_2">

<property name="geometry">

<rect>

<x>30</x>

<y>60</y>

<width>41</width>

<height>16</height>

</rect>

</property>

<property name="text">

<string>Возраст</string>

</property>

</widget>

<widget class="QLabel" name="label_3">

<property name="geometry">

<rect>

<x>30</x>

<y>100</y>

<width>41</width>

<height>16</height>

</rect>

</property>

<property name="text">

<string>Рейтинг</string>

</property>

</widget>

<widget class="QLabel" name="label_4">

<property name="geometry">

<rect>

<x>30</x>

<y>140</y>

<width>47</width>

<height>14</height>

</rect>

</property>

<property name="text">

<string>ФИО</string>

</property>

</widget>

<widget class="QLabel" name="label_5">

<property name="geometry">

<rect>

<x>30</x>

<y>180</y>

<width>47</width>

<height>14</height>

</rect>

</property>

<property name="text">

<string>Команда</string>

</property>

</widget>

</widget>

<resources/>

<connections>

<connection>

<sender>buttonBox</sender>

<signal>accepted()</signal>

<receiver>newItemDialog</receiver>

<slot>accept()</slot>

<hints>

<hint type="sourcelabel">

<x>248</x>

<y>254</y>

</hint>

<hint type="destinationlabel">

<x>157</x>

<y>274</y>

</hint>

</hints>

</connection>

<connection>

<sender>buttonBox</sender>

<signal>rejected()</signal>

<receiver>newItemDialog</receiver>

<slot>reject()</slot>

<hints>

<hint type="sourcelabel">

<x>316</x>

<y>260</y>

</hint>

<hint type="destinationlabel">

<x>286</x>

<y>274</y>

</hint>

</hints>

</connection>

</connections>

</ui>

newitemdialog.cpp

#include "newitemdialog.h"

#include "ui_newitemdialog.h"

#include <QDebug>

newItemDialog::newItemDialog(QWidget *parent) :

QDialog(parent),

ui(new Ui::newItemDialog)

{

ui->setupUi(this);

}

newItemDialog::~newItemDialog()

{

delete ui;

}

void newItemDialog::on_buttonBox_accepted()

{

number = ui->lineEdit->text().toInt();

age = ui->lineEdit_2->text().toInt();

rating = ui->lineEdit_3->text().toStdString() + ":" + ui->lineEdit_4->text().toStdString();

name = ui->lineEdit_5->text().toStdString();

team = ui->lineEdit_6->text().toStdString();

emit acceptClicked(number, age, rating, name, team);

}

FDB.h

/*

***FDB FORMAT CLASS DESIGNED FOR OOP COURSEWORK

***TOPIC: GUI APPLICATION

***IKPI-92 GROUP STUDENT - KOZLOV NIKITA

*/

#pragma once

#include "HashTable.h"

#include <string>

#include <QMessageBox>

#include "QMessageBox"

/// <summary>

/// FDB fromat class

/// </summary>

class FDB : public HashTable

{

private:

/// <summary>

/// file to read

/// </summary>

string dbfile;

/// <summary>

/// copy here single line from file

/// </summary>

string line;

/// <returns>true if file rely database</returns>

bool isdatabase = false;

/// <summary>

/// parse string from file

/// </summary>

/// <param name="line">- single string from fle</param>

void dbparser(string line);

string encrypt(string line);

string decrypt(string line);

public:

/// <summary>

/// Database container based on hash table

/// </summary>

HashTable DataBase;

/// <summary>

/// Read file and sets values to table

/// </summary>

/// <param name="path">- file path</param>

void open_n_place(string path);

/// <summary>

/// Read and decrypt file and set to table

/// </summary>

/// <param name="path">- file path</param>

void dopen_n_place(string path);

/// <summary>

/// Write database information to .fdb file

/// </summary>

/// <param name="HT">- hashtable based database</param>

/// <param name="path">- path for file to save</param>

void writeToDB(string path);

/// <summary>

/// Merge two databases

/// </summary>

/// <param name="path">- path to database you need merge with</param>

void merge(string path);

/// <summary>

/// Write database information to .fdb file and encrypt it

/// </summary>

/// <param name="HT">- hashtable based database</param>

void ewriteToDB(HashTable HT);

//TODO: encrypter&decrypter

};

FDB.cpp

#include <fstream>

#include <sstream>

#include <string>

#include "FDB.h"

void FDB::dbparser(string line)

{

stringstream from_line(line);

string str_segment;

vector<string> seglist;

if (!line.find("\t<dbinfo"))

{

while (getline(from_line, str_segment, '"')) // split string by '"' character

{

seglist.push_back(str_segment); // sets all splited sigments to array

}

}

if (!line.find("\t<player"))

{

while (getline(from_line, str_segment, '"'))

{

seglist.push_back(str_segment);

}

//indexes.push_back(atoi(seglist[1].c_str()));

DataBase.insertItem(atoi(seglist[1].c_str()), FootbalPlayer(atoi(seglist[1].c_str()),

atoi(seglist[3].c_str()),

seglist[5],

seglist[7],

seglist[9]

));

seglist.clear();

}

}

string FDB::encrypt(string line)

{

char symbol;

string encrypted_line;

for (size_t i{}; i < line.size(); i++)

{

symbol = (line.c_str()[i]) + 4 * sin(36);

encrypted_line.push_back(symbol);

}

return encrypted_line;

}

string FDB::decrypt(string line)

{

char symbol;

string decrypted_line;

for (size_t i{}; i < line.size(); i++)

{

symbol = (line.c_str()[i]) - 4 / sin(36);

decrypted_line.push_back(symbol);

}

return decrypted_line;

}

void FDB::open_n_place(string path)

{

dbfile = path;

ifstream dbfile(dbfile);

try

{

if (dbfile.is_open())

{

getline(dbfile, line);

if (line == "<database>")

{

isdatabase = true;

}

else

{

throw exception("file is not a database");

}

if (isdatabase == true)

{

do

{

getline(dbfile, line);

if (line == "</database>") { cout << endl; break; };

cout << line << endl;

dbparser(line);

} while (line != "</database>");

}

}

else

throw exception("file does not exist or corrupted");

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

}

}

void FDB::dopen_n_place(string path)

{

dbfile = path;

ifstream dbfile(dbfile);

stringstream ssline(line);

string segment;

vector<string> elem;

try

{

if (dbfile.is_open())

{

getline(dbfile, line);

if (!decrypt(line).find("<database>"))

{

isdatabase = true;

}

else

{

throw exception("file is not a database");

}

if (isdatabase == true)

{

getline(dbfile, line);

ssline << decrypt(line);

while (getline(ssline, segment, '\n'))

{

elem.push_back(segment);

}

for (size_t i{}; i < elem.size(); i++)

dbparser(elem[i]);

}

}

else

throw exception("file does not exist or corrupted");

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

}

}

void FDB::writeToDB(string path)

{

ofstream dbfile;

dbfile.open(path);

dbfile << "<database>\n";

dbfile << "\t<dbinfo amount=\"" << DataBase.index_amount() << "\" />\n";

for (size_t i{}; i < DataBase.index_amount(); i++)

{

dbfile << "\t<player number=\"" << DataBase.getPlayerNumber(DataBase.get_index(i)) << "\" age=\""

<< DataBase.getPlayerAge(DataBase.get_index(i)) << "\" rating=\""

<< DataBase.getPlayerRating(DataBase.get_index(i)) << "\" fullname=\""

<< DataBase.getPlayerName(DataBase.get_index(i)) << "\" team=\""

<< DataBase.getPlayerTeam(DataBase.get_index(i)) << "\" />\n";

}

dbfile << "</database>";

dbfile.close();

}

void FDB::ewriteToDB(HashTable HT)

{

ofstream dbfile;

dbfile.open("footballbase.fdb");

dbfile << encrypt("<database>\n");

dbfile << encrypt("\t<dbinfo amount=\""+ to_string(DataBase.index_amount()) + "\" />\n");

for (size_t i{}; i < DataBase.index_amount(); i++)

{

dbfile << encrypt("\t<player number=\"" + to_string(DataBase.getPlayerNumber(DataBase.get_index(i))) + "\" age=\""

+ to_string(DataBase.getPlayerAge(DataBase.get_index(i))) + "\" rating=\""

+ DataBase.getPlayerRating(DataBase.get_index(i)) + "\" fullname=\""

+ DataBase.getPlayerName(DataBase.get_index(i)) + "\" team=\""

+ DataBase.getPlayerTeam(DataBase.get_index(i)) + "\" />\n");

}

dbfile <<encrypt("</database>");

dbfile.close();

}

void FDB::merge(string path)

{

ifstream dbfile(path);

try

{

if (dbfile.is_open())

{

getline(dbfile, line);

if (line == "<database>")

{

isdatabase = true;

}

else

{

throw exception("file is not a database");

}

if (isdatabase == true)

{

do

{

getline(dbfile, line);

if (line == "</database>") { cout << endl; break; };

cout << line << endl;

stringstream from_line(line);

string str_segment;

vector<string> seglist;

if (!line.find("\t<dbinfo"))

{

while (getline(from_line, str_segment, '"')) // split string by '"' character

{

seglist.push_back(str_segment); // sets all splited sigments to array

}

}

if (!line.find("\t<player"))

{

while (getline(from_line, str_segment, '"'))

{

seglist.push_back(str_segment);

}

if (!isKeyExist(atoi(seglist[1].c_str())))

{

DataBase.insertItem(atoi(seglist[1].c_str()), FootbalPlayer(atoi(seglist[1].c_str()),

atoi(seglist[3].c_str()),

seglist[5],

seglist[7],

seglist[9]

));

seglist.clear();

}

else

{

throw exception("this key already exist");

}

}

} while (line != "</database>");

}

}

else

throw exception("file does not exist or corrupted");

}

catch (const std::exception& ex)

{

cout << "[ERROR]: " << ex.what() << endl;

}

}

FootbalPlayer.h

/*

***FOOTBALL PLAYER CLASS DESIGNED FOR OOP COURSEWORK

***TOPIC: GUI APPLICATION

***IKPI-92 GROUP STUDENT - KOZLOV NIKITA

*/

#pragma once

#ifdef FOOTBALL_PLAYER_H

#define FOOTBAL_PLAYER_H

#endif // FOOTBALL_PLAYER_H

#include <iostream>

using namespace std;

/// <summary>

/// General footbal player class

/// </summary>

class FootbalPlayer

{

private:

// Player number

size_t number;

// Player age

size_t age;

// Player rating (wins:looses)

//const char* rate;

string rate;

// Player fullname

string fullname;

// Team which player plays for

string team;

protected:

public:

/// <summary>

/// Footbal player constructor with a given values

/// </summary>

/// <param name="_number">- player number</param>

/// <param name="_age">- player age</param>

/// <param name="_rate">- player rating (wins:looses)</param>

/// <param name="_fullname">- player fullname</param>

/// <param name="_team">- team which player plays for</param>

FootbalPlayer(size_t _number, size_t _age, string _rate, string _fullname, string _team);

~FootbalPlayer() { };

/// <summary>

/// Sets player number

/// </summary>

/// <param name="_number">- player number</param>

void setPlayerNumber(size_t _number);

/// <summary>

/// Sets player age

/// </summary>

/// <param name="_age">- player age</param>

void setPlayerAge(size_t _age);

/// <summary>

/// Sets player fullname

/// </summary>

/// <param name="_name">- player fullname</param>

void setPlayerName(string _name);

/// <summary>

/// Sets player team

/// </summary>

/// <param name="_team">- team which player plays for</param>

void setPlayerTeam(string _team);

/// <summary>

/// Sets player rating

/// </summary>

/// <param name="_rate">- player rating (wins:looses)</param>

void setPlayerRate(string _rate);

/// <returns>player number</returns>

size_t getPlayerNumber();

/// <returns>player age</returns>

size_t getPlayerAge();

/// <returns>player name</returns>

string getPlayerName();

/// <returns>player team</returns>

string getPlayerTeam();

/// <returns>player rating (wins:looses)</returns>

string getPlayerRate();

/// <summary>

/// Ostream operator overloading to use cout function

/// </summary>

friend ostream& operator << (ostream& os, const FootbalPlayer& player)

{

os << "[ " << player.number << ", " << player.age << ", "

<< player.rate << ", " << player.fullname << ", " << player.team << " ]\n";

return os;

}

};

FootbalPlayer.cpp

#include "FootbalPlayer.h"

FootbalPlayer::FootbalPlayer(size_t _number, size_t _age, string _rate, string _fullname, string _team)

{

setPlayerNumber(_number);

setPlayerAge(_age);

setPlayerRate(_rate);

setPlayerName(_fullname);

setPlayerTeam(_team);

}

void FootbalPlayer::setPlayerNumber(size_t _number)

{

this->number = _number;

}

void FootbalPlayer::setPlayerAge(size_t _age)

{

this->age = _age;

}

void FootbalPlayer::setPlayerName(string _name)

{

this->fullname = _name;

}

void FootbalPlayer::setPlayerTeam(string _team)

{

this->team = _team;

}

void FootbalPlayer::setPlayerRate(string _rate)

{

this->rate = _rate;

}

size_t FootbalPlayer::getPlayerNumber()

{

return this->number;

}

size_t FootbalPlayer::getPlayerAge()

{

return this->age;

}

string FootbalPlayer::getPlayerName()

{

return this->fullname;

}

string FootbalPlayer::getPlayerTeam()

{

return this->team;

}

string FootbalPlayer::getPlayerRate()

{

return this->rate;

}

HashTable.h

/*

***HASH TABLE CLASS DESIGNED FOR OOP COURSEWORK

***TOPIC: GUI APPLICATION

***IKPI-92 GROUP STUDENT - KOZLOV NIKITA

*/

#pragma once

#include "FootbalPlayer.h"

#include <list>

#include <vector>

/// <summary>

/// Hash table class for data base

/// </summary>

class HashTable

{

private:

/// <summary>

/// hash table hash groups

/// </summary>

static const int hashGroups = 10;

list<pair<int, FootbalPlayer>> table[hashGroups];

protected:

/// <summary>

/// Simple hash function

/// </summary>

int hashFunction(int key);

/// <summary>

/// Index of all indexes

/// </summary>

vector<size_t> indexes;

public:

HashTable() {};

~HashTable() {};

/// <param name="key">- database key</param>

/// <returns>Player number from key place</returns>

size_t getPlayerNumber(size_t key);

/// <param name="key">- database key</param>

/// <returns>Player age from key place</returns>

size_t getPlayerAge(size_t key);

/// <param name="key">- database key</param>

/// <returns>Player rating from key place</returns>

string getPlayerRating(size_t key);

/// <param name="key">- database key</param>

/// <returns>Player name from key place</returns>

string getPlayerName(size_t key);

/// <param name="key">- database key</param>

/// <returns>Player team from key place</returns>

string getPlayerTeam(size_t key);

/// <summary>

/// all table indexes

/// </summary>

/// <returns>index amount</returns>

size_t index_amount();

/// <summary>

/// Gets particular index

/// </summary>

/// <param name="number">array index</param>

/// <returns>index from array[number]</returns>

size_t get_index(size_t number);

/// <returns>true if hash table is empty</returns>

bool isEmpty();

/// <param name="key">- item key</param>

/// <returns>true if key exist in table</returns>

bool isKeyExist(int key);

/// <summary>

/// Insert item into table and give it a key

/// </summary>

/// <param name="key">- value adress key</param>

/// <param name="value">- footbal player</param>

void insertItem(int key, FootbalPlayer value);

/// <summary>

/// Remove item from table

/// </summary>

/// <param name="key">- value adress</param>

void removeItem(int key);

/// <summary>

/// Prints all the table to the console

/// </summary>

void printTable();

/// <summary>

/// Clear table items

/// </summary>

void clear();

/// <summary>

/// Replace table item

/// </summary>

/// <param name="key">- item adress</param>

/// <param name="value">- item to replace</param>

void replaceItem(int key, FootbalPlayer value);

};

HashTable.cpp

#include "HashTable.h"

bool HashTable::isEmpty()

{

int sum{};

for (size_t i{}; i < hashGroups; i++)

sum += table[i].size();

if (!sum)

return true;

else

return false;

}

bool HashTable::isKeyExist(int key)

{

int hashValue = hashFunction(key);

auto& cell = table[hashValue];

auto bItr = begin(cell);

for (; bItr != end(cell); bItr++)

{

if (bItr->first == key)

{

return true;

break;

}

}

return false;

}

int HashTable::hashFunction(int key)

{

return key % hashGroups;

}

size_t HashTable::getPlayerNumber(size_t key)

{

int hashValue = hashFunction(key);

auto& cell = table[hashValue];

auto bItr = begin(cell);

for (; bItr != end(cell); bItr++)

{

if (bItr->first == key)

{

return bItr->second.getPlayerNumber();

break;

}

}

}

size_t HashTable::getPlayerAge(size_t key)

{

int hashValue = hashFunction(key);

auto& cell = table[hashValue];

auto bItr = begin(cell);

for (; bItr != end(cell); bItr++)

{

if (bItr->first == key)

{

return bItr->second.getPlayerAge();

break;

}

}

}

string HashTable::getPlayerRating(size_t key)

{

int hashValue = hashFunction(key);

auto& cell = table[hashValue];

auto bItr = begin(cell);

for (; bItr != end(cell); bItr++)

{

if (bItr->first == key)

{

return bItr->second.getPlayerRate();

break;

}

}

}

string HashTable::getPlayerName(size_t key)

{

int hashValue = hashFunction(key);

auto& cell = table[hashValue];

auto bItr = begin(cell);

for (; bItr != end(cell); bItr++)

{

if (bItr->first == key)

{

return bItr->second.getPlayerName();

break;

}

}

}

string HashTable::getPlayerTeam(size_t key)

{

int hashValue = hashFunction(key);

auto& cell = table[hashValue];

auto bItr = begin(cell);

for (; bItr != end(cell); bItr++)

{

if (bItr->first == key)

{

return bItr->second.getPlayerTeam();

break;

}

}

}

size_t HashTable::index_amount()

{

return indexes.size();

}

size_t HashTable::get_index(size_t number)

{

return indexes[number];

}

void HashTable::insertItem(int key, FootbalPlayer value)

{

int hashValue = hashFunction(key);

auto& cell = table[hashValue];

auto bItr = begin(cell);

bool keyExists = false;

for (; bItr != end(cell); bItr++)

{

if (bItr->first == key)

{

keyExists = true;

bItr->second = value;

cout << "[WARNING]: key exist, but value replaced\n";

break;

}

}

if (!keyExists)

{

cell.emplace_back(key, value);

indexes.push_back(key);

}

}

void HashTable::removeItem(int key)

{

int hashValue = hashFunction(key);

auto& cell = table[hashValue];

auto bItr = begin(cell);

bool keyExist = false;

for (; bItr != end(cell); bItr++)

{

if (bItr->first == key)

{

keyExist = true;

bItr = cell.erase(bItr);

cout << "[INFO]: item has been removed\n";

for (size_t i{}; i < index_amount(); i++)

{

if (key == indexes[i])

indexes.erase(indexes.begin() + i);

}

break;

}

}

if (!keyExist)

cout << "[WARNING]: key not found\n";

}

void HashTable::printTable()

{

for (int i{}; i < hashGroups; i++)

{

if (table[i].size() == 0) continue;

auto bItr = table[i].begin();

for (; bItr != table[i].end(); bItr++)

{

cout << "Key: " << bItr->first << " Player: " << bItr->second << endl;

}

}

}

void HashTable::clear()

{

for (uint16_t i{}; i < index_amount(); i++)

{

removeItem(get_index(i));

}

indexes.clear();

}

void HashTable::replaceItem(int key, FootbalPlayer value)

{

removeItem(key);

insertItem(key, value);

}

main.cpp

#include "dbwindow.h"

#include <QApplication>

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

dbWindow w;

w.show();

return a.exec();

return 0;

}

Структура файлов для базы данных example.dfb

<database>

<dbinfo amount="4" />

<player number="1" age="25" rating="5:3" fullname="Иванов Иван Сергеевич" team="Зенит" />

<player number="2" age="24" rating="4:2" fullname="Беликов Евгений Евгеньевич" team="Зенит" />

<player number="3" age="27" rating="5:3" fullname="Колесников Артур Александрович" team="ЦСКА" />

<player number="5" age="31" rating="3:1" fullname="Кириллов Даниил Александрович" team="ЦСКА" />

</database>