From c34930425fadfc4083067b9306159cd8e8ecf6c6 Mon Sep 17 00:00:00 2001 From: Louie S Date: Tue, 23 Jul 2024 20:37:48 -0400 Subject: Rearrange source file locations --- src/frontend/qtwidgets/addEntryForm.cpp | 49 ++++++ src/frontend/qtwidgets/addEntryForm.h | 24 +++ src/frontend/qtwidgets/addGroupForm.cpp | 34 +++++ src/frontend/qtwidgets/addGroupForm.h | 21 +++ src/frontend/qtwidgets/assignmentList.cpp | 169 +++++++++++++++++++++ src/frontend/qtwidgets/assignmentList.h | 43 ++++++ src/frontend/qtwidgets/assignmentList.ui | 213 +++++++++++++++++++++++++++ src/frontend/qtwidgets/editEntryForm.cpp | 55 +++++++ src/frontend/qtwidgets/editEntryForm.h | 25 ++++ src/frontend/qtwidgets/editGroupForm.cpp | 40 +++++ src/frontend/qtwidgets/editGroupForm.h | 25 ++++ src/frontend/qtwidgets/entry.cpp | 36 +++++ src/frontend/qtwidgets/entry.h | 39 +++++ src/frontend/qtwidgets/entryForm.ui | 185 +++++++++++++++++++++++ src/frontend/qtwidgets/entryLayout.cpp | 177 ++++++++++++++++++++++ src/frontend/qtwidgets/entryLayout.h | 32 ++++ src/frontend/qtwidgets/group.cpp | 14 ++ src/frontend/qtwidgets/group.h | 25 ++++ src/frontend/qtwidgets/groupForm.ui | 131 ++++++++++++++++ src/frontend/qtwidgets/groupLayout.cpp | 68 +++++++++ src/frontend/qtwidgets/groupLayout.h | 23 +++ src/frontend/qtwidgets/lib.cpp | 22 +++ src/frontend/qtwidgets/lib.h | 12 ++ src/frontend/qtwidgets/main.cpp | 12 ++ src/frontend/qtwidgets/preferencesDialog.cpp | 59 ++++++++ src/frontend/qtwidgets/preferencesDialog.h | 28 ++++ src/frontend/qtwidgets/preferencesDialog.ui | 128 ++++++++++++++++ src/frontend/qtwidgets/rule.cpp | 15 ++ src/frontend/qtwidgets/rule.h | 28 ++++ src/frontend/qtwidgets/ruleLayout.cpp | 40 +++++ src/frontend/qtwidgets/ruleLayout.h | 27 ++++ src/frontend/qtwidgets/rulesDialog.cpp | 107 ++++++++++++++ src/frontend/qtwidgets/rulesDialog.h | 32 ++++ src/frontend/qtwidgets/rulesDialog.ui | 123 ++++++++++++++++ 34 files changed, 2061 insertions(+) create mode 100644 src/frontend/qtwidgets/addEntryForm.cpp create mode 100644 src/frontend/qtwidgets/addEntryForm.h create mode 100644 src/frontend/qtwidgets/addGroupForm.cpp create mode 100644 src/frontend/qtwidgets/addGroupForm.h create mode 100644 src/frontend/qtwidgets/assignmentList.cpp create mode 100644 src/frontend/qtwidgets/assignmentList.h create mode 100644 src/frontend/qtwidgets/assignmentList.ui create mode 100644 src/frontend/qtwidgets/editEntryForm.cpp create mode 100644 src/frontend/qtwidgets/editEntryForm.h create mode 100644 src/frontend/qtwidgets/editGroupForm.cpp create mode 100644 src/frontend/qtwidgets/editGroupForm.h create mode 100644 src/frontend/qtwidgets/entry.cpp create mode 100644 src/frontend/qtwidgets/entry.h create mode 100644 src/frontend/qtwidgets/entryForm.ui create mode 100644 src/frontend/qtwidgets/entryLayout.cpp create mode 100644 src/frontend/qtwidgets/entryLayout.h create mode 100644 src/frontend/qtwidgets/group.cpp create mode 100644 src/frontend/qtwidgets/group.h create mode 100644 src/frontend/qtwidgets/groupForm.ui create mode 100644 src/frontend/qtwidgets/groupLayout.cpp create mode 100644 src/frontend/qtwidgets/groupLayout.h create mode 100644 src/frontend/qtwidgets/lib.cpp create mode 100644 src/frontend/qtwidgets/lib.h create mode 100644 src/frontend/qtwidgets/main.cpp create mode 100644 src/frontend/qtwidgets/preferencesDialog.cpp create mode 100644 src/frontend/qtwidgets/preferencesDialog.h create mode 100644 src/frontend/qtwidgets/preferencesDialog.ui create mode 100644 src/frontend/qtwidgets/rule.cpp create mode 100644 src/frontend/qtwidgets/rule.h create mode 100644 src/frontend/qtwidgets/ruleLayout.cpp create mode 100644 src/frontend/qtwidgets/ruleLayout.h create mode 100644 src/frontend/qtwidgets/rulesDialog.cpp create mode 100644 src/frontend/qtwidgets/rulesDialog.h create mode 100644 src/frontend/qtwidgets/rulesDialog.ui (limited to 'src/frontend/qtwidgets') diff --git a/src/frontend/qtwidgets/addEntryForm.cpp b/src/frontend/qtwidgets/addEntryForm.cpp new file mode 100644 index 0000000..7402167 --- /dev/null +++ b/src/frontend/qtwidgets/addEntryForm.cpp @@ -0,0 +1,49 @@ +#include +#include +#include + +#include "addEntryForm.h" +#include "../../backend/db_sqlite.h" + +AddEntryForm::AddEntryForm(const Group &g) : + parent_group(g) +{ + // load uic + ui.setupUi(this); + + // set titles + this->setWindowTitle("Add Entry"); + ui.title->setText("Add Entry"); + + // widgets setup + ui.entry_due->setDate(QDate::currentDate()); +} + +void AddEntryForm::accept() { + QString desc_text = ui.entry_desc->text(); + QDateTime due_text = ui.entry_due->date().startOfDay(); + QString due_alt_text = ui.entry_due_alt->text(); + QString link_text = ui.entry_link->text(); + QString color_text = ui.entry_color->text(); + QString highlight_text = ui.entry_highlight->text(); + QMessageBox error_message; + BackendDB database; + int new_id; + + // Check that the new entry is not blank + if(desc_text.isEmpty()) { + error_message.setIcon(QMessageBox::Warning); + error_message.setWindowTitle("Error Message"); + error_message.setText("Description cannot be blank"); + error_message.exec(); + return; + } + + // replace due_text with null date if due_checkbox is unchecked + if(!ui.entry_due_checkbox->isChecked()) + due_text = QDateTime(); + + new_id = database.insertEntry(Entry(0, this->parent_group.id, desc_text, due_text, due_alt_text, link_text, color_text, highlight_text)); + + QDialog::accept(); +} diff --git a/src/frontend/qtwidgets/addEntryForm.h b/src/frontend/qtwidgets/addEntryForm.h new file mode 100644 index 0000000..81535f1 --- /dev/null +++ b/src/frontend/qtwidgets/addEntryForm.h @@ -0,0 +1,24 @@ +#ifndef ADDENTRYFORM_H +#define ADDENTRYFORM_H + +#include + +#include "group.h" +#include "ui_entryForm.h" + +class AddEntryForm : public QDialog { + Q_OBJECT + + public: + AddEntryForm(const Group &g); + + private: + Ui::entryDialog ui; + + Group parent_group; + + private slots: + void accept(); +}; + +#endif diff --git a/src/frontend/qtwidgets/addGroupForm.cpp b/src/frontend/qtwidgets/addGroupForm.cpp new file mode 100644 index 0000000..c7d5faa --- /dev/null +++ b/src/frontend/qtwidgets/addGroupForm.cpp @@ -0,0 +1,34 @@ +#include + +#include "addGroupForm.h" +#include "../../backend/db_sqlite.h" + +AddGroupForm::AddGroupForm() { + // load uic + ui.setupUi(this); + + // set titles + this->setWindowTitle("Add Group"); + ui.title->setText("Add Group"); +} + +void AddGroupForm::accept() { + QString name_text = ui.group_name->text(); + Group::Column column_value = Group::Column(ui.group_column->currentIndex()); + QString link_text = ui.group_link->text(); + QMessageBox error_message; + BackendDB database; + int new_id; + + if(name_text.isEmpty()) { + error_message.setIcon(QMessageBox::Warning); + error_message.setWindowTitle("Error Message"); + error_message.setText("Name cannot be blank"); + error_message.exec(); + return; + } + + new_id = database.insertGroup(Group(0, name_text, column_value, link_text)); + + QDialog::accept(); +} diff --git a/src/frontend/qtwidgets/addGroupForm.h b/src/frontend/qtwidgets/addGroupForm.h new file mode 100644 index 0000000..b181408 --- /dev/null +++ b/src/frontend/qtwidgets/addGroupForm.h @@ -0,0 +1,21 @@ +#ifndef ADDGROUPFORM_H +#define ADDGROUPFORM_H + +#include + +#include "ui_groupForm.h" + +class AddGroupForm : public QDialog { + Q_OBJECT + + public: + AddGroupForm(); + + private: + Ui::groupDialog ui; + + private slots: + void accept(); +}; + +#endif diff --git a/src/frontend/qtwidgets/assignmentList.cpp b/src/frontend/qtwidgets/assignmentList.cpp new file mode 100644 index 0000000..dc89544 --- /dev/null +++ b/src/frontend/qtwidgets/assignmentList.cpp @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "../../../config.h" +#include "addGroupForm.h" +#include "assignmentList.h" +#include "../../backend/db_sqlite.h" +#include "entryLayout.h" +#include "groupLayout.h" +#include "lib.h" +#include "preferencesDialog.h" + +AssignmentList::AssignmentList() { + // set QSettings information + QCoreApplication::setOrganizationName(ORGANIZATION_NAME); + QCoreApplication::setApplicationName(PROJECT_NAME); + + // ensure QSettings location exists + this->initializeSettings(); + + // load everything from database into static global variables + this->initializeGlobals(); + + // load uic + ui.setupUi(this); + this->initializeUI(); +} + +void AssignmentList::initializeSettings() { + QSettings settings; + QDir local_data_dir(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation)); + + settings.beginGroup("paths"); + if(!settings.contains("db_path")) { + qDebug() << "Setting default db_path"; + settings.setValue("db_path", local_data_dir.filePath("data.db")); + } + settings.endGroup(); +} + +// load from database into static QList variables +void AssignmentList::initializeGlobals() { + BackendDB database; + + Group::groups = database.loadGroups(); + Entry::entries = database.loadEntries(); + Rule::rules = database.loadRules(); +} + +void AssignmentList::initializeUI() { + // create menu connections + QObject::connect(ui.actionPreferences, &QAction::triggered, this, &AssignmentList::preferences); + QObject::connect(ui.actionReload, &QAction::triggered, this, &AssignmentList::reload); + QObject::connect(ui.actionExit, &QAction::triggered, this, QApplication::quit); + QObject::connect(ui.actionAdd_Group, &QAction::triggered, this, &AssignmentList::addGroup); + QObject::connect(ui.actionClean_Hidden, &QAction::triggered, this, &AssignmentList::cleanHidden); + QObject::connect(ui.actionAbout, &QAction::triggered, this, &AssignmentList::aboutDialog); + + // create toolbar + ui.toolBar->addAction(ui.actionAdd_Group); + + this->displayDate(); + this->show(); + this->displayWidgets(); +} + +void AssignmentList::displayDate() { + QDate today = QDate::currentDate(); + ui.title->setText(today.toString("dddd, MMM d yyyy")); +} + +void AssignmentList::displayWidgets() { + QVBoxLayout *column_left = new QVBoxLayout(); + QVBoxLayout *column_right = new QVBoxLayout(); + BackendDB database; + GroupLayout *new_group_layout; + int i; + + // clear out old layouts if they exist + recursiveClear(ui.groups_layout); + + for(i = 0; i < Group::groups.size(); ++i) { + if(Group::groups[i].hidden) continue; + new_group_layout = new GroupLayout(Group::groups[i]); + new_group_layout->addLayout(this->drawEntries(Group::groups[i].id)); // add entries to layout + if(Group::groups[i].column == Group::left) column_left->addLayout(new_group_layout); + else column_right->addLayout(new_group_layout); + } + + column_left->addStretch(); + column_right->addStretch(); + + ui.groups_layout->addLayout(column_left, 0, 0); + ui.groups_layout->addLayout(column_right, 0, 1); +} + +QVBoxLayout *AssignmentList::drawEntries(int parent_id) { + BackendDB database; + QVBoxLayout *output = new QVBoxLayout; + int i; + + // styling + output->setContentsMargins(5, 0, 0, 0); + + // sort entries + std::sort(Entry::entries.begin(), Entry::entries.end(), Entry::compare); + + for(i = 0; i < Entry::entries.size(); ++i) { + if(Entry::entries[i].parent_id != parent_id) continue; + // skip if this entry is set to hidden + if(Entry::entries[i].hidden) continue; + output->addLayout(new EntryLayout(Entry::entries[i])); + } + + return output; +} + +// Open the 'addGroup' form +void AssignmentList::addGroup() { + AddGroupForm create_new_group_dialog; + if(create_new_group_dialog.exec() == QDialog::Accepted) + this->displayWidgets(); +} + +void AssignmentList::preferences() { + PreferencesDialog preferences_dialog; + if(preferences_dialog.exec() == QDialog::Accepted) + this->displayWidgets(); +} + +void AssignmentList::reload() { + this->initializeGlobals(); + this->displayWidgets(); +} + +void AssignmentList::cleanHidden() { + QMessageBox::StandardButton are_you_sure; + BackendDB database; + + // create 'are you sure?' dialog before going forward + are_you_sure = QMessageBox::question(this, "Are You Sure?", + "Are you sure? All removed groups and entries will be permanently deleted from the database.", + QMessageBox::Yes|QMessageBox::No); + + if(are_you_sure == QMessageBox::Yes) + database.cleanHidden(); +} + +void AssignmentList::aboutDialog() { + QMessageBox about; + QString title("About " + QString(PROJECT_TITLE)); + QString text( + QString(PROJECT_TITLE) + " " + QString(VERSION) + "\n" + + "Created by Louie S. - 2024"); + about.about(this, title, text); +} diff --git a/src/frontend/qtwidgets/assignmentList.h b/src/frontend/qtwidgets/assignmentList.h new file mode 100644 index 0000000..4b792fa --- /dev/null +++ b/src/frontend/qtwidgets/assignmentList.h @@ -0,0 +1,43 @@ +#ifndef ASSIGNMENTLIST_H +#define ASSIGNMENTLIST_H + +#include +#include +#include + +#include "ui_assignmentList.h" + +class AssignmentList : public QMainWindow { + Q_OBJECT + + public: + QSettings configuration; + + AssignmentList(); + void initializeGlobals(); + void displayWidgets(); + + private: + Ui::MainWindow ui; + + void initializeSettings(); + void initializeUI(); + void displayDate(); + QVBoxLayout *drawEntries(int parent_id); + void editEntry(int id); + void toggleDoneEntry(int id); + void removeEntry(int id); + void editRules(int id); + void entryContextMenu(int entry_id); + void drawGroups(); + void drawEntries(); + + private slots: + void preferences(); + void reload(); + void addGroup(); + void cleanHidden(); + void aboutDialog(); +}; + +#endif diff --git a/src/frontend/qtwidgets/assignmentList.ui b/src/frontend/qtwidgets/assignmentList.ui new file mode 100644 index 0000000..60c66da --- /dev/null +++ b/src/frontend/qtwidgets/assignmentList.ui @@ -0,0 +1,213 @@ + + + MainWindow + + + + 0 + 0 + 640 + 480 + + + + Assignment List + + + + :/data/assignment-list.svg:/data/assignment-list.svg + + + + + + + true + + + + + 0 + 0 + 620 + 421 + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + Arial + 17 + + + + [DATE] + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 20 + + + 5 + + + 20 + + + 5 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + 0 + 0 + 640 + 22 + + + + + File + + + + + + + + + Edit + + + + + + + + Help + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + Preferences + + + Alt+Return + + + + + Reload + + + F5 + + + + + Exit + + + Ctrl+Q + + + + + Add Group + + + + + Permanently Delete Removed Groups and Entries + + + + + About + + + + + + + + diff --git a/src/frontend/qtwidgets/editEntryForm.cpp b/src/frontend/qtwidgets/editEntryForm.cpp new file mode 100644 index 0000000..ca788ca --- /dev/null +++ b/src/frontend/qtwidgets/editEntryForm.cpp @@ -0,0 +1,55 @@ +#include + +#include "../../backend/db_sqlite.h" +#include "editEntryForm.h" + +EditEntryForm::EditEntryForm(const Entry &e) : + entry(e) +{ + // load uic + ui.setupUi(this); + + // set titles + this->setWindowTitle("Edit Entry"); + ui.title->setText("Edit Entry"); + + // widgets setup + ui.entry_desc->setText(this->entry.desc); + ui.entry_due->setDate(QDate::currentDate()); + if(this->entry.due.isValid()) { + ui.entry_due->setDate(entry.due.date()); + ui.entry_due_checkbox->setChecked(true); + } + else + ui.entry_due_checkbox->setChecked(false); + ui.entry_due_alt->setText(this->entry.due_alt); + ui.entry_link->setText(this->entry.link.toString()); + ui.entry_color->setText(this->entry.color); + ui.entry_highlight->setText(this->entry.highlight); +} + +void EditEntryForm::accept() { + this->entry.desc = ui.entry_desc->text(); + if(ui.entry_due_checkbox->isChecked()) + this->entry.due = ui.entry_due->dateTime(); + else + this->entry.due = QDateTime(); + this->entry.due_alt = ui.entry_due_alt->text(); + this->entry.link = ui.entry_link->text(); + this->entry.color = ui.entry_color->text(); + this->entry.highlight = ui.entry_highlight->text(); + QMessageBox error_message; + BackendDB database; + + if(this->entry.desc.isEmpty()) { + error_message.setIcon(QMessageBox::Warning); + error_message.setWindowTitle("Error Message"); + error_message.setText("Name cannot be blank"); + error_message.exec(); + return; + } + + database.updateEntry(this->entry); + + QDialog::accept(); +} diff --git a/src/frontend/qtwidgets/editEntryForm.h b/src/frontend/qtwidgets/editEntryForm.h new file mode 100644 index 0000000..6231478 --- /dev/null +++ b/src/frontend/qtwidgets/editEntryForm.h @@ -0,0 +1,25 @@ +#ifndef EDITENTRYFORM_H +#define EDITENTRYFORM_H + +#include + +#include "entry.h" +#include "ui_entryForm.h" + +// form to edit/update an entry +class EditEntryForm : public QDialog { + Q_OBJECT + + public: + EditEntryForm(const Entry &e); + + private: + Ui::entryDialog ui; + + Entry entry; + + private slots: + void accept(); +}; + +#endif diff --git a/src/frontend/qtwidgets/editGroupForm.cpp b/src/frontend/qtwidgets/editGroupForm.cpp new file mode 100644 index 0000000..fa17467 --- /dev/null +++ b/src/frontend/qtwidgets/editGroupForm.cpp @@ -0,0 +1,40 @@ +#include + +#include "../../backend/db_sqlite.h" +#include "editGroupForm.h" + +EditGroupForm::EditGroupForm(const Group &g) : + group(g) +{ + // load uic + ui.setupUi(this); + + // set titles + this->setWindowTitle("Edit Group"); + ui.title->setText("Edit Group"); + + // widgets setup + ui.group_name->setText(this->group.name); + ui.group_column->setCurrentIndex(this->group.column); + ui.group_link->setText(this->group.link); +} + +void EditGroupForm::accept() { + this->group.name = ui.group_name->text(); + this->group.column = Group::Column(ui.group_column->currentIndex()); + this->group.link = ui.group_link->text(); + QMessageBox error_message; + BackendDB database; + + if(this->group.name.isEmpty()) { + error_message.setIcon(QMessageBox::Warning); + error_message.setWindowTitle("Error Message"); + error_message.setText("Name cannot be blank"); + error_message.exec(); + return; + } + + database.updateGroup(this->group); + + QDialog::accept(); +} diff --git a/src/frontend/qtwidgets/editGroupForm.h b/src/frontend/qtwidgets/editGroupForm.h new file mode 100644 index 0000000..e04b46e --- /dev/null +++ b/src/frontend/qtwidgets/editGroupForm.h @@ -0,0 +1,25 @@ +#ifndef EDITGROUPFORM_H +#define EDITGROUPFORM_H + +#include + +#include "group.h" +#include "ui_groupForm.h" + +// form to edit/update a group +class EditGroupForm : public QDialog { + Q_OBJECT + + public: + EditGroupForm(const Group &g); + + private: + Ui::groupDialog ui; + + Group group; + + private slots: + void accept(); +}; + +#endif diff --git a/src/frontend/qtwidgets/entry.cpp b/src/frontend/qtwidgets/entry.cpp new file mode 100644 index 0000000..c95bbb0 --- /dev/null +++ b/src/frontend/qtwidgets/entry.cpp @@ -0,0 +1,36 @@ +#include + +#include "entry.h" + +Entry::Entry(int id, int parent_id, QString desc, QDateTime due, QString due_alt, QUrl link, QString color, QString highlight, bool done, bool hidden) : + id(id), + parent_id(parent_id), + desc(desc), + due(due), + due_alt(due_alt), + link(link), + color(color), + highlight(highlight), + done(done), + hidden(hidden) +{ +} + +QList Entry::entries; + +bool Entry::compare(Entry a, Entry b) { + // 1st level: sort not done before done + if(a.done != b.done) + return a.done < b.done; + // next level: sort on due date + if(a.due != b.due) + return a.due < b.due; + // next level: sort on alt due date + if(a.due_alt != b.due_alt) + return a.due_alt < b.due_alt; + // next level: sort on description + if(a.desc != b.desc) + return a.desc < b.desc; + // otherwise, sort on id + return a.id < b.id; +} diff --git a/src/frontend/qtwidgets/entry.h b/src/frontend/qtwidgets/entry.h new file mode 100644 index 0000000..294df7b --- /dev/null +++ b/src/frontend/qtwidgets/entry.h @@ -0,0 +1,39 @@ +#ifndef ENTRY_H +#define ENTRY_H + +#include +#include +#include + +struct Entry { + int id; + int parent_id; + QString desc; + QDateTime due; + QString due_alt; + QUrl link; + QString color; // consider making this a QColor instead + QString highlight; // see color comment + bool done; + bool hidden; + + Entry( + int id, + int parent_id, + QString desc, + QDateTime due = QDateTime(), + QString due_alt = "", + QUrl link = QUrl(), + QString color = "", + QString highlight = "", + bool done = false, + bool hidden = false + ); + + static QList entries; + + // function for sorting algorithm + static bool compare(Entry a, Entry b); +}; + +#endif diff --git a/src/frontend/qtwidgets/entryForm.ui b/src/frontend/qtwidgets/entryForm.ui new file mode 100644 index 0000000..bce8ce3 --- /dev/null +++ b/src/frontend/qtwidgets/entryForm.ui @@ -0,0 +1,185 @@ + + + entryDialog + + + + 0 + 0 + 400 + 266 + + + + Add Entry + + + + + + + + Description: + + + + + + + + + + + Arial + 18 + + + + [TITLE] + + + Qt::AlignCenter + + + + + + + Due Date: + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + MM/dd/yyyy + + + + + + + true + + + + + + true + + + + + + + + + + Due Date (Alt): + + + + + + + + + + Link: + + + + + + + + + + Color: + + + + + + + + + + Highlight: + + + + + + + + + + + + Qt::LeftToRight + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + true + + + + + + + + + buttonBox + accepted() + entryDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + entryDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/frontend/qtwidgets/entryLayout.cpp b/src/frontend/qtwidgets/entryLayout.cpp new file mode 100644 index 0000000..578ec23 --- /dev/null +++ b/src/frontend/qtwidgets/entryLayout.cpp @@ -0,0 +1,177 @@ +#include +#include + +#include + +#include "../../backend/db_sqlite.h" +#include "editEntryForm.h" +#include "entryLayout.h" +#include "lib.h" +#include "rulesDialog.h" + +EntryLayout::EntryLayout(const Entry &e) : + entry(e) +{ + QLabel *bullet = new QLabel(); + QLabel *body = new QLabel(); + int i; + + // set styling + this->setContentsMargins(2, 2, 2, 2); + + bullet->setFont(QFont("Arial", 11)); + bullet->setMaximumWidth(15); + + body->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse); + body->setFont(QFont("Arial", 11)); + body->setWordWrap(true); + body->setToolTip("Right-Click for actions"); + body->setContextMenuPolicy(Qt::CustomContextMenu); + + // set context menu + body->setContextMenuPolicy(Qt::CustomContextMenu); + QObject::connect(body, + SIGNAL(customContextMenuRequested(const QPoint &)), + SLOT(showContextMenu())); + + // Check rules + QList rules = this->loadRules(); + for(i = 0; i < rules.size(); ++i) { + if( + (rules[i].when == Rule::before && + rules[i].date > QDateTime::currentDateTime()) || + (rules[i].when == Rule::after && + rules[i].date <= QDateTime::currentDateTime()) + ) { + if(!rules[i].color.isEmpty()) + this->entry.color = rules[i].color; + if(!rules[i].highlight.isEmpty()) + this->entry.highlight = rules[i].highlight; + } + } + + // set conditional styling + if(this->entry.done) { + bullet->setText("\u2713"); + bullet->setStyleSheet( + "QLabel {" + " color: green;" + "}" + ); + } + else + bullet->setText("- "); + this->addWidget(bullet); + + if(!this->entry.due.isNull()) + body->setText(this->entry.due.toString("dddd, MM/dd/yyyy: ")); + else if(!this->entry.due_alt.isEmpty()) + body->setText(this->entry.due_alt + ": "); + + if(!this->entry.link.isEmpty()) { + body->setOpenExternalLinks(true); + body->setText(body->text() + "entry.link.toString() + "\" " "style=\"color: "); + if(this->entry.done) + body->setText(body->text() + "green"); + else if(this->entry.color.isEmpty()) + body->setText(body->text() + "default"); + else + body->setText(body->text() + this->entry.color); + body->setText(body->text() + ";\">"); + } + body->setText(body->text() + this->entry.desc); + if(!this->entry.link.isEmpty()) { + body->setText(body->text() + ""); + body->setToolTip(this->entry.link.toString()); + } + + if(this->entry.done) { + QFont body_font = body->font(); + body_font.setStrikeOut(true); + body->setFont(body_font); + body->setStyleSheet( + "QLabel {" + " color: green" + "}" + ); + } + else { + body->setStyleSheet( + "QLabel {" + " color: " + (this->entry.color.isEmpty() ? "default" : this->entry.color) + ";" + " background-color: " + (this->entry.highlight.isEmpty() ? "none" : this->entry.highlight) + ";" + " font-weight: " + (this->entry.due.isValid() && this->entry.due <= QDateTime::currentDateTime() ? "bold" : "normal") + ";" + "}" + ); + } + + this->addWidget(body); +} + +QList EntryLayout::loadRules() { + BackendDB database; + + return database.loadRules(this->entry.id); +} + +void EntryLayout::showContextMenu() { + QMenu menu; + + QAction *edit_entry_act = new QAction("Edit Entry"); + QObject::connect(edit_entry_act, &QAction::triggered, this, &EntryLayout::editEntry); + menu.addAction(edit_entry_act); + + QAction *set_rules_act = new QAction("Rules"); + QObject::connect(set_rules_act, &QAction::triggered, this, &EntryLayout::setRules); + menu.addAction(set_rules_act); + + QAction *toggle_done_act = new QAction("Done"); + toggle_done_act->setCheckable(true); + if(this->entry.done) toggle_done_act->setChecked(true); + QObject::connect(toggle_done_act, &QAction::triggered, this, &EntryLayout::toggleDone); + menu.addAction(toggle_done_act); + + QAction *clone_entry_act = new QAction("Clone Entry"); + QObject::connect(clone_entry_act, &QAction::triggered, this, &EntryLayout::cloneEntry); + menu.addAction(clone_entry_act); + + QAction *del_entry_act = new QAction("Remove Entry"); + QObject::connect(del_entry_act, &QAction::triggered, this, &EntryLayout::removeEntry); + menu.addAction(del_entry_act); + + menu.exec(QCursor::pos()); +} + +void EntryLayout::editEntry() { + EditEntryForm edit_entry_dialog(this->entry); + if(edit_entry_dialog.exec() == QDialog::Accepted) + getMainWindow()->displayWidgets(); +} + +void EntryLayout::setRules() { + RulesDialog rules_dialog(this->entry); + if(rules_dialog.exec() == QDialog::Accepted) + getMainWindow()->displayWidgets(); +} + +void EntryLayout::toggleDone() { + BackendDB database; + + this->entry.done = !this->entry.done; + database.updateEntry(this->entry); + getMainWindow()->displayWidgets(); +} + +void EntryLayout::cloneEntry() { + BackendDB database; + + database.insertEntry(this->entry); + getMainWindow()->displayWidgets(); +} + +void EntryLayout::removeEntry() { + BackendDB database; + + if(database.removeEntry(this->entry) > 0) + getMainWindow()->displayWidgets(); +} diff --git a/src/frontend/qtwidgets/entryLayout.h b/src/frontend/qtwidgets/entryLayout.h new file mode 100644 index 0000000..54e523f --- /dev/null +++ b/src/frontend/qtwidgets/entryLayout.h @@ -0,0 +1,32 @@ +#ifndef ENTRYLAYOUT_H +#define ENTRYLAYOUT_H + +#include +#include +#include +#include + +#include "entry.h" +#include "rule.h" + +class EntryLayout : public QHBoxLayout { + Q_OBJECT + + public: + Entry entry; + + EntryLayout(const Entry &e); + + private: + QList loadRules(); + + private slots: + void showContextMenu(); + void editEntry(); + void setRules(); + void toggleDone(); + void cloneEntry(); + void removeEntry(); +}; + +#endif diff --git a/src/frontend/qtwidgets/group.cpp b/src/frontend/qtwidgets/group.cpp new file mode 100644 index 0000000..ddb3b13 --- /dev/null +++ b/src/frontend/qtwidgets/group.cpp @@ -0,0 +1,14 @@ +#include + +#include "group.h" + +Group::Group(int id, QString name, Group::Column column, QString link, bool hidden) : + id(id), + name(name), + column(column), + link(link), + hidden(hidden) +{ +} + +QList Group::groups; diff --git a/src/frontend/qtwidgets/group.h b/src/frontend/qtwidgets/group.h new file mode 100644 index 0000000..9c7bfa4 --- /dev/null +++ b/src/frontend/qtwidgets/group.h @@ -0,0 +1,25 @@ +#ifndef GROUP_H +#define GROUP_H + +#include + +struct Group { + enum Column { left, right }; + int id; + QString name; + Column column; + QString link; + bool hidden; + + Group( + int id, + QString name, + Column column = left, + QString link = "", + bool hidden = false + ); + + static QList groups; +}; + +#endif diff --git a/src/frontend/qtwidgets/groupForm.ui b/src/frontend/qtwidgets/groupForm.ui new file mode 100644 index 0000000..4f58e1d --- /dev/null +++ b/src/frontend/qtwidgets/groupForm.ui @@ -0,0 +1,131 @@ + + + groupDialog + + + + 0 + 0 + 400 + 172 + + + + Group Form + + + + + + + + + Arial + 18 + + + + [TITLE] + + + Qt::AlignCenter + + + + + + + Name: + + + + + + + + + + Column: + + + + + + + + Left + + + + + Right + + + + + + + + Link: + + + + + + + + + + + + Qt::LeftToRight + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + true + + + + + + + + + buttonBox + accepted() + groupDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + groupDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/src/frontend/qtwidgets/groupLayout.cpp b/src/frontend/qtwidgets/groupLayout.cpp new file mode 100644 index 0000000..e67d3a5 --- /dev/null +++ b/src/frontend/qtwidgets/groupLayout.cpp @@ -0,0 +1,68 @@ +#include +#include +#include + +#include + +#include "addEntryForm.h" +#include "../../backend/db_sqlite.h" +#include "editGroupForm.h" +#include "groupLayout.h" +#include "lib.h" + +GroupLayout::GroupLayout(const Group &g) : + group(g) +{ + this->setContentsMargins(0, 10, 0, 10); + + QLabel *name_label = new QLabel(this->group.name); + name_label->setTextInteractionFlags(Qt::TextSelectableByMouse); + name_label->setToolTip("Right-Click for actions"); + name_label->setContextMenuPolicy(Qt::CustomContextMenu); + //name_label->customContextMenuRequested(const QPoint &pos) + QObject::connect(name_label, + SIGNAL(customContextMenuRequested(const QPoint &)), + SLOT(showContextMenu())); + + QFont name_font = QFont("Arial", 13); + name_font.setUnderline(true); + name_label->setFont(name_font); + + this->addWidget(name_label); +} + +void GroupLayout::showContextMenu() { + QMenu menu; + + QAction *add_entry_act = new QAction("Add Entry"); + QObject::connect(add_entry_act, &QAction::triggered, this, &GroupLayout::addEntry); + menu.addAction(add_entry_act); + + QAction *edit_group_act = new QAction("Edit Group"); + QObject::connect(edit_group_act, &QAction::triggered, this, &GroupLayout::editGroup); + menu.addAction(edit_group_act); + + QAction *del_group_act = new QAction("Remove Group"); + QObject::connect(del_group_act, &QAction::triggered, this, &GroupLayout::removeGroup); + menu.addAction(del_group_act); + + menu.exec(QCursor::pos()); +} + +void GroupLayout::addEntry() { + AddEntryForm create_new_entry_dialog(this->group); + if(create_new_entry_dialog.exec() == QDialog::Accepted) + getMainWindow()->displayWidgets(); +} + +void GroupLayout::editGroup() { + EditGroupForm edit_group_dialog(this->group); + if(edit_group_dialog.exec() == QDialog::Accepted) + getMainWindow()->displayWidgets(); +} + +void GroupLayout::removeGroup() { + BackendDB database; + if(database.removeGroup(this->group) > 0) + getMainWindow()->displayWidgets(); +} diff --git a/src/frontend/qtwidgets/groupLayout.h b/src/frontend/qtwidgets/groupLayout.h new file mode 100644 index 0000000..cfd33cf --- /dev/null +++ b/src/frontend/qtwidgets/groupLayout.h @@ -0,0 +1,23 @@ +#ifndef GROUPLAYOUT_H +#define GROUPLAYOUT_H + +#include + +#include "group.h" + +class GroupLayout : public QVBoxLayout { + Q_OBJECT + + public: + Group group; + + GroupLayout(const Group &g); + + private slots: + void showContextMenu(); + void addEntry(); + void editGroup(); + void removeGroup(); +}; + +#endif diff --git a/src/frontend/qtwidgets/lib.cpp b/src/frontend/qtwidgets/lib.cpp new file mode 100644 index 0000000..2290472 --- /dev/null +++ b/src/frontend/qtwidgets/lib.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +#include "lib.h" + +// shamelessly ripped from https://stackoverflow.com/a/46456214 +AssignmentList *getMainWindow() { + foreach(QWidget *w, QApplication::topLevelWidgets()) + if(AssignmentList *mainWin = qobject_cast(w)) + return mainWin; + return nullptr; +} + +void recursiveClear(QLayout *layout) { + QLayoutItem *child; + while((child = layout->takeAt(0)) != nullptr) { + if(child->layout()) recursiveClear(child->layout()); + delete child->widget(); + delete child; + } +} diff --git a/src/frontend/qtwidgets/lib.h b/src/frontend/qtwidgets/lib.h new file mode 100644 index 0000000..14f63c1 --- /dev/null +++ b/src/frontend/qtwidgets/lib.h @@ -0,0 +1,12 @@ +/* Helper functions that various classes utilize */ + +#include + +#include "assignmentList.h" + +AssignmentList *getMainWindow(); + +QDialog *getParentDialog(); + +// used to clear out a layout when a refresh occurs +void recursiveClear(QLayout *layout); diff --git a/src/frontend/qtwidgets/main.cpp b/src/frontend/qtwidgets/main.cpp new file mode 100644 index 0000000..f7d69ee --- /dev/null +++ b/src/frontend/qtwidgets/main.cpp @@ -0,0 +1,12 @@ +#include +#include + +#include "assignmentList.h" + +int main(int argc, char **argv) { + QApplication app (argc, argv); + + AssignmentList window; + + return app.exec(); +} diff --git a/src/frontend/qtwidgets/preferencesDialog.cpp b/src/frontend/qtwidgets/preferencesDialog.cpp new file mode 100644 index 0000000..d3b3dff --- /dev/null +++ b/src/frontend/qtwidgets/preferencesDialog.cpp @@ -0,0 +1,59 @@ +#include +#include + +#include "preferencesDialog.h" + +PreferencesDialog::PreferencesDialog() { + // load uic + ui.setupUi(this); + + // display widgets + // TODO make this a scollable window + // FIXME could use some work on sizing + this->setupPathsTab(); + + // create button connections + QObject::connect(ui.close_button, &QPushButton::released, this, &PreferencesDialog::close); + QObject::connect(ui.apply_button, &QPushButton::released, this, &PreferencesDialog::apply); + QObject::connect(ui.reload_button, &QPushButton::released, this, &PreferencesDialog::reload); +} + +void PreferencesDialog::setupPathsTab() { + QSettings settings; + settings.beginGroup("paths"); + + ui.db_path_edit->setText(settings.value("db_path").toString()); + QObject::connect(ui.db_path_button, &QPushButton::released, this, &PreferencesDialog::dbPathDialog); +} + +void PreferencesDialog::dbPathDialog() { + QFileDialog file_dialog; + // TODO create filter to only allow selecting .db files + QString new_path = file_dialog.getOpenFileName(this, "Open File"); + + if(!new_path.isEmpty()) + ui.db_path_edit->setText(new_path); +} + +// close the dialog, returning our ret_value +void PreferencesDialog::close() { + this->done(ret_value); +} + +// update the configuration in the config file +void PreferencesDialog::apply() { + QSettings settings; + + // save paths + settings.beginGroup("paths"); + settings.setValue("db_path", ui.db_path_edit->text()); + + // set the return value to accepted + this->ret_value = QDialog::Accepted; +} + +// update, reload, and close the window +void PreferencesDialog::reload() { + this->apply(); + this->accept(); +} diff --git a/src/frontend/qtwidgets/preferencesDialog.h b/src/frontend/qtwidgets/preferencesDialog.h new file mode 100644 index 0000000..ac9b88e --- /dev/null +++ b/src/frontend/qtwidgets/preferencesDialog.h @@ -0,0 +1,28 @@ +#ifndef PREFERENCESDIALOG_H +#define PREFERENCESDIALOG_H + +#include + +#include "ui_preferencesDialog.h" + +// set configuration options in the program +class PreferencesDialog : public QDialog { + Q_OBJECT + + public: + PreferencesDialog(); + + private: + Ui::preferencesDialog ui; + QDialog::DialogCode ret_value = QDialog::Rejected; + + void setupPathsTab(); + + private slots: + void dbPathDialog(); + void close(); + void apply(); + void reload(); +}; + +#endif diff --git a/src/frontend/qtwidgets/preferencesDialog.ui b/src/frontend/qtwidgets/preferencesDialog.ui new file mode 100644 index 0000000..343ba33 --- /dev/null +++ b/src/frontend/qtwidgets/preferencesDialog.ui @@ -0,0 +1,128 @@ + + + preferencesDialog + + + + 0 + 0 + 500 + 320 + + + + Preferences + + + + + + + + 0 + + + + Paths + + + + + + + + + + + Database File: + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 25 + 16777215 + + + + ... + + + + + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Close + + + + + + + Apply + + + + + + + Reload + + + + + + + + + + + + diff --git a/src/frontend/qtwidgets/rule.cpp b/src/frontend/qtwidgets/rule.cpp new file mode 100644 index 0000000..85da13a --- /dev/null +++ b/src/frontend/qtwidgets/rule.cpp @@ -0,0 +1,15 @@ +#include + +#include "rule.h" + +Rule::Rule(int id, int entry_id, When when, QDateTime date, QString color, QString highlight) : + id(id), + entry_id(entry_id), + when(when), + date(date), + color(color), + highlight(highlight) +{ +} + +QList Rule::rules; diff --git a/src/frontend/qtwidgets/rule.h b/src/frontend/qtwidgets/rule.h new file mode 100644 index 0000000..cf9abfe --- /dev/null +++ b/src/frontend/qtwidgets/rule.h @@ -0,0 +1,28 @@ +#ifndef RULE_H +#define RULE_H + +#include +#include + +struct Rule { + enum When { before, after }; + int id; + int entry_id; + When when; + QDateTime date; + QString color; // consider making this a QColor instead + QString highlight; // see color comment + + Rule( + int id, + int entry_id, + When when, + QDateTime date = QDateTime::currentDateTime(), + QString color = "", + QString highlight = "" + ); + + static QList rules; +}; + +#endif diff --git a/src/frontend/qtwidgets/ruleLayout.cpp b/src/frontend/qtwidgets/ruleLayout.cpp new file mode 100644 index 0000000..11abf80 --- /dev/null +++ b/src/frontend/qtwidgets/ruleLayout.cpp @@ -0,0 +1,40 @@ + +#include "lib.h" +#include "ruleLayout.h" + +RuleLayout::RuleLayout(const Rule &r) : + rule(r) +{ + this->when_widget = new QComboBox; + this->date_widget = new QDateTimeEdit(QDate::currentDate()); + this->color_widget = new QLineEdit; + this->highlight_widget = new QLineEdit; + this->del_button = new QPushButton; + + QStringList when_options; + when_options.append("Before"); + when_options.append("After"); + this->when_widget->addItems(when_options); + this->when_widget->setCurrentIndex(this->rule.when); + this->addWidget(this->when_widget); + + this->date_widget->setDisplayFormat("MM/dd/yyyy"); + this->date_widget->setDateTime(this->rule.date); + this->addWidget(this->date_widget); + + this->addStretch(); + + this->color_widget->setPlaceholderText("Color"); + if(!this->rule.color.isEmpty()) + this->color_widget->setText(this->rule.color); + this->addWidget(this->color_widget); + + this->highlight_widget->setPlaceholderText("Highlight"); + if(!this->rule.highlight.isEmpty()) + this->highlight_widget->setText(this->rule.highlight); + this->addWidget(this->highlight_widget); + + this->del_button->setText("Delete"); + // connection needs to be made in rulesDialog.cpp + this->addWidget(this->del_button); +} diff --git a/src/frontend/qtwidgets/ruleLayout.h b/src/frontend/qtwidgets/ruleLayout.h new file mode 100644 index 0000000..29a4deb --- /dev/null +++ b/src/frontend/qtwidgets/ruleLayout.h @@ -0,0 +1,27 @@ +#ifndef RULELAYOUT_H +#define RULELAYOUT_H + +#include +#include +#include +#include +#include +#include + +#include "rule.h" + +class RuleLayout : public QHBoxLayout { + Q_OBJECT + + public: + Rule rule; + QComboBox *when_widget; + QDateTimeEdit *date_widget; + QLineEdit *color_widget; // TODO consider making this a color selector widget + QLineEdit *highlight_widget; // TODO consider making this a color selector widget + QPushButton *del_button; + + RuleLayout(const Rule &r); +}; + +#endif diff --git a/src/frontend/qtwidgets/rulesDialog.cpp b/src/frontend/qtwidgets/rulesDialog.cpp new file mode 100644 index 0000000..cd62342 --- /dev/null +++ b/src/frontend/qtwidgets/rulesDialog.cpp @@ -0,0 +1,107 @@ +#include +#include +#include + +#include + +#include "../../backend/db_sqlite.h" +#include "lib.h" +#include "ruleLayout.h" +#include "rulesDialog.h" + +RulesDialog::RulesDialog(const Entry &entry) { + BackendDB database; + + this->entry_id = entry.id; + + // load uic + ui.setupUi(this); + + // load rules into object member + this->rules = database.loadRules(entry_id); + + // display widgets + this->drawRules(); + + // set connections + QObject::connect(ui.add_rule_button, &QPushButton::released, this, &RulesDialog::addRule); +} + +// for maintaining values when adding/removing rules +void RulesDialog::updateRulesList() { + int i; + + for(i = 0; i < ui.rules_layout->children().size(); ++i) { + this->rules[i].when = Rule::When(qobject_cast(ui.rules_layout->children()[i])->when_widget->currentIndex()); + this->rules[i].date = qobject_cast(ui.rules_layout->children()[i])->date_widget->dateTime(); + this->rules[i].color = qobject_cast(ui.rules_layout->children()[i])->color_widget->text(); + this->rules[i].highlight = qobject_cast(ui.rules_layout->children()[i])->highlight_widget->text(); + } +} + +void RulesDialog::drawRules() { + RuleLayout *new_layout; + int i; + + + // remove all children from layout + recursiveClear(ui.rules_layout); + + // Draw each rule + for(i = 0; i < this->rules.size(); ++i) { + new_layout = new RuleLayout(rules[i]); + + // connect delete button + QObject::connect(new_layout->del_button, &QPushButton::released, this, [=](){ this->deleteRule(i); }); + + ui.rules_layout->addLayout(new_layout); + } +} + +void RulesDialog::addRule() { + Rule new_rule = Rule(0, this->entry_id, Rule::before); + RuleLayout *new_layout = new RuleLayout(new_rule); + + // add new rule to the member variable + this->rules.append(new_rule); + + // redraw rules + this->updateRulesList(); + this->drawRules(); +} + +void RulesDialog::deleteRule(int i) { + if(i < 0) return; + if(i >= this->rules.size()) return; + + this->updateRulesList(); + // mark as needing to be deleted from database if id > 0 + if(this->rules[i].id > 0) + this->deleted_rules.append(this->rules[i]); + this->rules.removeAt(i); + this->drawRules(); +} + +void RulesDialog::accept() { + int i; + BackendDB database; + + this->updateRulesList(); + + // update rules in database + for(i = 0; i < this->rules.size(); ++i) { + // insert - this is a new rule + if(this->rules[i].id == 0) + database.insertRule(this->rules[i]); + // update - this is an existing rule + else + database.updateRule(this->rules[i]); + } + + // delete deleted rules in database + for(i = 0; i < this->deleted_rules.size(); ++i) { + database.removeRule(this->deleted_rules[i]); + } + + QDialog::accept(); +} diff --git a/src/frontend/qtwidgets/rulesDialog.h b/src/frontend/qtwidgets/rulesDialog.h new file mode 100644 index 0000000..7e74dc2 --- /dev/null +++ b/src/frontend/qtwidgets/rulesDialog.h @@ -0,0 +1,32 @@ +#ifndef RULESDIALOG_H +#define RULESDIALOG_H + +#include + +#include "entry.h" +#include "rule.h" +#include "ui_rulesDialog.h" + +// show the list of rules associated with an entry +class RulesDialog : public QDialog { + Q_OBJECT + + public: + RulesDialog(const Entry &entry); + void drawRules(); + + private: + Ui::rulesDialog ui; + int entry_id; + QList rules; + QList deleted_rules; + + void updateRulesList(); + + private slots: + void addRule(); + void deleteRule(int i); + void accept(); +}; + +#endif diff --git a/src/frontend/qtwidgets/rulesDialog.ui b/src/frontend/qtwidgets/rulesDialog.ui new file mode 100644 index 0000000..c362887 --- /dev/null +++ b/src/frontend/qtwidgets/rulesDialog.ui @@ -0,0 +1,123 @@ + + + rulesDialog + + + + 0 + 0 + 500 + 320 + + + + Dialog + + + + + + true + + + + + 0 + 0 + 480 + 269 + + + + + + + + + + + + Add Rule + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + rulesDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + rulesDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + -- cgit