summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/assignmentList.cpp12
-rw-r--r--src/assignmentList.h4
-rw-r--r--src/backend/db_sqlite.cpp48
-rw-r--r--src/backend/db_sqlite.h3
-rw-r--r--src/entryLayout.cpp21
-rw-r--r--src/lib.cpp9
-rw-r--r--src/lib.h5
-rw-r--r--src/rule.h10
-rw-r--r--src/ruleLayout.cpp42
-rw-r--r--src/ruleLayout.h15
-rw-r--r--src/rulesDialog.cpp81
-rw-r--r--src/rulesDialog.h30
-rw-r--r--src/rulesDialog.ui123
13 files changed, 348 insertions, 55 deletions
diff --git a/src/assignmentList.cpp b/src/assignmentList.cpp
index 953d443..673e0b5 100644
--- a/src/assignmentList.cpp
+++ b/src/assignmentList.cpp
@@ -18,6 +18,7 @@
#include "backend/db_sqlite.h"
#include "entryLayout.h"
#include "groupLayout.h"
+#include "lib.h"
#include "preferencesDialog.h"
AssignmentList::AssignmentList() {
@@ -76,7 +77,7 @@ void AssignmentList::displayWidgets() {
int i;
// clear out old layouts if they exist
- this->recursiveClear(ui.groups_layout);
+ recursiveClear(ui.groups_layout);
for(i = 0; i < groups.size(); ++i) {
if(groups[i]->hidden) continue;
@@ -138,12 +139,3 @@ void AssignmentList::aboutDialog() {
QMessageBox about;
about.about(this, "About Assignment List", "Created by Louie S. - 2023");
}
-
-void AssignmentList::recursiveClear(QLayout *layout) {
- QLayoutItem *child;
- while((child = layout->takeAt(0)) != nullptr) {
- if(child->layout()) this->recursiveClear(child->layout());
- delete child->widget();
- delete child;
- }
-}
diff --git a/src/assignmentList.h b/src/assignmentList.h
index d5da023..8b028d7 100644
--- a/src/assignmentList.h
+++ b/src/assignmentList.h
@@ -31,10 +31,6 @@ class AssignmentList : public QMainWindow {
void drawGroups();
void drawEntries();
- // helpers
- // used to clear out the grid layout when a refresh occurs
- void recursiveClear(QLayout *layout);
-
private slots:
void preferences();
void reload();
diff --git a/src/backend/db_sqlite.cpp b/src/backend/db_sqlite.cpp
index 4319b67..32108e1 100644
--- a/src/backend/db_sqlite.cpp
+++ b/src/backend/db_sqlite.cpp
@@ -134,7 +134,33 @@ QList<Rule *> BackendDB::loadRules() {
QSqlDatabase database(this->openDB());
QSqlQuery query;
- query.exec("SELECT * FROM groups");
+ query.exec("SELECT * FROM rules");
+ while(query.next()) {
+ output.append(new Rule(
+ query.record().field("id").value().toInt(),
+ query.record().field("entry_id").value().toInt(),
+ (Rule::When) query.record().field("before_after").value().toInt(),
+ query.record().field("date").value().toDateTime(),
+ query.record().field("color").value().toString(),
+ query.record().field("highlight").value().toString()));
+ }
+ }
+
+ QSqlDatabase::removeDatabase("qt_sql_default_connection");
+ return output;
+}
+
+// load entries
+QList<Rule *> BackendDB::loadRules(int entry_id) {
+ QList<Rule *> output;
+
+ {
+ QSqlDatabase database(this->openDB());
+ QSqlQuery query;
+
+ query.prepare("SELECT * FROM rules WHERE entry_id = ?");
+ query.bindValue(0, entry_id);
+ query.exec();
while(query.next()) {
output.append(new Rule(
query.record().field("id").value().toInt(),
@@ -295,6 +321,26 @@ int BackendDB::removeEntry(const Entry &entry) {
return output;
}
+// return value: number of affected rows
+int BackendDB::removeRule(const Rule &rule) {
+ int output;
+
+ {
+ QSqlDatabase database(this->openDB());
+ QSqlQuery query;
+
+ query.prepare("DELETE FROM rules WHERE id = ?");
+ query.bindValue(0, rule.id);
+ query.exec();
+
+ // FIXME not sure if this also needs to be called after the first query...
+ output = query.numRowsAffected();
+ }
+
+ QSqlDatabase::removeDatabase("qt_sql_default_connection");
+ return output;
+}
+
// permanently delete removed/hidden groups and entries
void BackendDB::cleanHidden() {
{
diff --git a/src/backend/db_sqlite.h b/src/backend/db_sqlite.h
index 1db61e8..ce2d900 100644
--- a/src/backend/db_sqlite.h
+++ b/src/backend/db_sqlite.h
@@ -16,6 +16,7 @@ class BackendDB : QSqlDatabase {
QList<Entry *> loadEntries();
QList<Entry *> loadEntries(int parent_id);
QList<Rule *> loadRules();
+ QList<Rule *> loadRules(int entry_id);
int insertGroup(const Group &new_group);
int insertEntry(const Entry &new_entry);
int insertRule(int new_rule); // param datatype TBD
@@ -24,7 +25,7 @@ class BackendDB : QSqlDatabase {
void updateRule(int rule); // param datatype TBD
int removeGroup(const Group &group);
int removeEntry(const Entry &entry);
- void removeRule(int rule); // param datatype TBD
+ int removeRule(const Rule &rule);
void cleanHidden();
private:
diff --git a/src/entryLayout.cpp b/src/entryLayout.cpp
index 48b2888..54aa5f8 100644
--- a/src/entryLayout.cpp
+++ b/src/entryLayout.cpp
@@ -7,6 +7,7 @@
#include "editEntryForm.h"
#include "entryLayout.h"
#include "lib.h"
+#include "rulesDialog.h"
EntryLayout::EntryLayout(const Entry &e) :
entry(e)
@@ -38,13 +39,11 @@ EntryLayout::EntryLayout(const Entry &e) :
// set conditional styling
if(this->entry.done) {
bullet->setText("\u2713");
- /*
bullet->setStyleSheet(
"QLabel {"
" color: green;"
"}"
);
- */
}
else
bullet->setText("- ");
@@ -69,24 +68,20 @@ EntryLayout::EntryLayout(const Entry &e) :
QFont body_font = body->font();
body_font.setStrikeOut(true);
body->setFont(body_font);
- /*
body->setStyleSheet(
"QLabel {"
" color: green"
"}"
);
- */
}
else {
- /*
body->setStyleSheet(
"QLabel {"
- " color: " + (this->color.isEmpty() ? "default" : this->color) + ";"
- " background-color: " + (this->highlight.isEmpty() ? "none" : this->highlight) + ";"
- " font-weight: " + (this->due.isValid() && this->due <= QDateTime::currentDateTime() ? "bold" : "normal") + ";"
- ";"
+ " 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);
@@ -100,7 +95,7 @@ void EntryLayout::showContextMenu() {
menu.addAction(edit_entry_act);
QAction *set_rules_act = new QAction("Rules");
- QObject::connect(edit_entry_act, &QAction::triggered, this, &EntryLayout::setRules);
+ QObject::connect(set_rules_act, &QAction::triggered, this, &EntryLayout::setRules);
menu.addAction(set_rules_act);
QAction *toggle_done_act = new QAction("Done");
@@ -123,7 +118,9 @@ void EntryLayout::editEntry() {
}
void EntryLayout::setRules() {
- qDebug() << "WIP";
+ RulesDialog rules_dialog(this->entry);
+ if(rules_dialog.exec() == QDialog::Accepted)
+ getMainWindow()->displayWidgets();
}
void EntryLayout::toggleDone() {
diff --git a/src/lib.cpp b/src/lib.cpp
index 2815863..2290472 100644
--- a/src/lib.cpp
+++ b/src/lib.cpp
@@ -11,3 +11,12 @@ AssignmentList *getMainWindow() {
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/lib.h b/src/lib.h
index b9b876b..14f63c1 100644
--- a/src/lib.h
+++ b/src/lib.h
@@ -5,3 +5,8 @@
#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/rule.h b/src/rule.h
index 2120401..1d7e90a 100644
--- a/src/rule.h
+++ b/src/rule.h
@@ -10,16 +10,16 @@ struct Rule {
int entry_id;
When when;
QDateTime date;
- QString color = "";
- QString highlight = "";
+ QString color; // consider making this a QColor instead
+ QString highlight; // see color comment
Rule(
int id,
int entry_id,
When when,
- QDateTime date,
- QString color,
- QString highlight
+ QDateTime date = QDateTime::currentDateTime(),
+ QString color = "",
+ QString highlight = ""
);
};
diff --git a/src/ruleLayout.cpp b/src/ruleLayout.cpp
index f922f1a..11abf80 100644
--- a/src/ruleLayout.cpp
+++ b/src/ruleLayout.cpp
@@ -1,38 +1,40 @@
-#include <QComboBox>
-#include <QDate>
-#include <QDateTimeEdit>
-#include <QLineEdit>
+#include "lib.h"
#include "ruleLayout.h"
RuleLayout::RuleLayout(const Rule &r) :
rule(r)
{
- QComboBox *when_widget = new QComboBox;
- QDateTimeEdit *date_widget = new QDateTimeEdit(QDate::currentDate());
- QLineEdit *color_widget = new QLineEdit; // TODO consider making this a color selector widget
- QLineEdit *highlight_widget = new QLineEdit; // TODO consider making this a color selector widget
+ 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");
- when_widget->addItems(when_options);
- when_widget->setCurrentIndex(this->rule.when);
- this->addWidget(when_widget);
+ this->when_widget->addItems(when_options);
+ this->when_widget->setCurrentIndex(this->rule.when);
+ this->addWidget(this->when_widget);
- date_widget->setDisplayFormat("MM/dd/yyyy");
- date_widget->setDateTime(this->rule.date);
- this->addWidget(date_widget);
+ this->date_widget->setDisplayFormat("MM/dd/yyyy");
+ this->date_widget->setDateTime(this->rule.date);
+ this->addWidget(this->date_widget);
this->addStretch();
- color_widget->setPlaceholderText("Color");
+ this->color_widget->setPlaceholderText("Color");
if(!this->rule.color.isEmpty())
- color_widget->setText(this->rule.color);
- this->addWidget(color_widget);
+ this->color_widget->setText(this->rule.color);
+ this->addWidget(this->color_widget);
- highlight_widget->setPlaceholderText("Highlight");
+ this->highlight_widget->setPlaceholderText("Highlight");
if(!this->rule.highlight.isEmpty())
- highlight_widget->setText(this->rule.highlight);
- this->addWidget(highlight_widget);
+ 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/ruleLayout.h b/src/ruleLayout.h
index 45aafc1..29a4deb 100644
--- a/src/ruleLayout.h
+++ b/src/ruleLayout.h
@@ -1,14 +1,25 @@
#ifndef RULELAYOUT_H
#define RULELAYOUT_H
+#include <QComboBox>
+#include <QDate>
+#include <QDateTimeEdit>
#include <QHBoxLayout>
+#include <QLineEdit>
+#include <QPushButton>
#include "rule.h"
-// TODO consider getting rid of this class (unneccesary)
-class RuleLayout : QHBoxLayout {
+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);
};
diff --git a/src/rulesDialog.cpp b/src/rulesDialog.cpp
new file mode 100644
index 0000000..b856ebb
--- /dev/null
+++ b/src/rulesDialog.cpp
@@ -0,0 +1,81 @@
+#include <QPushButton>
+#include <QScrollArea>
+#include <QVBoxLayout>
+
+#include <QDebug>
+
+#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<RuleLayout *>(ui.rules_layout->children()[i])->when_widget->currentIndex());
+ this->rules[i]->date = qobject_cast<RuleLayout *>(ui.rules_layout->children()[i])->date_widget->dateTime();
+ this->rules[i]->color = qobject_cast<RuleLayout *>(ui.rules_layout->children()[i])->color_widget->text();
+ this->rules[i]->highlight = qobject_cast<RuleLayout *>(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() {
+ // TODO handle in db backend to insert instead of updating if id is 0
+ Rule *new_rule = new 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();
+ this->rules.removeAt(i);
+ this->drawRules();
+}
diff --git a/src/rulesDialog.h b/src/rulesDialog.h
new file mode 100644
index 0000000..8f0fd81
--- /dev/null
+++ b/src/rulesDialog.h
@@ -0,0 +1,30 @@
+#ifndef RULESDIALOG_H
+#define RULESDIALOG_H
+
+#include <QDialog>
+
+#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<Rule *> rules;
+
+ void updateRulesList();
+
+ private slots:
+ void addRule();
+ void deleteRule(int i);
+};
+
+#endif
diff --git a/src/rulesDialog.ui b/src/rulesDialog.ui
new file mode 100644
index 0000000..c362887
--- /dev/null
+++ b/src/rulesDialog.ui
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>rulesDialog</class>
+ <widget class="QDialog" name="rulesDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>500</width>
+ <height>320</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QScrollArea" name="scrollArea">
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaWidgetContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>480</width>
+ <height>269</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <layout class="QVBoxLayout" name="rules_layout"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="rules_button_box">
+ <item>
+ <widget class="QPushButton" name="add_rule_button">
+ <property name="text">
+ <string>Add Rule</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>rulesDialog</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>rulesDialog</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>