diff --git a/images/readme/editor.png b/images/readme/editor.png index 0ec5176..969046e 100644 Binary files a/images/readme/editor.png and b/images/readme/editor.png differ diff --git a/images/readme/entry_list.png b/images/readme/entry_list.png index 4a77981..bf6c7d3 100644 Binary files a/images/readme/entry_list.png and b/images/readme/entry_list.png differ diff --git a/images/readme/main_menu.png b/images/readme/main_menu.png index 1f59495..ca3d781 100644 Binary files a/images/readme/main_menu.png and b/images/readme/main_menu.png differ diff --git a/images/readme/pixels.png b/images/readme/pixels.png index 4412153..6e89a1e 100644 Binary files a/images/readme/pixels.png and b/images/readme/pixels.png differ diff --git a/images/readme/statistics.png b/images/readme/statistics.png index 98708b7..5bf0a10 100644 Binary files a/images/readme/statistics.png and b/images/readme/statistics.png differ diff --git a/src/core/internalmanager.cpp b/src/core/internalmanager.cpp index a175780..75c0ccb 100644 --- a/src/core/internalmanager.cpp +++ b/src/core/internalmanager.cpp @@ -136,21 +136,21 @@ void InternalManager::start_update_theme() void InternalManager::set_light_palette() { set_colour(td::ColourRole::Unknown, QStringLiteral("#C9C9CF")); - set_colour(td::ColourRole::VeryBad, QStringLiteral("#7b1fa2")); - set_colour(td::ColourRole::Bad, QStringLiteral("#5e35b1")); - set_colour(td::ColourRole::Ok, QStringLiteral("#1976d2")); - set_colour(td::ColourRole::Good, QStringLiteral("#0097a7")); - set_colour(td::ColourRole::VeryGood, QStringLiteral("#4caf50")); + set_colour(td::ColourRole::VeryBad, QStringLiteral("#C43F31")); + set_colour(td::ColourRole::Bad, QStringLiteral("#E07F16")); + set_colour(td::ColourRole::Ok, QStringLiteral("#FFD30F")); + set_colour(td::ColourRole::Good, QStringLiteral("#5EA10E")); + set_colour(td::ColourRole::VeryGood, QStringLiteral("#118f17")); set_colour(td::ColourRole::Text, QStringLiteral("#1D1D20")); } void InternalManager::set_dark_palette() { set_colour(td::ColourRole::Unknown, QStringLiteral("#2F2F32")); - set_colour(td::ColourRole::VeryBad, QStringLiteral("#7b1fa2")); - set_colour(td::ColourRole::Bad, QStringLiteral("#5e35b1")); - set_colour(td::ColourRole::Ok, QStringLiteral("#1976d2")); - set_colour(td::ColourRole::Good, QStringLiteral("#0097a7")); - set_colour(td::ColourRole::VeryGood, QStringLiteral("#4caf50")); + set_colour(td::ColourRole::VeryBad, QStringLiteral("#C43F31")); + set_colour(td::ColourRole::Bad, QStringLiteral("#DB9837")); + set_colour(td::ColourRole::Ok, QStringLiteral("#F0C400")); + set_colour(td::ColourRole::Good, QStringLiteral("#608A22")); + set_colour(td::ColourRole::VeryGood, QStringLiteral("#1F8023")); set_colour(td::ColourRole::Text, QStringLiteral("#CACBCE")); } diff --git a/src/gui/diaryeditor.cpp b/src/gui/diaryeditor.cpp index 25d86d6..644f979 100644 --- a/src/gui/diaryeditor.cpp +++ b/src/gui/diaryeditor.cpp @@ -20,6 +20,7 @@ #include "../core/diaryholder.h" #include "../util/custommessageboxes.h" #include "../util/misc.h" +#include "mainwindow.h" #include "ui_diaryeditor.h" DiaryEditor::DiaryEditor(QDate const &date, QWidget *parent) : QWidget(parent), ui(new Ui::DiaryEditor) @@ -27,9 +28,10 @@ DiaryEditor::DiaryEditor(QDate const &date, QWidget *parent) : QWidget(parent), ui->setupUi(this); ui->alert_text->setText(""); ui->alert_text->update(); + setup_buttons(); current_month_offset = 0; - last_selected_day = 0; + current_date = date; last_entry_snapshot = td::Entry{false, td::Rating::Unknown, "", 0}; // Ctrl S to save the diary. @@ -47,17 +49,12 @@ DiaryEditor::DiaryEditor(QDate const &date, QWidget *parent) : QWidget(parent), connect(ui->prev_month, &QPushButton::clicked, this, &DiaryEditor::prev_month, Qt::QueuedConnection); // Info pane actions. - connect( - ui->update_button, &QPushButton::clicked, this, [&]() { update_day(false); }, Qt::QueuedConnection); + connect(MainWindow::instance(), &MainWindow::sig_update_diary, this, &DiaryEditor::update_day); + connect(ui->update_button, &QPushButton::clicked, this, &DiaryEditor::update_day, Qt::QueuedConnection); connect(ui->delete_button, &QPushButton::clicked, this, &DiaryEditor::delete_day, Qt::QueuedConnection); connect(ui->reset_button, &QPushButton::clicked, this, &DiaryEditor::reset_day, Qt::QueuedConnection); - connect(InternalManager::instance(), &InternalManager::update_theme, this, &DiaryEditor::update_theme, - Qt::QueuedConnection); - update_theme(); - // Render current month. - auto current_date = date; change_month(current_date); // The diary editor DOES NOT USE internal_diary_changed. It implements its own change detection system!!! @@ -69,103 +66,116 @@ DiaryEditor::~DiaryEditor() delete save_shortcut; } -void DiaryEditor::update_theme() -{ - // When this function is run in the constructor, no buttons should exist yet. - emit sig_re_render_buttons( - td::CalendarButtonData{std::nullopt, std::nullopt, std::nullopt, std::nullopt, std::nullopt}); -} - -DiaryCalendarButton *DiaryEditor::create_button(const td::CalendarButtonData &&d) +void DiaryEditor::setup_buttons() { - auto ptr = new DiaryCalendarButton(d); - - connect(this, &DiaryEditor::sig_re_render_buttons, ptr, &DiaryCalendarButton::re_render, Qt::QueuedConnection); - connect(ptr, &DiaryCalendarButton::sig_clicked, this, &DiaryEditor::date_clicked, Qt::QueuedConnection); - - return ptr; + for (int row = 0; row < 6; ++row) { + for (int col = 0; col < 7; ++col) { + auto ptr = new DiaryCalendarButton(td::CalendarButtonData{std::optional(-1), std::optional(false), + std::optional(td::Rating::Unknown), std::optional(false), std::optional(false)}); + connect(ptr, &DiaryCalendarButton::sig_clicked, this, &DiaryEditor::date_clicked, Qt::QueuedConnection); + ui->dates->addWidget(ptr, row, col, 1, 1, Qt::AlignCenter); + } + } } -// Note for future me and any other readers: -// There is probably some way to make this function more readable but really this was a write once and never touch again -// thing because of how hard it is to keep track of all the changing variables. -void DiaryEditor::render_month(QDate const &date, std::optional const &opt) +void DiaryEditor::render_month(std::optional const &opt) { - // Note that the YearMap iterator actually contains a month map which holds all the days of the month. auto irl_current_day = QDate::currentDate(); + int counter = 1; - // Render spacers for first row padding. - for (int i = 0; i < current_month_offset; ++i) - ui->dates->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum), 0, i, 1, 1); - - int days_added = 0; - int row = 1; - int current_row_length = 0; + if (!opt) { + // Render the first row. + for (int day = 0; day < 7; ++day) { + auto button = qobject_cast(ui->dates->itemAtPosition(0, day)->widget()); - // Render rest of first row. - for (int i = current_month_offset; i < 7; ++i, ++days_added) { - // Render the day if it has a corresponding entry. - // There are 2 entirely separate flows here simply because there are 2 checks required to see if the entry is - // present. I could use goto but that's kind of messy and harder to keep track of compared to plain old copy - // pasting. - - auto current = irl_current_day == QDate(date.year(), date.month(), i - current_month_offset + 1); - - if (opt) { - auto const &monthmap = (*opt)->second; - auto const &entry_iter = monthmap.find(i - current_month_offset + 1); - - if (entry_iter != monthmap.end()) { - auto const &[important, rating, dummy, d2] = entry_iter->second; + if (day < current_month_offset) { + button->setVisible(false); + } + else { + auto current_cond = irl_current_day == QDate(current_date.year(), current_date.month(), counter); + button->render(td::CalendarButtonData{std::optional(counter++), std::optional(false), + std::optional(td::Rating::Unknown), std::optional(false), std::optional(current_cond)}); + button->setVisible(true); + } + } - auto ptr = create_button(td::CalendarButtonData{std::optional(i - current_month_offset + 1), - std::optional(important), std::optional(rating), std::optional(false), std::optional(current)}); - ui->dates->addWidget(ptr, 0, i, 1, 1, Qt::AlignCenter); - continue; + // Render the rest of the rows. + for (int row = 1; row < 6; ++row) { + for (int col = 0; col < 7; ++col) { + auto button = qobject_cast(ui->dates->itemAtPosition(row, col)->widget()); + + if (counter > current_date.daysInMonth()) { + button->setVisible(false); + } + else { + auto current_cond = irl_current_day == QDate(current_date.year(), current_date.month(), counter); + button->render(td::CalendarButtonData{std::optional(counter++), std::optional(false), + std::optional(td::Rating::Unknown), std::optional(false), std::optional(current_cond)}); + button->setVisible(true); + } } } - auto ptr = create_button(td::CalendarButtonData{std::optional(i - current_month_offset + 1), - std::optional(false), std::optional(td::Rating::Unknown), std::optional(false), std::optional(current)}); - ui->dates->addWidget(ptr, 0, i, 1, 1, Qt::AlignCenter); + return; } - // Render rest of month. - for (int i = days_added; i < date.daysInMonth(); ++i, ++current_row_length) { - if (7 == current_row_length) { - ++row; - current_row_length = 0; - } + auto const &monthmap = (*opt)->second; - // 2 passes required here as well which means 2 kind of same declarations. + // Render the first row. + for (int day = 0; day < 7; ++day) { + auto button = qobject_cast(ui->dates->itemAtPosition(0, day)->widget()); - auto current = irl_current_day == QDate(date.year(), date.month(), i + 1); - - if (opt) { - auto const &monthmap = (*opt)->second; - auto const &entry_iter = monthmap.find(i + 1); + if (day < current_month_offset) { + button->setVisible(false); + } + else { + auto const &entry_iter = monthmap.find(counter); + auto current_cond = irl_current_day == QDate(current_date.year(), current_date.month(), counter); - if (entry_iter != monthmap.end()) { + if (entry_iter == monthmap.end()) { + button->render(td::CalendarButtonData{std::optional(counter++), std::optional(false), + std::optional(td::Rating::Unknown), std::optional(false), std::optional(current_cond)}); + } + else { auto const &[important, rating, dummy, d2] = entry_iter->second; - auto ptr = create_button(td::CalendarButtonData{std::optional(i + 1), std::optional(important), - std::optional(rating), std::optional(false), std::optional(current)}); - ui->dates->addWidget(ptr, row, current_row_length, 1, 1, Qt::AlignCenter); - continue; + button->render(td::CalendarButtonData{std::optional(counter++), std::optional(important), + std::optional(rating), std::optional(false), std::optional(current_cond)}); } - } - auto ptr = create_button(td::CalendarButtonData{std::optional(i + 1), std::optional(false), - std::optional(td::Rating::Unknown), std::optional(false), std::optional(current)}); - ui->dates->addWidget(ptr, row, current_row_length, 1, 1, Qt::AlignCenter); + button->setVisible(true); + } } - // Fill in last row with spacers if necessary. There is a vertical spacer beneath the whole grid of buttons to push - // them up so they don't expand downwards. - while (current_row_length < 7) - ui->dates->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum), row, current_row_length++, 1, 1); + // Render the rest of the rows. + for (int row = 1; row < 6; ++row) { + for (int col = 0; col < 7; ++col) { + auto button = qobject_cast(ui->dates->itemAtPosition(row, col)->widget()); - qDebug() << "Rendered month editor (first day of month):" << date; + if (counter > current_date.daysInMonth()) { + button->setVisible(false); + } + else { + auto const &entry_iter = monthmap.find(counter); + auto current_cond = irl_current_day == QDate(current_date.year(), current_date.month(), counter); + + if (entry_iter == monthmap.end()) { + button->render(td::CalendarButtonData{std::optional(counter++), std::optional(false), + std::optional(td::Rating::Unknown), std::optional(false), std::optional(current_cond)}); + } + else { + auto const &[important, rating, dummy, d2] = entry_iter->second; + + button->render(td::CalendarButtonData{std::optional(counter++), std::optional(important), + std::optional(rating), std::optional(false), std::optional(current_cond)}); + } + + button->setVisible(true); + } + } + } + + qDebug() << "Rendered month for current date:" << current_date; } // Returns true if equal, false if not equal. @@ -183,20 +193,13 @@ void DiaryEditor::change_month(QDate const &date) if (QMessageBox::Cancel == res) return; - if (QMessageBox::Save == res) - update_day(true); - - // Remove everything from current grid. - QLayoutItem *child; - while ((child = ui->dates->takeAt(0)) != 0) { - delete child->widget(); - delete child; - } + if (QMessageBox::Save == res && !update_day()) + return; + current_date = date; QDate const first_day(date.year(), date.month(), 1); // dayOfWeek() returns a number from 1 to 7. current_month_offset = first_day.dayOfWeek() - 1; - last_selected_day = date.day(); // Set the calendar widget UI (not the info pane). ui->month_dropdown->blockSignals(true); @@ -209,15 +212,16 @@ void DiaryEditor::change_month(QDate const &date) ui->year_edit->blockSignals(false); // Render current month. - render_month(first_day, DiaryHolder::instance()->get_monthmap(date)); + render_month(DiaryHolder::instance()->get_monthmap(date)); - // Render current day. + // Render current day with selection outline. + // This is not done within the render_month function since not just the rendering has to be done. td::CalendarButtonData const d{ std::optional(date.day()), std::nullopt, std::nullopt, std::optional(true), std::nullopt}; render_day(d, true); + qDebug() << "Changed month in editor and broadcasting update_data:" << date; emit InternalManager::instance()->update_data(date); - qDebug() << "Changed month in editor and broadcasted update_data:" << date; }; if (!compare_snapshots()) @@ -232,28 +236,28 @@ void DiaryEditor::render_day(td::CalendarButtonData const &d, bool const set_inf int const x = (*d.day + current_month_offset - 1) % 7; int const y = static_cast((*d.day + current_month_offset - 1) / 7); - auto const &button = qobject_cast(ui->dates->itemAtPosition(y, x)->widget()); - button->re_render(d); + qobject_cast(ui->dates->itemAtPosition(y, x)->widget())->render(d); - if (set_info_pane) { - auto const &new_date = QDate(ui->year_edit->date().year(), ui->month_dropdown->currentIndex() + 1, *d.day); - auto const &opt = DiaryHolder::instance()->get_entry(new_date); + if (!set_info_pane) + return; - if (opt) { - last_entry_snapshot = (*opt)->second; - update_info_pane(new_date, (*opt)->second); - } - else { - auto default_entry = td::Entry{false, td::Rating::Unknown, "", 0}; - last_entry_snapshot = default_entry; - update_info_pane(new_date, default_entry); - } + auto const &new_date = QDate(current_date.year(), current_date.month(), *d.day); + auto const &opt = DiaryHolder::instance()->get_entry(new_date); + + if (opt) { + last_entry_snapshot = (*opt)->second; + update_info_pane(new_date, (*opt)->second); + } + else { + auto default_entry = td::Entry{false, td::Rating::Unknown, "", 0}; + last_entry_snapshot = default_entry; + update_info_pane(new_date, default_entry); } } void DiaryEditor::next_month() { - QDate &&next = ui->year_edit->date().addMonths(1); + QDate &&next = current_date.addMonths(1); next.setDate(next.year(), next.month(), 1); if (next.isValid()) change_month(next); @@ -261,7 +265,7 @@ void DiaryEditor::next_month() void DiaryEditor::prev_month() { - QDate &&prev = ui->year_edit->date().addMonths(-1); + QDate &&prev = current_date.addMonths(-1); prev.setDate(prev.year(), prev.month(), 1); if (prev.isValid()) change_month(prev); @@ -285,18 +289,18 @@ void DiaryEditor::date_clicked(int const day) ui->alert_text->update(); // Don't respond to spam clicks on same button. - if (day == last_selected_day) + if (day == current_date.day()) return; auto cb = [this, day](int const res) { if (QMessageBox::Cancel == res) return; - if (QMessageBox::Yes == res) - update_day(true); // Suppress entry saved message so it doesn't appear on new date. + if (QMessageBox::Yes == res && !update_day(false)) + return; td::CalendarButtonData const old{ - std::optional(last_selected_day), std::nullopt, std::nullopt, std::optional(false), std::nullopt}; + std::optional(current_date.day()), std::nullopt, std::nullopt, std::optional(false), std::nullopt}; td::CalendarButtonData const n{ std::optional(day), std::nullopt, std::nullopt, std::optional(true), std::nullopt}; // Remove selected border from old calendar button. @@ -304,7 +308,7 @@ void DiaryEditor::date_clicked(int const day) // Add selected border to new calendar button. render_day(n, true); - last_selected_day = day; + current_date = QDate(current_date.year(), current_date.month(), day); }; if (!compare_snapshots()) @@ -341,6 +345,7 @@ void DiaryEditor::update_info_pane(QDate const &date, td::Entry const &entry) ui->rating_dropdown->setCurrentIndex(static_cast(entry.rating)); ui->special_box->setChecked(entry.important); ui->entry_edit->setPlainText(entry.message.data()); + // ui->entry_edit->setPlainText("PLACEHOLDER"); ui->rating_dropdown->blockSignals(false); ui->special_box->blockSignals(false); @@ -352,26 +357,27 @@ void DiaryEditor::update_info_pane(QDate const &date, td::Entry const &entry) // The suppress_error parameter stops the save error box from popping up. // This is useful when locking the diary as typically the user is AFK. // The app shouldn't get stuck on the save error dialog as then it wouldn't be able to lock itself properly. -void DiaryEditor::update_day(bool const suppress_error) +bool DiaryEditor::update_day(bool const suppress_error) { AppBusyLock lock; // Add the entry to the in memory map. - auto const &new_date = - QDate(ui->year_edit->date().year(), ui->month_dropdown->currentIndex() + 1, last_selected_day); td::Entry const e{ui->special_box->isChecked(), static_cast(ui->rating_dropdown->currentIndex()), ui->entry_edit->toPlainText().toStdString(), QDateTime::currentSecsSinceEpoch()}; - DiaryHolder::instance()->create_entry(new_date, e); + DiaryHolder::instance()->create_entry(current_date, e); // Actually try and save the diary. - if (!DiaryHolder::instance()->save() && suppress_error) - return cmb::display_local_diary_save_error(this); + if (!DiaryHolder::instance()->save() && suppress_error) { + cmb::display_local_diary_save_error(this); + return false; + } - td::CalendarButtonData const d{std::optional(last_selected_day), std::optional(ui->special_box->isChecked()), - std::optional(static_cast(ui->rating_dropdown->currentIndex())), std::nullopt, std::nullopt}; + td::CalendarButtonData const d{std::optional(current_date.day()), std::optional(ui->special_box->isChecked()), + std::optional(static_cast(ui->rating_dropdown->currentIndex())), std::optional(true), std::nullopt}; // This updates the day button in the calendar widget. render_day(d, false); + last_entry_snapshot = e; // The last edited field is the only one that needs updating in this instance. QDateTime last_edited; @@ -379,13 +385,14 @@ void DiaryEditor::update_day(bool const suppress_error) // Thanks stackoverflow ;) ui->last_edited->setText("Last edited " + last_edited.toString("dd MMM ''yy 'at' h:mm ap")); ui->last_edited->setToolTip( - last_edited.toString("dddd MMMM d%1 yyyy 'at' h:mm:ss ap").arg(misc::get_day_suffix(new_date.day()))); + last_edited.toString("dddd MMMM d%1 yyyy 'at' h:mm:ss ap").arg(misc::get_day_suffix(current_date.day()))); ui->last_edited->update(); ui->alert_text->setText("Updated entry."); ui->alert_text->update(); - InternalManager::instance()->update_data(new_date); - qDebug() << "Updated entry and broadcasted update_data:" << new_date; + InternalManager::instance()->update_data(current_date); + qDebug() << "Updated entry and broadcasted update_data:" << current_date; + return true; } void DiaryEditor::delete_day() @@ -397,9 +404,7 @@ void DiaryEditor::delete_day() AppBusyLock lock; // Remove the entry from the in memory map. - auto const &new_date = - QDate(ui->year_edit->date().year(), ui->month_dropdown->currentIndex() + 1, last_selected_day); - DiaryHolder::instance()->delete_entry(new_date); + DiaryHolder::instance()->delete_entry(current_date); // Actually try and save the diary. if (!DiaryHolder::instance()->save()) @@ -408,14 +413,15 @@ void DiaryEditor::delete_day() ui->alert_text->setText("Deleted entry."); ui->alert_text->update(); - update_info_pane(new_date, td::Entry{false, td::Rating::Unknown, "", 0}); - - td::CalendarButtonData const d{std::optional(last_selected_day), std::optional(false), - std::optional(static_cast(td::Rating::Unknown)), std::nullopt, std::nullopt}; - render_day(d, false); + render_day(td::CalendarButtonData{std::optional(current_date.day()), std::optional(false), + std::optional(td::Rating::Unknown), std::optional(true), std::nullopt}, + false); + auto empty = td::Entry{false, td::Rating::Unknown, "", 0}; + update_info_pane(current_date, empty); + last_entry_snapshot = empty; - InternalManager::instance()->update_data(new_date); - qDebug() << "Deleted entry and broadcasted update_data:" << new_date; + InternalManager::instance()->update_data(current_date); + qDebug() << "Deleted entry and broadcasted update_data:" << current_date; }; // Shift click bypasses confirmation dialog. diff --git a/src/gui/diaryeditor.h b/src/gui/diaryeditor.h index 34af02c..581daa5 100644 --- a/src/gui/diaryeditor.h +++ b/src/gui/diaryeditor.h @@ -33,25 +33,20 @@ class DiaryEditor; class DiaryEditor : public QWidget { Q_OBJECT -signals: - void sig_re_render_buttons(td::CalendarButtonData const &data); - void sig_re_render(QDate const &date, bool const ignore_month_check); - public: explicit DiaryEditor(QDate const &date, QWidget *parent = nullptr); ~DiaryEditor(); + QDate current_date; int current_month_offset; - int last_selected_day; QShortcut *save_shortcut; // Saves the state of the entry when it was first loaded. Used to decide if the save prompt needs showing. td::Entry last_entry_snapshot; public slots: - void update_theme(); - // Calendar widget. - void render_month(QDate const &date, std::optional const &iter); + void setup_buttons(); + void render_month(std::optional const &iter); void change_month(QDate const &date); void render_day(td::CalendarButtonData const &d, bool const set_info_pane); void next_month(); @@ -62,14 +57,13 @@ public slots: // Info pane. void update_info_pane(QDate const &date, td::Entry const &entry); - void update_day(bool const suppress_error); + bool update_day(bool const suppress_error = false); void delete_day(); void reset_day(); private: Ui::DiaryEditor *ui; - DiaryCalendarButton *create_button(td::CalendarButtonData const &&d); bool compare_snapshots(); }; diff --git a/src/gui/diaryeditor.ui b/src/gui/diaryeditor.ui index 23fe493..435c789 100644 --- a/src/gui/diaryeditor.ui +++ b/src/gui/diaryeditor.ui @@ -58,148 +58,16 @@ - - 0 - 20 10 - - - - Message for this entry. - - - Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - - - - - Rating - - - - - - - Entry - - - - - - - 0 - - - 0 - - - - - Whether or not to mark this entry with a star. - - - Important? - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - 0 - - - - - - 120 - 0 - - - - Determines the colour associated with this entry. - - - - None - - - - - Very bad - - - - - Bad - - - - - OK - - - - - Good - - - - - Very good - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - 15 - - - 15 - - 15 - - - 0 + 8 @@ -267,6 +135,66 @@ + + + + Whether or not to mark this entry with a star. + + + Important? + + + + + + + Entry + + + + + + + + 120 + 0 + + + + Determines the colour associated with this entry. + + + + None + + + + + Very bad + + + + + Bad + + + + + OK + + + + + Good + + + + + Very good + + + + @@ -279,17 +207,28 @@ + + + + Message for this entry. + + + Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextEditable|Qt::TextEditorInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Rating + + + - - 0 - - - 0 - - + 10 @@ -316,22 +255,6 @@ - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 20 - - - - @@ -772,8 +695,6 @@ month_dropdown year_edit next_month - rating_dropdown - special_box entry_edit update_button delete_button diff --git a/src/gui/diaryentryviewer.cpp b/src/gui/diaryentryviewer.cpp index ef85463..d602f26 100644 --- a/src/gui/diaryentryviewer.cpp +++ b/src/gui/diaryentryviewer.cpp @@ -64,7 +64,6 @@ DiaryEntryViewer::DiaryEntryViewer(QWidget *parent) : QWidget(parent), ui(new Ui Qt::QueuedConnection); connect(InternalManager::instance(), &InternalManager::update_theme, this, &DiaryEntryViewer::update_theme, Qt::QueuedConnection); - update_theme(); // current_date is initialised by &InternalManager::change_month signal. } @@ -122,6 +121,11 @@ void DiaryEntryViewer::change_month(QDate const &date) .arg(generate_base64_icon(i.first, rating, important), last_edited.toString("dddd MMMM d%1 yyyy 'at' h:mm:ss ap").arg(misc::get_day_suffix(i.first)), misc::sanitise_html(misc::trim(copy)))); + // html.append( + // QString(SINGLE_ROW) + // .arg(generate_base64_icon(i.first, rating, important), + // last_edited.toString("dddd MMMM d%1 yyyy 'at' h:mm:ss + // ap").arg(misc::get_day_suffix(i.first)), "PLACEHOLDER")); html.append(HR_ROW); ++row_counter; @@ -202,8 +206,8 @@ QPixmap DiaryEntryViewer::generate_background(td::Rating const rating) QPainter p(&pixmap); p.setRenderHint(QPainter::Antialiasing); - if (InternalManager::instance()->get_theme() == td::Theme::Light) - p.setOpacity(0.8); + // if (InternalManager::instance()->get_theme() == td::Theme::Light) + // p.setOpacity(0.8); p.setPen(Qt::transparent); p.setBrush(QBrush(colour)); diff --git a/src/gui/diarypixels.cpp b/src/gui/diarypixels.cpp index 4d5228e..a35a84f 100644 --- a/src/gui/diarypixels.cpp +++ b/src/gui/diarypixels.cpp @@ -29,13 +29,13 @@ int const LABEL_SIZE = 36; DiaryPixels::DiaryPixels(QWidget *parent) : QWidget(parent), ui(new Ui::DiaryPixels) { ui->setupUi(this); + setup_grid(); ui->year_edit->setDate(QDate::currentDate()); connect(InternalManager::instance(), &InternalManager::update_data, this, &DiaryPixels::render_grid, Qt::QueuedConnection); - connect(ui->render_button, &QPushButton::clicked, this, &DiaryPixels::render_button_clicked, Qt::QueuedConnection); + connect(ui->year_edit, &QDateEdit::dateChanged, this, &DiaryPixels::render_grid, Qt::QueuedConnection); connect(ui->export_img_button, &QPushButton::clicked, this, &DiaryPixels::export_image, Qt::QueuedConnection); - // current_date is initialised by &InternalManager::change_month signal. } @@ -84,34 +84,12 @@ void DiaryPixels::render_button_clicked() render_grid(ui->year_edit->date()); } -void DiaryPixels::render_grid(QDate const &new_date) +void DiaryPixels::setup_grid() { - // Remove everything from current grid. - QLayoutItem *child; - while ((child = ui->grid->takeAt(0)) != 0) { - delete child->widget(); - delete child; - } - - current_date = new_date; - auto const &opt = DiaryHolder::instance()->get_yearmap(current_date); - - // Set new grid. - if (!opt) { - auto label = new QLabel("It seems there are no entries yet for this year...", this); - auto f = label->font(); - f.setPointSize(11); - label->setFont(f); - - return ui->grid->addWidget(label, 0, 0, 1, 1, Qt::AlignCenter); - } - - auto &&tmp_date = QDate::currentDate(); - auto const year = current_date.year(); auto const size = calculate_size(); - for (int month = 0; month < 12; ++month) { - auto label = new QLabel(QString(MONTH_LETTERS[month]), this); + for (int month = 1; month < 13; ++month) { + auto label = new QLabel(QString(MONTH_LETTERS[month - 1]), this); QFont f = label->font(); f.setPointSize(14); f.setBold(true); @@ -119,51 +97,84 @@ void DiaryPixels::render_grid(QDate const &new_date) label->setFixedHeight(LABEL_SIZE); label->setFixedWidth(LABEL_SIZE); label->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); - ui->grid->addWidget(label, month, 0); + ui->grid->addWidget(label, month - 1, 0); - int days = QDate(current_date.year(), month + 1, 1).daysInMonth(); + for (int day = 1; day < 32; ++day) { + auto ptr = new DiaryPixelLabel(td::Rating::Unknown, false, month, day, size, this); + connect(this, &DiaryPixels::sig_changed_size, ptr, &DiaryPixelLabel::resize, Qt::QueuedConnection); - // This block runs if the month doesn't exist at all. - auto const &monthmap = (*opt)->second; - auto const &iter = monthmap.find(month + 1 /* Month is index 1 based */); - if (iter == monthmap.end()) { - for (int day = 0; day < days; ++day) { - tmp_date.setDate(year, month + 1, day + 1); + ui->grid->addWidget(ptr, month - 1, day); + } + } - auto ptr = new DiaryPixelLabel(td::Rating::Unknown, false, tmp_date, size, this); - connect(this, &DiaryPixels::sig_changed_size, ptr, &DiaryPixelLabel::resize, Qt::QueuedConnection); + qDebug() << "Rendered pixel grid."; +} - ui->grid->addWidget( - ptr, month, day + 1 /* +1 here because of the month label added at the start of each row */); - } +void DiaryPixels::render_grid(QDate const &new_date) +{ + current_date = new_date; + ui->year_edit->blockSignals(true); + ui->year_edit->setDate(new_date); + ui->year_edit->blockSignals(false); + auto const &opt = DiaryHolder::instance()->get_yearmap(current_date); - continue; - } + for (int month = 1; month < 13; ++month) { + int days = QDate(current_date.year(), month, 1).daysInMonth(); - // This code runs if some/all dates in a month exist. - for (int day = 0; day < days; ++day) { - auto const &entrymap = iter->second; - auto const &iter2 = entrymap.find(day + 1 /* day is index 1 based */); + auto placeholder = [this, month, days]() { + for (int day = 1; day < 32; ++day) { + auto pixel = qobject_cast(ui->grid->itemAtPosition(month - 1, day)->widget()); - tmp_date.setDate(year, month + 1, day + 1); - if (iter2 == entrymap.end()) { - auto ptr = new DiaryPixelLabel(td::Rating::Unknown, false, tmp_date, size, this); - connect(this, &DiaryPixels::sig_changed_size, ptr, &DiaryPixelLabel::resize, Qt::QueuedConnection); + if (day > days) + pixel->setVisible(false); + else + pixel->setVisible(true); - ui->grid->addWidget(ptr, month, day + 1); + pixel->rating = td::Rating::Unknown; + pixel->special = false; + pixel->update(); } - else { - auto const &[important, rating, dummy, d2] = iter2->second; + }; - auto ptr = new DiaryPixelLabel(rating, important, tmp_date, size, this); - connect(this, &DiaryPixels::sig_changed_size, ptr, &DiaryPixelLabel::resize, Qt::QueuedConnection); + if (opt) { + auto const &monthmap = (*opt)->second; + auto const &iter = monthmap.find(month); - ui->grid->addWidget(ptr, month, day + 1); + if (iter == monthmap.end()) { + placeholder(); } + else { + auto const &entrymap = iter->second; + + for (int day = 1; day < 32; ++day) { + auto pixel = qobject_cast(ui->grid->itemAtPosition(month - 1, day)->widget()); + auto const &iter2 = entrymap.find(day); + + if (day > days) + pixel->setVisible(false); + else + pixel->setVisible(true); + + if (iter2 == entrymap.end()) { + pixel->rating = td::Rating::Unknown; + pixel->special = false; + } + else { + auto const &[important, rating, dummy, d2] = iter2->second; + pixel->rating = rating; + pixel->special = important; + } + + pixel->update(); + } + } + } + else { + placeholder(); } } - qDebug() << "Rendered pixels grid" << current_date; + qDebug() << "Updated pixels grid" << current_date; } void DiaryPixels::export_image() diff --git a/src/gui/diarypixels.h b/src/gui/diarypixels.h index 23a4eb9..e565603 100644 --- a/src/gui/diarypixels.h +++ b/src/gui/diarypixels.h @@ -39,6 +39,7 @@ class DiaryPixels : public QWidget { ~DiaryPixels(); void resizeEvent(QResizeEvent *); + void setup_grid(); int calculate_size(); QDate current_date; diff --git a/src/gui/diarypixels.ui b/src/gui/diarypixels.ui index 8e6535a..f596de0 100644 --- a/src/gui/diarypixels.ui +++ b/src/gui/diarypixels.ui @@ -64,6 +64,19 @@ 0 + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -79,20 +92,7 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - + Export the diary pixel grid. @@ -102,19 +102,6 @@ - - - - Re-render the pixel grid. - - - Render - - - true - - - @@ -128,7 +115,7 @@ - + Whether or not to add the current year as text above the exported image. @@ -144,7 +131,6 @@ year_edit - render_button export_img_button diff --git a/src/gui/mainmenu.ui b/src/gui/mainmenu.ui index fe5d3f5..2185aab 100644 --- a/src/gui/mainmenu.ui +++ b/src/gui/mainmenu.ui @@ -20,43 +20,121 @@ Form - - 0 - - - + + Qt::Vertical - - QSizePolicy::Fixed - 20 - 9 + 40 - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 30 - + + + + 0 - + + + + + 0 + 0 + + + + + 150 + 150 + + + + + 1 + 1 + + + + + + + :/linux_icons/scalable/theoreticaldiary.svg + + + true + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 0 + + + 10 + + + + + Welcome back to + + + + + + + + 36 + + + + <b>Theoretical Diary</b> + + + + + + + Version placeholder + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - + + Qt::Vertical @@ -68,11 +146,114 @@ - + + + + 8 + + + + + + 100 + 0 + + + + Open the settings menu. + + + Settings + + + + + + + + 100 + 0 + + + + Exit the application. + + + Quit + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + 0 + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 16 + + + + <b>Open diary</b> + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + @@ -143,8 +324,8 @@ 0 - - 6 + + 8 @@ -215,214 +396,8 @@ - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 16 - - - - <b>Open diary</b> - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - - - - 100 - 0 - - - - Open the settings menu. - - - Settings - - - - - - - - 100 - 0 - - - - Exit the application. - - - Quit - - - - - - - - - - - 0 - 0 - - - - - - - - 0 - 0 - - - - - 150 - 150 - - - - - 1 - 1 - - - - - - - :/linux_icons/scalable/theoreticaldiary.svg - - - true - - - - - - - 0 - - - 10 - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 0 - - - - - - - - - 36 - - - - <b>Theoretical Diary</b> - - - - - - - Version placeholder - - - - - - - Qt::Vertical - - - QSizePolicy::Expanding - - - - 20 - 0 - - - - - - - - Welcome back to - - - - - - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - @@ -441,8 +416,6 @@ decrypt_button new_button import_button - options_button - quit_button diff --git a/src/gui/mainwindow.cpp b/src/gui/mainwindow.cpp index 5a31456..070fd87 100644 --- a/src/gui/mainwindow.cpp +++ b/src/gui/mainwindow.cpp @@ -209,9 +209,7 @@ void MainWindow::lock_diary() return; } - emit sig_update_diary(); - if (InternalManager::instance()->internal_diary_changed) - DiaryHolder::instance()->save(); // Ignore any errors. + emit sig_update_diary(true); qDebug() << "Locking diary."; exit_diary_to_main_menu(true); diff --git a/src/gui/mainwindow.h b/src/gui/mainwindow.h index 02781f0..0163bf6 100644 --- a/src/gui/mainwindow.h +++ b/src/gui/mainwindow.h @@ -31,7 +31,7 @@ class MainWindow : public QMainWindow { Q_OBJECT signals: - void sig_update_diary(); + void sig_update_diary(bool const); public: explicit MainWindow(QWidget *parent = nullptr); diff --git a/src/gui/optionsmenu.ui b/src/gui/optionsmenu.ui index 03a20b1..aa656e2 100644 --- a/src/gui/optionsmenu.ui +++ b/src/gui/optionsmenu.ui @@ -64,7 +64,7 @@ 0 - 10 + 8 diff --git a/src/util/diarycalendarbutton.h b/src/util/diarycalendarbutton.h index bfec597..3760097 100644 --- a/src/util/diarycalendarbutton.h +++ b/src/util/diarycalendarbutton.h @@ -49,8 +49,6 @@ class DiaryCalendarButton : public QAbstractButton { setFixedSize(QSize(override::SIZE, override::SIZE)); data = d; mouse_down = false; - - update(); } ~DiaryCalendarButton() {} @@ -59,8 +57,11 @@ class DiaryCalendarButton : public QAbstractButton { bool mouse_down; public slots: - void re_render(td::CalendarButtonData const &d) + void render(td::CalendarButtonData const &d) { + if (d.day) + data.day = d.day; + if (d.important) data.important = d.important; @@ -70,6 +71,9 @@ public slots: if (d.selected) data.selected = d.selected; + if (d.current_day) + data.current_day = d.current_day; + update(); } @@ -135,8 +139,8 @@ public slots: path.addRoundedRect( QRect(topleft_offset, topleft_offset, adjusted_size, adjusted_size), ROUNDNESS, ROUNDNESS); - if (InternalManager::instance()->get_theme() == td::Theme::Light) - p.setOpacity(0.8); + // if (InternalManager::instance()->get_theme() == td::Theme::Light) + // p.setOpacity(0.8); // Set background color. QColor color = misc::rating_to_colour(*data.rating); diff --git a/src/util/diarycomparisonlabel.h b/src/util/diarycomparisonlabel.h index 8929045..07def02 100644 --- a/src/util/diarycomparisonlabel.h +++ b/src/util/diarycomparisonlabel.h @@ -96,8 +96,8 @@ class DiaryComparisonLabel : public QLabel { QPainter p(&bkg); p.setRenderHint(QPainter::Antialiasing); - if (InternalManager::instance()->get_theme() == td::Theme::Light) - p.setOpacity(0.8); + // if (InternalManager::instance()->get_theme() == td::Theme::Light) + // p.setOpacity(0.8); p.setPen(bkg_color); p.setBrush(QBrush(bkg_color)); diff --git a/src/util/diarypixellabel.h b/src/util/diarypixellabel.h index c9ffc88..0ad4caf 100644 --- a/src/util/diarypixellabel.h +++ b/src/util/diarypixellabel.h @@ -24,12 +24,17 @@ #include "../core/internalmanager.h" #include "misc.h" +namespace override { +static char const *MONTHS[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", + "October", "November", "December"}; +} + class DiaryPixelLabel : public QLabel { Q_OBJECT public: explicit DiaryPixelLabel( - td::Rating const r, bool const s, QDate const &date, int const size, QWidget *parent = nullptr) + td::Rating const r, bool const s, int const month, int const day, int const size, QWidget *parent = nullptr) : QLabel(parent) { special = s; @@ -38,8 +43,8 @@ class DiaryPixelLabel : public QLabel { setFixedHeight(size); setFixedWidth(size); - setToolTip(QString("%1 %2%3").arg( - date.toString("MMMM"), QString::number(date.day()), misc::get_day_suffix(date.day()))); + setToolTip( + QString("%1 %2%3").arg(override::MONTHS[month - 1], QString::number(day), misc::get_day_suffix(day))); } ~DiaryPixelLabel() {} @@ -92,8 +97,8 @@ public slots: QPainter p(&bkg); p.setRenderHint(QPainter::Antialiasing); - if (InternalManager::instance()->get_theme() == td::Theme::Light) - p.setOpacity(0.8); + // if (InternalManager::instance()->get_theme() == td::Theme::Light) + // p.setOpacity(0.8); p.setPen(bkg_colour); p.setBrush(QBrush(bkg_colour)); diff --git a/src/util/misc.cpp b/src/util/misc.cpp index c2c7795..e17afd7 100644 --- a/src/util/misc.cpp +++ b/src/util/misc.cpp @@ -131,10 +131,10 @@ td::Theme rating_to_theme(const td::Rating rating) case td::Rating::VeryBad: case td::Rating::Bad: case td::Rating::Ok: - return td::Theme::Light; case td::Rating::Good: - case td::Rating::VeryGood: return td::Theme::Dark; + case td::Rating::VeryGood: + return td::Theme::Light; } // This can never happen, it's only here to shut down the compiler warning. diff --git a/text/VERSION.txt b/text/VERSION.txt index 53c4a94..bc4abe8 100644 --- a/text/VERSION.txt +++ b/text/VERSION.txt @@ -1 +1 @@ -2.3.67 +2.3.8