diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5ab7ea9..42a9577 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,7 @@ jobs: - name: qmake and nmake run: | - echo $(git rev-parse --short "$GITHUB_SHA") > text\\REVISION.txt + echo $(git rev-parse --short "${{github.sha}}") > text\\REVISION.txt type text\\REVISION.txt qmake theoreticaldiary.pro CONFIG+=release set CL=/MP diff --git a/images/readme/editor.png b/images/readme/editor.png index 791e0f3..0ec5176 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 0b692e9..4a77981 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 da51507..1f59495 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 e0863c6..db7636b 100644 Binary files a/images/readme/pixels.png and b/images/readme/pixels.png differ diff --git a/images/readme/settings.png b/images/readme/settings.png index 220f391..4cb8af7 100644 Binary files a/images/readme/settings.png and b/images/readme/settings.png differ diff --git a/images/readme/statistics.png b/images/readme/statistics.png index 19fe523..5f65456 100644 Binary files a/images/readme/statistics.png and b/images/readme/statistics.png differ diff --git a/images/themes/dark/eye_off.svg b/images/themes/dark/eye_off.svg index 74f33ec..396cb2a 100644 --- a/images/themes/dark/eye_off.svg +++ b/images/themes/dark/eye_off.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/themes/dark/eye_on.svg b/images/themes/dark/eye_on.svg index eaf9346..ca40f72 100644 --- a/images/themes/dark/eye_on.svg +++ b/images/themes/dark/eye_on.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/themes/dark/star.svg b/images/themes/dark/star.svg index 4e6ed3a..ee43c24 100644 --- a/images/themes/dark/star.svg +++ b/images/themes/dark/star.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/themes/light/eye_off.svg b/images/themes/light/eye_off.svg index 396cb2a..74f33ec 100644 --- a/images/themes/light/eye_off.svg +++ b/images/themes/light/eye_off.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/themes/light/eye_on.svg b/images/themes/light/eye_on.svg index ca40f72..eaf9346 100644 --- a/images/themes/light/eye_on.svg +++ b/images/themes/light/eye_on.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/themes/light/star.svg b/images/themes/light/star.svg index ee43c24..4e6ed3a 100644 --- a/images/themes/light/star.svg +++ b/images/themes/light/star.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/src/core/googlewrapper.cpp b/src/core/googlewrapper.cpp index a0378a8..1cc8e90 100644 --- a/src/core/googlewrapper.cpp +++ b/src/core/googlewrapper.cpp @@ -25,7 +25,8 @@ char const *CLIENT_ID = "71530390003-2fr89p1c0unpd1n169munqajeepnhdco.apps.googleusercontent.com"; char const *CLIENT_SECRET = "zuyjH1Cd_8pL4Q-OFNLjNCJ7"; -char const *SCOPE = "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive.appdata"; +char const *SCOPE = "https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive.appdata " + "https://www.googleapis.com/auth/drive.file"; char const *REPLY_CONTENT = "

Authorization flow completed. Feel free to close " "this window.

"; @@ -303,7 +304,7 @@ std::pair GoogleWrapper::get_file_ids(QByteArray const &data) } for (auto const &file : json["files"]) { - if ("drive#file" == file["kind"] && "application/octet-stream" == file["mimeType"]) { + if ("drive#file" == file["kind"]) { if ("diary.dat" == file["name"]) { primary_backup_id = QString::fromStdString(file["id"]); } diff --git a/src/core/internalmanager.cpp b/src/core/internalmanager.cpp index b7a4027..8698371 100644 --- a/src/core/internalmanager.cpp +++ b/src/core/internalmanager.cpp @@ -61,14 +61,25 @@ void InternalManager::init_settings(const bool force_reset) settings->setValue("lock_timeout", static_cast(300000 /* 5 minutes */)); } -td::Theme InternalManager::get_theme() +td::Theme InternalManager::get_theme(bool const opposite) { - return static_cast(settings->value("theme").toInt()); + if (opposite) { + return static_cast(settings->value("theme").toInt()) == td::Theme::Dark ? td::Theme::Light + : td::Theme::Dark; + } + else { + return static_cast(settings->value("theme").toInt()); + } } -QString InternalManager::get_theme_str() +QString InternalManager::get_theme_str(bool const opposite) { - return QString(td::Theme::Light == get_theme() ? "light" : "dark"); + if (opposite) { + return td::Theme::Light == get_theme() ? "dark" : "light"; + } + else { + return td::Theme::Light == get_theme() ? "light" : "dark"; + } } QString InternalManager::data_location() @@ -104,16 +115,15 @@ void InternalManager::end_busy_mode(int const line, std::string const &func, std void InternalManager::start_update_theme() { QPixmapCache::clear(); - state_color_palette = StateColorPalette(); if (get_theme() == td::Theme::Dark) { - state_color_palette.initDefaultPaletteDark(); + set_dark_palette(); auto s = new DarkStyle; QApplication::setPalette(s->standardPalette()); QApplication::setStyle(s); } else { - state_color_palette.initDefaultPaletteLight(); + set_light_palette(); auto s = new LightStyle; QApplication::setPalette(s->standardPalette()); QApplication::setStyle(s); @@ -121,3 +131,25 @@ void InternalManager::start_update_theme() emit 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::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::Text, QStringLiteral("#CACBCE")); +} diff --git a/src/core/internalmanager.h b/src/core/internalmanager.h index 19fd440..5452cd0 100644 --- a/src/core/internalmanager.h +++ b/src/core/internalmanager.h @@ -24,7 +24,6 @@ #include #include -#include "../gui/styles/statecolorpalette.h" #include "../util/eventfilters.h" #include "asyncfuture.h" #include "json.hpp" @@ -127,6 +126,22 @@ enum class Window { Main, Editor, Options }; enum class LinkingResponse { Fail, ScopeMismatch, OK }; using NRO = AsyncFuture::Observable; + +struct CalendarButtonData { + std::optional day; + std::optional important; + std::optional rating; + std::optional selected; + std::optional current_day; +}; + +struct DiaryEntryIconData { + std::optional day; + std::optional rating; + std::optional important; +}; + +enum class ColourRole { Text, Unknown, VeryBad, Bad, Ok, Good, VeryGood }; } // namespace td // The reason why this class exists is to redirect #include statements away from theoreticaldiary.h @@ -149,18 +164,30 @@ class InternalManager : public QObject { ~InternalManager(); static InternalManager *instance(); - QString get_theme_str(); - td::Theme get_theme(); + QString get_theme_str(bool const opposite = false); + td::Theme get_theme(bool const opposite = false); QString data_location(); void start_busy_mode(int const line, std::string const &func, std::string const &file); void end_busy_mode(int const line, std::string const &func, std::string const &file); void init_settings(bool const force_reset); void start_update_theme(); + void set_dark_palette(); + void set_light_palette(); + + inline void set_colour(td::ColourRole role, const QColor &colour) + { + colourmap[static_cast(role)] = colour; + } + + inline QColor colour(td::ColourRole role) const + { + return colourmap.value(static_cast(role)); + } + QHash colourmap; QSettings *settings; InactiveFilter *inactive_filter; BusyFilter busy_filter; - StateColorPalette state_color_palette; bool app_busy; bool internal_diary_changed; bool diary_file_changed; diff --git a/src/gui/calendarbutton.cpp b/src/gui/calendarbutton.cpp deleted file mode 100644 index 30a2205..0000000 --- a/src/gui/calendarbutton.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * This file is part of Theoretical Diary. - * Copyright (C) 2022 someretical - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "calendarbutton.h" -#include "diaryeditor.h" - -CalendarButton::CalendarButton(td::CalendarButtonData const &d) : QPushButton(qobject_cast(*d.parent)) -{ - data = d; - - setAutoDefault(true); - setCursor(QCursor(Qt::PointingHandCursor)); - setText(QString::number(*d.day)); - - QFont f = font(); - f.setPointSize(16); - setFont(f); - - update(); - - // Apply new themes if requested - connect(*d.parent, &DiaryEditor::sig_re_render_buttons, this, &CalendarButton::re_render, Qt::QueuedConnection); - - // Link click event through here to pass day variable through. - connect(this, &CalendarButton::clicked, this, &CalendarButton::clicked_on, Qt::QueuedConnection); - connect(this, &CalendarButton::sig_clicked, *d.parent, &DiaryEditor::date_clicked, Qt::QueuedConnection); - - re_render(d); -} - -CalendarButton::~CalendarButton() {} - -// Update the the following properties of the button: -// - Background colour -// - Icon -// - Whether it is selected or not -void CalendarButton::re_render(td::CalendarButtonData const &d) -{ - // // Set stylesheet (determines colours). - // QString stylesheet((*data.parent)->base_stylesheet); - - // // Set background star if necessary. - // // If the provided 'd' object does not have the 'important' property set, use the 'important' property from - // 'data' - // // instead. If the provided 'd' object DOES contain an 'important' property, update the 'important' property - // of - // // 'data'. - // data.important = std::optional(d.important.value_or(*data.important)); - // data.rating = std::optional(d.rating.value_or(*data.rating)); - - // if (*data.important) { - // switch (*data.rating) { - // case td::Rating::Unknown: - // // Fall through - // case td::Rating::VeryBad: - // // Fall through - // case td::Rating::Bad: - // // Fall through - // case td::Rating::Ok: - // stylesheet.append((*data.parent)->white_star); - // break; - // case td::Rating::Good: - // // Fall through - // case td::Rating::VeryGood: - // stylesheet.append((*data.parent)->black_star); - // break; - // } - // } - - // // Set colour scheme. - // auto const r = d.rating.value_or(*data.rating); - // data.rating = std::optional(r); - // stylesheet.append(*(((*data.parent)->rating_stylesheets)[static_cast(r)])); - - // // Give border if selected. - // data.selected = std::optional(d.selected.value_or(*data.selected)); - // if (*data.selected) { - // stylesheet.append((*data.parent)->selected_stylesheet); - // } - - // setStylesheet\(stylesheet); -} - -void CalendarButton::clicked_on() -{ - emit sig_clicked(*data.day); -} diff --git a/src/gui/calendarbutton.h b/src/gui/calendarbutton.h deleted file mode 100644 index b9cf11a..0000000 --- a/src/gui/calendarbutton.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of Theoretical Diary. - * Copyright (C) 2022 someretical - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef CALENDARBUTTON_H -#define CALENDARBUTTON_H - -class DiaryEditor; - -#include -#include - -#include "../core/internalmanager.h" - -namespace td { -struct CalendarButtonData { - std::optional day; - std::optional parent; - std::optional important; - std::optional rating; - std::optional selected; -}; -} // namespace td - -class CalendarButton : public QPushButton { - Q_OBJECT - -signals: - void sig_clicked(int const day); - -public: - explicit CalendarButton(td::CalendarButtonData const &d); - ~CalendarButton(); - - td::CalendarButtonData data; - -public slots: - void clicked_on(); - void re_render(td::CalendarButtonData const &d); -}; - -#endif // CALENDARBUTTON_H diff --git a/src/gui/diaryeditor.cpp b/src/gui/diaryeditor.cpp index e73decb..22bd995 100644 --- a/src/gui/diaryeditor.cpp +++ b/src/gui/diaryeditor.cpp @@ -28,13 +28,6 @@ DiaryEditor::DiaryEditor(QDate const &date, QWidget *parent) : QWidget(parent), ui->alert_text->setText(""); ui->alert_text->update(); - // These will be filled when update_theme is called. - base_stylesheet = QString(); - selected_stylesheet = QString(); - white_star = QString(); - black_star = QString(); - rating_stylesheets = std::vector>(); - current_month_offset = 0; last_selected_day = 0; @@ -85,48 +78,19 @@ DiaryEditor::~DiaryEditor() void DiaryEditor::update_theme() { - // auto const &theme = InternalManager::instance()->get_theme_str(); - - // QFile file(QString(":/%1/diaryeditor.qss").arg(theme)); - // file.open(QIODevice::ReadOnly); - // // setStylesheet\(file.readAll()); - // file.close(); - - // file.setFileName(QString(":/%1/theoretical_calendar/base.qss").arg(theme)); - // file.open(QIODevice::ReadOnly); - // base_stylesheet = file.readAll(); - // file.close(); - - // file.setFileName(QString(":/%1/theoretical_calendar/selected.qss").arg(theme)); - // file.open(QIODevice::ReadOnly); - // selected_stylesheet = file.readAll(); - // file.close(); - - // file.setFileName(":/global/white_star.qss"); - // file.open(QIODevice::ReadOnly); - // white_star = file.readAll(); - // file.close(); - - // file.setFileName(":/global/black_star.qss"); - // file.open(QIODevice::ReadOnly); - // black_star = file.readAll(); - // file.close(); - - // for (auto &ss_ptr : rating_stylesheets) - // ss_ptr.reset(); - - // rating_stylesheets.clear(); - - // for (int i = 0; i < 6; ++i) { - // file.setFileName(QString(":/%1/theoretical_calendar/%2.qss").arg(theme, QString::number(i))); - // file.open(QIODevice::ReadOnly); - // rating_stylesheets.push_back(std::make_unique(file.readAll())); - // file.close(); - // } - - // // 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}); + // 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) +{ + 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; } // Note for future me and any other readers: @@ -135,6 +99,7 @@ void DiaryEditor::update_theme() void DiaryEditor::render_month(QDate const &date, 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(); // Render spacers for first row padding. for (int i = 0; i < current_month_offset; ++i) @@ -150,6 +115,9 @@ void DiaryEditor::render_month(QDate const &date, std::optionalsecond; auto const &entry_iter = monthmap.find(i - current_month_offset + 1); @@ -157,18 +125,16 @@ void DiaryEditor::render_month(QDate const &date, std::optionalsecond; - td::CalendarButtonData const d{std::optional(i - current_month_offset + 1), std::optional(this), - std::optional(important), std::optional(rating), std::optional(false)}; - - ui->dates->addWidget(new CalendarButton(d), 0, i, 1, 1, Qt::AlignCenter); + 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; } } - td::CalendarButtonData const d{std::optional(i - current_month_offset + 1), std::optional(this), - std::optional(false), std::optional(td::Rating::Unknown), std::optional(false)}; - - ui->dates->addWidget(new CalendarButton(d), 0, i, 1, 1, Qt::AlignCenter); + 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); } // Render rest of month. @@ -179,6 +145,9 @@ void DiaryEditor::render_month(QDate const &date, std::optionalsecond; auto const &entry_iter = monthmap.find(i + 1); @@ -186,18 +155,16 @@ void DiaryEditor::render_month(QDate const &date, std::optionalsecond; - td::CalendarButtonData const d{std::optional(i + 1), std::optional(this), std::optional(important), - std::optional(rating), std::optional(false)}; - - ui->dates->addWidget(new CalendarButton(d), row, current_row_length, 1, 1, Qt::AlignCenter); + 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; } } - td::CalendarButtonData const d{std::optional(i + 1), std::optional(this), std::optional(false), - std::optional(td::Rating::Unknown), std::optional(false)}; - - ui->dates->addWidget(new CalendarButton(d), row, current_row_length, 1, 1, Qt::AlignCenter); + 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); } // Fill in last row with spacers if necessary. There is a vertical spacer beneath the whole grid of buttons to push @@ -247,7 +214,7 @@ void DiaryEditor::change_month(QDate const &date, bool const suppress_confirm) // Render current day. td::CalendarButtonData const d{ - std::optional(date.day()), std::nullopt, std::nullopt, std::nullopt, std::optional(true)}; + std::optional(date.day()), std::nullopt, std::nullopt, std::optional(true), std::nullopt}; render_day(d, true); emit InternalManager::instance()->update_data(date); @@ -266,7 +233,7 @@ 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()); + auto const &button = qobject_cast(ui->dates->itemAtPosition(y, x)->widget()); button->re_render(d); if (set_info_pane) { @@ -322,9 +289,9 @@ void DiaryEditor::date_clicked(int const day) update_day(true); // Suppress entry saved message so it doesn't appear on new date. td::CalendarButtonData const old{ - std::optional(last_selected_day), std::nullopt, std::nullopt, std::nullopt, std::optional(false)}; + std::optional(last_selected_day), std::nullopt, std::nullopt, std::optional(false), std::nullopt}; td::CalendarButtonData const n{ - std::optional(day), std::nullopt, std::nullopt, std::nullopt, std::optional(true)}; + std::optional(day), std::nullopt, std::nullopt, std::optional(true), std::nullopt}; // Remove selected border from old calendar button. render_day(old, false); // Add selected border to new calendar button. @@ -391,9 +358,8 @@ void DiaryEditor::update_day(bool const suppress_error) if (!DiaryHolder::instance()->save() && suppress_error) return cmb::save_error(this, []() {}); - td::CalendarButtonData const d{std::optional(last_selected_day), std::nullopt, - std::optional(ui->special_box->isChecked()), - std::optional(static_cast(ui->rating_dropdown->currentIndex())), std::nullopt}; + 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}; // This updates the day button in the calendar widget. render_day(d, false); @@ -403,6 +369,8 @@ 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->update(); + ui->alert_text->setText("Updated entry."); + ui->alert_text->update(); // This updates the information in the other tabs. // The pixels tab should call end_busy_mode when it is done re rendering. @@ -432,8 +400,8 @@ void DiaryEditor::delete_day() update_info_pane(new_date, td::Entry{false, td::Rating::Unknown, "", 0}); - td::CalendarButtonData const d{std::optional(last_selected_day), std::nullopt, std::optional(false), - std::optional(static_cast(td::Rating::Unknown)), std::nullopt}; + 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); // This updates the information in the other tabs. diff --git a/src/gui/diaryeditor.h b/src/gui/diaryeditor.h index 6ee8869..b3ee124 100644 --- a/src/gui/diaryeditor.h +++ b/src/gui/diaryeditor.h @@ -23,7 +23,8 @@ #include #include -#include "calendarbutton.h" +#include "../core/internalmanager.h" +#include "../util/diarycalendarbutton.h" namespace Ui { class DiaryEditor; @@ -45,13 +46,6 @@ class DiaryEditor : public QWidget { QShortcut *save_shortcut; - // This is an array of 6 stylesheets. - std::vector> rating_stylesheets; - QString base_stylesheet; - QString selected_stylesheet; - QString white_star; - QString black_star; - public slots: void update_theme(); @@ -73,6 +67,8 @@ public slots: private: Ui::DiaryEditor *ui; + + DiaryCalendarButton *create_button(td::CalendarButtonData const &&d); }; #endif // DIARYEDITOR_H diff --git a/src/gui/diaryeditor.ui b/src/gui/diaryeditor.ui index cc0755f..7477a59 100644 --- a/src/gui/diaryeditor.ui +++ b/src/gui/diaryeditor.ui @@ -101,7 +101,7 @@ - 7 + 0 diff --git a/src/gui/diaryentryviewer.cpp b/src/gui/diaryentryviewer.cpp index 86d4e00..a1ebfd2 100644 --- a/src/gui/diaryentryviewer.cpp +++ b/src/gui/diaryentryviewer.cpp @@ -23,6 +23,29 @@ int const MAX_LINE_LEN = 110; int const DAY_LABEL_SIZE = 50; +int const SIZE = 50; + +const char *PLACEHOLDER_TEXT = R"( +

It seems there are no entries yet for this month...

+)"; + +char const *TABLE_START = ""; + +char const *SINGLE_ROW = R"( + + + + +)"; + +const QString HR_ROW(R"( + + + + +)"); + +char const *TABLE_END = "
%2

"; DiaryEntryViewer::DiaryEntryViewer(QWidget *parent) : QWidget(parent), ui(new Ui::DiaryEntryViewer) { @@ -45,13 +68,6 @@ DiaryEntryViewer::DiaryEntryViewer(QWidget *parent) : QWidget(parent), ui(new Ui Qt::QueuedConnection); update_theme(); - // Make scroll bar hit the bottom. - QTimer::singleShot(0, this, [&]() { - ui->scrollArea->widget()->adjustSize(); - ui->scrollArea->widget()->update(); - ui->scrollArea->verticalScrollBar()->triggerAction(QAbstractSlider::SliderToMaximum); - }); - // current_date is initialised by &InternalManager::change_month signal. } @@ -62,52 +78,11 @@ DiaryEntryViewer::~DiaryEntryViewer() void DiaryEntryViewer::update_theme() { - // auto const &theme = InternalManager::instance()->get_theme_str(); - - // QFile file(QString(":/%1/diary_entry_list/base.qss").arg(theme)); - // file.open(QIODevice::ReadOnly); - // // ui->scrollArea->setStyleSheet(file.readAll()); - // file.close(); - - // file.setFileName(QString(":/%1/diaryentryviewer.qss").arg(theme)); - // file.open(QIODevice::ReadOnly); - // // setStylesheet\(file.readAll()); - // file.close(); - - // file.setFileName(":/global/white_star.qss"); - // file.open(QIODevice::ReadOnly); - // white_star = file.readAll(); - // file.close(); - - // file.setFileName(":/global/black_star.qss"); - // file.open(QIODevice::ReadOnly); - // black_star = file.readAll(); - // file.close(); - - // for (auto &ss_ptr : rating_stylesheets) - // ss_ptr.reset(); - - // rating_stylesheets.clear(); - - // for (int i = 0; i < 6; ++i) { - // file.setFileName(QString(":/%1/diary_entry_list/%2.qss").arg(theme, QString::number(i))); - // file.open(QIODevice::ReadOnly); - // rating_stylesheets.push_back(std::make_unique(file.readAll())); - // file.close(); - // } - - // emit sig_update_labels(); + change_month(QDate::currentDate()); } void DiaryEntryViewer::change_month(QDate const &date) { - // Remove everything from current grid. - QLayoutItem *child; - while ((child = ui->entry_grid->takeAt(0)) != 0) { - delete child->widget(); - delete child; - } - // Update the selector UI. ui->month_dropdown->blockSignals(true); ui->year_edit->blockSignals(true); @@ -125,18 +100,12 @@ void DiaryEntryViewer::change_month(QDate const &date) ui->year_edit->blockSignals(false); auto const &opt = DiaryHolder::instance()->get_monthmap(date.isValid() ? date : current_date); - if (!opt) { - auto label = new QLabel("It seems there are no entries yet for this month...", this); - label->setAlignment(Qt::AlignCenter); - auto f = label->font(); - f.setPointSize(11); - label->setFont(f); - - current_date = date; - return ui->entry_grid->addWidget(label); - } + if (!opt) + return ui->entry_edit->setText(PLACEHOLDER_TEXT); - int row_counter = 0; + QString html(TABLE_START); + + auto row_counter = 0; for (auto const &i : (*opt)->second) { auto const &[important, rating, message, dummy] = i.second; @@ -144,26 +113,23 @@ void DiaryEntryViewer::change_month(QDate const &date) if (message.empty()) continue; - // Ideally, the message should have been trimmed when the entry itself was saved. However, that was not always - // the case so the message has to be trimmed here for backwards compatability. - auto msg_copy = message; - auto day = new DiaryEntryDayLabel(td::LabelData{this, i.first, rating, important}, this); - auto formatted_msg = new DiaryEntryDayMessage(misc::trim(msg_copy), this); - auto spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); + auto copy = message; + + // This is just about the most janky thing in this entire app. + html.append(QString(SINGLE_ROW) + .arg(generate_base64_icon(i.first, rating, important), misc::sanitise_html(misc::trim(copy)))); + html.append(HR_ROW); - ui->entry_grid->addWidget(day, row_counter, 0, 1, 1, Qt::AlignTop | Qt::AlignLeft); - ui->entry_grid->addWidget(formatted_msg, row_counter, 1, 1, 1, Qt::AlignVCenter | Qt::AlignLeft); - ui->entry_grid->addItem(spacer, row_counter++, 2); + ++row_counter; } if (0 == row_counter) { - auto label = new QLabel("It seems there are no entries yet for this month...", this); - label->setAlignment(Qt::AlignCenter); - auto f = label->font(); - f.setPointSize(11); - label->setFont(f); - - ui->entry_grid->addWidget(label); + return ui->entry_edit->setText(PLACEHOLDER_TEXT); + } + else { + html.chop(HR_ROW.size()); + html.append(TABLE_END); + ui->entry_edit->setText(html); } current_date = date; @@ -174,31 +140,15 @@ void DiaryEntryViewer::change_month(QDate const &date) void DiaryEntryViewer::next_month() { QDate const next = ui->year_edit->date().addMonths(1); - if (next.isValid()) { + if (next.isValid()) change_month(next); - - // Make scroll bar hit top. - QTimer::singleShot(0, this, [&]() { - ui->scrollArea->widget()->adjustSize(); - ui->scrollArea->widget()->update(); - ui->scrollArea->verticalScrollBar()->triggerAction(QAbstractSlider::SliderToMinimum); - }); - } } void DiaryEntryViewer::prev_month() { QDate const prev = ui->year_edit->date().addMonths(-1); - if (prev.isValid()) { + if (prev.isValid()) change_month(prev); - - // Make scroll bar hit bottom. - QTimer::singleShot(0, this, [&]() { - ui->scrollArea->widget()->adjustSize(); - ui->scrollArea->widget()->update(); - ui->scrollArea->verticalScrollBar()->triggerAction(QAbstractSlider::SliderToMaximum); - }); - } } void DiaryEntryViewer::month_changed(int) @@ -212,102 +162,110 @@ void DiaryEntryViewer::year_changed(QDate const &date) change_month(QDate(ui->year_edit->date().year(), ui->month_dropdown->currentIndex() + 1, 1)); } -/* - * DiaryEntryDayLabel class - */ -DiaryEntryDayLabel::DiaryEntryDayLabel(td::LabelData const &d, QWidget *parent) : QLabel(parent) +QByteArray DiaryEntryViewer::generate_base64_icon(int const day, td::Rating const rating, bool const important) { - data = d; - setText(QString::number(d.day)); - setFixedHeight(DAY_LABEL_SIZE); - setFixedWidth(DAY_LABEL_SIZE); - setAlignment(Qt::AlignCenter); + QPixmap pixmap(SIZE, SIZE); + pixmap.fill(Qt::transparent); + QPainter p(&pixmap); + p.setRenderHint(QPainter::Antialiasing); + p.drawPixmap(0, 0, generate_background(rating)); - QFont f = font(); - f.setPointSize(14); - f.setBold(true); - setFont(f); + if (important) + p.drawPixmap(0, 0, generate_star(rating)); - update(); + p.drawPixmap(0, 0, generate_text(day, rating)); - connect(InternalManager::instance(), &InternalManager::update_theme, this, &DiaryEntryDayLabel::update_theme, - Qt::QueuedConnection); - connect( - d.parent, &DiaryEntryViewer::sig_update_labels, this, &DiaryEntryDayLabel::update_theme, Qt::QueuedConnection); - update_theme(); -} + QByteArray barray; + QBuffer buf(&barray); + buf.open(QIODevice::WriteOnly); -DiaryEntryDayLabel::~DiaryEntryDayLabel() {} + pixmap.toImage().save(&buf, "PNG"); + return barray.toBase64(); +} -void DiaryEntryDayLabel::update_theme() +QPixmap DiaryEntryViewer::generate_background(td::Rating const rating) { - // // Set colour theme. - // QString stylesheet(*(data.parent->rating_stylesheets)[static_cast(data.rating)]); - - // // Set background star if necessary. - // if (data.special) { - // switch (data.rating) { - // case td::Rating::Unknown: - // // Fall through - // case td::Rating::VeryBad: - // // Fall through - // case td::Rating::Bad: - // // Fall through - // case td::Rating::Ok: - // stylesheet.append(data.parent->white_star); - // break; - // case td::Rating::Good: - // // Fall through - // case td::Rating::VeryGood: - // stylesheet.append(data.parent->black_star); - // break; - // } - // } - - // setStylesheet\(stylesheet); + QString key = QString("diaryentryicon:bkg:%1:%2") + .arg(QString::number(static_cast(rating)), + QString::number(static_cast(InternalManager::instance()->get_theme()))); + QPixmap pixmap; + + if (!QPixmapCache::find(key, pixmap)) { + pixmap = QPixmap(SIZE, SIZE); + pixmap.fill(Qt::transparent); + + QColor colour = misc::rating_to_colour(rating); + QPainter p(&pixmap); + p.setRenderHint(QPainter::Antialiasing); + + if (InternalManager::instance()->get_theme() == td::Theme::Light) + p.setOpacity(0.8); + + p.setPen(Qt::transparent); + p.setBrush(QBrush(colour)); + p.drawEllipse(0, 0, SIZE, SIZE); + + QPixmapCache::insert(key, pixmap); + } + + return pixmap; } -/* - * DiaryEntryDayMessage class - */ -DiaryEntryDayMessage::DiaryEntryDayMessage(std::string const &m, QWidget *parent) : QLabel(parent) +QPixmap DiaryEntryViewer::generate_star(td::Rating const rating) { - message = std::string(m); - expanded = false; + auto theme_str = misc::rating_to_theme(rating) == td::Theme::Dark ? "dark" : "light"; + QString key = QString("diaryentryicon:star:%1").arg(theme_str); + QPixmap pixmap; - // Set text. - setText(misc::get_trunc_first_line(m, MAX_LINE_LEN).data()); - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard); + if (!QPixmapCache::find(key, pixmap)) { + pixmap = QPixmap(SIZE, SIZE); + pixmap.fill(Qt::transparent); - QFont f = font(); - f.setPointSize(14); - setFont(f); + QPainter p(&pixmap); + p.setRenderHint(QPainter::Antialiasing); + p.setOpacity(0.3); - update(); + auto overlay = QIcon(QString(":/themes/%1/star.svg").arg(theme_str)).pixmap(SIZE * 0.8, SIZE * 0.8); - setCursor(QCursor(Qt::PointingHandCursor)); + // Draw overlay on the centre of the pixmap. + auto x = ((rect().bottomRight().x() - overlay.rect().bottomRight().x()) / 2); + // y is the same as x since it's a square. - connect(InternalManager::instance(), &InternalManager::update_theme, this, &DiaryEntryDayMessage::update_theme, - Qt::QueuedConnection); - update_theme(); -} + p.drawPixmap(x, x, overlay); -DiaryEntryDayMessage::~DiaryEntryDayMessage() {} + QPixmapCache::insert(key, pixmap); + } -void DiaryEntryDayMessage::update_theme() {} + return pixmap; +} -void DiaryEntryDayMessage::mouseDoubleClickEvent(QMouseEvent *event) +QPixmap DiaryEntryViewer::generate_text(int const day_, td::Rating const rating) { - if (event->button() != Qt::LeftButton) - return; + QString day = QString::number(day_); + auto theme = QString::number(static_cast(misc::rating_to_theme(rating))); + QString key = QString("diaryentryicon:text:%1:%2").arg(day, theme); + QPixmap pixmap; + + if (!QPixmapCache::find(key, pixmap)) { + pixmap = QPixmap(SIZE, SIZE); + pixmap.fill(Qt::transparent); + + QPainter p(&pixmap); + p.setRenderHint(QPainter::Antialiasing); - if (expanded) - setText(misc::get_trunc_first_line(message, MAX_LINE_LEN).data()); - else - setText(message.data()); + auto bold_font = QApplication::font(); + bold_font.setBold(true); + bold_font.setPointSize(16); + p.setFont(bold_font); - update(); + QRectF rect; + rect = p.boundingRect(pixmap.rect(), Qt::AlignCenter, day); + + p.setPen(misc::theme_to_text(misc::rating_to_theme(rating))); + p.drawText(rect, Qt::AlignCenter, day); + + QPixmapCache::insert(key, pixmap); + } - expanded = !expanded; + return pixmap; } diff --git a/src/gui/diaryentryviewer.h b/src/gui/diaryentryviewer.h index 41ae40e..3db0f86 100644 --- a/src/gui/diaryentryviewer.h +++ b/src/gui/diaryentryviewer.h @@ -28,16 +28,6 @@ namespace Ui { class DiaryEntryViewer; } -class DiaryEntryViewer; -namespace td { -struct LabelData { - DiaryEntryViewer *parent; - int day; - td::Rating rating; - bool special; -}; -} // namespace td - class DiaryEntryViewer : public QWidget { Q_OBJECT @@ -63,36 +53,11 @@ public slots: private: Ui::DiaryEntryViewer *ui; -}; - -class DiaryEntryDayLabel : public QLabel { - Q_OBJECT - -public: - explicit DiaryEntryDayLabel(td::LabelData const &d, QWidget *parent = nullptr); - ~DiaryEntryDayLabel(); - - td::LabelData data; - -public slots: - void update_theme(); -}; - -class DiaryEntryDayMessage : public QLabel { - Q_OBJECT - -public: - explicit DiaryEntryDayMessage(std::string const &m, QWidget *parent = nullptr); - ~DiaryEntryDayMessage(); - - std::string message; - bool expanded; - -public slots: - void update_theme(); -protected: - void mouseDoubleClickEvent(QMouseEvent *event); + QByteArray generate_base64_icon(int const day, td::Rating const rating, bool const important); + QPixmap generate_background(td::Rating const rating); + QPixmap generate_star(td::Rating const rating); + QPixmap generate_text(int const day_, td::Rating const rating); }; #endif // DIARYENTRYVIEWER_H diff --git a/src/gui/diaryentryviewer.ui b/src/gui/diaryentryviewer.ui index 560b239..068cd41 100644 --- a/src/gui/diaryentryviewer.ui +++ b/src/gui/diaryentryviewer.ui @@ -80,87 +80,6 @@ 30 - - - - - 0 - 0 - - - - true - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - 0 - 0 - 1218 - 545 - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Qt::Vertical - - - - 20 - 0 - - - - - - - - 15 - - - 15 - - - 15 - - - 15 - - - 30 - - - - - - - @@ -364,13 +283,19 @@ + + + + Qt::TextSelectableByMouse + + + - scrollArea prev_month month_dropdown year_edit diff --git a/src/gui/diarypixels.cpp b/src/gui/diarypixels.cpp index c0e9f89..332d3a6 100644 --- a/src/gui/diarypixels.cpp +++ b/src/gui/diarypixels.cpp @@ -21,7 +21,6 @@ #include "../util/custommessageboxes.h" #include "../util/diarypixellabel.h" #include "../util/misc.h" -#include "styles/statecolorpalette.h" #include "ui_diarypixels.h" char const *MONTH_LETTERS = "JFMAMJJASOND"; diff --git a/src/gui/diarystats.cpp b/src/gui/diarystats.cpp index 8954b11..743693e 100644 --- a/src/gui/diarystats.cpp +++ b/src/gui/diarystats.cpp @@ -18,13 +18,12 @@ #include "diarystats.h" #include "../core/diaryholder.h" +#include "../util/misc.h" #include "ui_diarystats.h" using namespace QtCharts; char const *ratings[] = {"Unknown", "Very bad", "Bad", "OK", "Good", "Very good"}; -QColor const rating_colours[] = {QColor(84, 110, 122, 51), QColor(123, 31, 162, 255), QColor(94, 53, 177, 255), - QColor(25, 118, 210, 255), QColor(0, 151, 167, 255), QColor(76, 175, 80, 255)}; qreal const angular_min = 1; // qreal const angular_max = 31; @@ -36,9 +35,6 @@ auto const light_background = QColor(230, 230, 230, 170); auto const dark_white = light_background.darker(); auto const light_black = dark_background.lighter(); -auto const almost_white = QColor(202, 203, 206); -auto const almost_black = QColor(29, 29, 32); - DiaryStats::DiaryStats(QWidget *parent) : QWidget(parent), ui(new Ui::DiaryStats) { ui->setupUi(this); @@ -188,8 +184,8 @@ void DiaryStats::render_pie_chart(std::vector const &rating_counts) // If there is no data for the current month, display an empty pie chart. pie_series->append(ratings[0], current_date.daysInMonth()); auto slice = pie_series->slices().at(0); - slice->setBrush(rating_colours[0]); - slice->setLabelColor(td::Theme::Dark == theme ? almost_white : almost_black); + slice->setBrush(InternalManager::instance()->colour(td::ColourRole::Unknown)); + slice->setLabelColor(InternalManager::instance()->colour(td::ColourRole::Text)); slice->setLabelVisible(); slice->setBorderWidth(4); slice->setBorderColor(td::Theme::Dark == theme ? light_black : dark_white); @@ -212,9 +208,9 @@ void DiaryStats::render_pie_chart(std::vector const &rating_counts) auto slice = pie_series->slices().at(pie_series->slices().size() - 1); slice->setBorderWidth(4); slice->setBorderColor(td::Theme::Dark == theme ? light_black : dark_white); - slice->setLabelColor(td::Theme::Dark == theme ? almost_white : almost_black); + slice->setLabelColor(InternalManager::instance()->colour(td::ColourRole::Text)); slice->setLabelVisible(); - slice->setBrush(rating_colours[static_cast(rating)]); + slice->setBrush(misc::rating_to_colour(rating)); } } @@ -236,7 +232,7 @@ void DiaryStats::render_polar_chart(std::optional const & auto angular_axis = new QValueAxis(); angular_axis->setTickCount(angular_max + 1); angular_axis->setLabelFormat("%d"); - angular_axis->setLabelsColor(td::Theme::Dark == theme ? almost_white : almost_black); + angular_axis->setLabelsColor(InternalManager::instance()->colour(td::ColourRole::Text)); angular_axis->setRange(angular_min, angular_max + 1); angular_axis->setGridLineColor(td::Theme::Dark == theme ? light_black : dark_white); chart->addAxis(angular_axis, QPolarChart::PolarOrientationAngular); @@ -266,7 +262,7 @@ void DiaryStats::render_polar_chart(std::optional const & area->setLowerSeries(lower); area->setUpperSeries(upper); area->setOpacity(0.75); - area->setColor(rating_colours[static_cast(rating)]); + area->setColor(misc::rating_to_colour(rating)); area->setBorderColor(QColor(Qt::transparent)); area->attachAxis(angular_axis); area->attachAxis(radial_axis); @@ -328,10 +324,10 @@ void DiaryStats::render_spline_chart(std::optional const x_axis->setGridLineColor(td::Theme::Dark == theme ? light_black : dark_white); x_axis->setLabelFormat("%d"); - x_axis->setLabelsColor(td::Theme::Dark == theme ? almost_white : almost_black); + x_axis->setLabelsColor(InternalManager::instance()->colour(td::ColourRole::Text)); x_axis->setLabelsVisible(); x_axis->setTitleText("Day"); - x_axis->setTitleBrush(QBrush(td::Theme::Dark == theme ? almost_white : almost_black)); + x_axis->setTitleBrush(QBrush(InternalManager::instance()->colour(td::ColourRole::Text))); auto y_axis = new QValueAxis(); chart->addAxis(y_axis, Qt::AlignLeft); @@ -339,17 +335,17 @@ void DiaryStats::render_spline_chart(std::optional const y_axis->setTickCount(5); y_axis->setGridLineColor(td::Theme::Dark == theme ? light_black : dark_white); y_axis->setLabelFormat("%d"); - y_axis->setLabelsColor(td::Theme::Dark == theme ? almost_white : almost_black); + y_axis->setLabelsColor(InternalManager::instance()->colour(td::ColourRole::Text)); y_axis->setLabelsVisible(); y_axis->setTitleText("Rating"); - y_axis->setTitleBrush(QBrush(td::Theme::Dark == theme ? almost_white : almost_black)); + y_axis->setTitleBrush(QBrush(InternalManager::instance()->colour(td::ColourRole::Text))); auto scatter_series = new QScatterSeries(); chart->addSeries(scatter_series); scatter_series->attachAxis(x_axis); scatter_series->attachAxis(y_axis); scatter_series->setMarkerSize(8); - scatter_series->setColor(td::Theme::Dark == theme ? almost_white : almost_black); + scatter_series->setColor(InternalManager::instance()->colour(td::ColourRole::Text)); scatter_series->setBorderColor(QColor(Qt::transparent)); if (opt) { @@ -358,7 +354,7 @@ void DiaryStats::render_spline_chart(std::optional const chart->addSeries(current_spline_series); current_spline_series->attachAxis(x_axis); current_spline_series->attachAxis(y_axis); - current_spline_series->setColor(rating_colours[3]); + current_spline_series->setColor(InternalManager::instance()->colour(td::ColourRole::Text)); for (auto const &[day, data] : (*opt)->second) { auto const &[important, rating, dummy, d2] = data; @@ -376,7 +372,7 @@ void DiaryStats::render_spline_chart(std::optional const chart->addSeries(current_spline_series); current_spline_series->attachAxis(x_axis); current_spline_series->attachAxis(y_axis); - current_spline_series->setColor(rating_colours[3]); + current_spline_series->setColor(InternalManager::instance()->colour(td::ColourRole::Text)); } else { ++prev_day; diff --git a/src/gui/styles/statecolorpalette.cpp b/src/gui/styles/statecolorpalette.cpp deleted file mode 100644 index 0cefc3c..0000000 --- a/src/gui/styles/statecolorpalette.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2021 KeePassXC Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 or (at your option) - * version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "statecolorpalette.h" - -StateColorPalette::StateColorPalette() {} - -void StateColorPalette::initDefaultPaletteLight() -{ - setColor(ColorRole::Error, QStringLiteral("#FF7D7D")); - setColor(ColorRole::Warning, QStringLiteral("#FFD30F")); - setColor(ColorRole::Info, QStringLiteral("#84D0E1")); - setColor(ColorRole::Incomplete, QStringLiteral("#FFD30F")); - - setColor(ColorRole::Unknown, QStringLiteral("#C9C9CF")); - setColor(ColorRole::VeryBad, QStringLiteral("#7b1fa2")); - setColor(ColorRole::Bad, QStringLiteral("#5e35b1")); - setColor(ColorRole::Ok, QStringLiteral("#1976d2")); - setColor(ColorRole::Good, QStringLiteral("#0097a7")); - setColor(ColorRole::VeryGood, QStringLiteral("#4caf50")); - - setColor(ColorRole::True, QStringLiteral("#5EA10E")); - setColor(ColorRole::False, QStringLiteral("#C43F31")); -} - -void StateColorPalette::initDefaultPaletteDark() -{ - setColor(ColorRole::Error, QStringLiteral("#802D2D")); - setColor(ColorRole::Warning, QStringLiteral("#73682E")); - setColor(ColorRole::Info, QStringLiteral("#207183")); - setColor(ColorRole::Incomplete, QStringLiteral("#665124")); - - setColor(ColorRole::Unknown, QStringLiteral("#2F2F32")); - setColor(ColorRole::VeryBad, QStringLiteral("#7b1fa2")); - setColor(ColorRole::Bad, QStringLiteral("#5e35b1")); - setColor(ColorRole::Ok, QStringLiteral("#1976d2")); - setColor(ColorRole::Good, QStringLiteral("#0097a7")); - setColor(ColorRole::VeryGood, QStringLiteral("#4caf50")); - - setColor(ColorRole::True, QStringLiteral("#608A22")); - setColor(ColorRole::False, QStringLiteral("#C43F31")); -} diff --git a/src/gui/styles/statecolorpalette.h b/src/gui/styles/statecolorpalette.h deleted file mode 100644 index 681c952..0000000 --- a/src/gui/styles/statecolorpalette.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2021 KeePassXC Team - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 or (at your option) - * version 3 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef KEEPASSXC_STATECOLORPALETTE_H -#define KEEPASSXC_STATECOLORPALETTE_H - -#include -#include -#include - -// TODO fix the really janky workaround keeping this class separate. -// Probably merge it into the internal manager class some time. - -/** - * Extended color palette for indicating custom widget states. - */ -class StateColorPalette { - Q_GADGET - -public: - StateColorPalette(); - - enum ColorRole { Error, Warning, Info, Incomplete, True, False, Unknown, VeryBad, Bad, Ok, Good, VeryGood }; - - inline void setColor(ColorRole role, const QColor &color) - { - m_colorMap[role] = color; - } - - inline QColor color(ColorRole role) const - { - return m_colorMap.value(role); - } - - void initDefaultPaletteLight(); - void initDefaultPaletteDark(); - -private: - QHash m_colorMap; -}; - -#endif // KEEPASSXC_STATECOLORPALETTE_H diff --git a/src/main.cpp b/src/main.cpp index 5008124..6706b43 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,7 +21,6 @@ #include "core/internalmanager.h" #include "core/theoreticaldiary.h" -#include "gui/calendarbutton.h" #include "gui/mainwindow.h" #include "o2requestor.h" #include "util/runguard.h" diff --git a/src/util/diarycalendarbutton.h b/src/util/diarycalendarbutton.h new file mode 100644 index 0000000..64b8e59 --- /dev/null +++ b/src/util/diarycalendarbutton.h @@ -0,0 +1,278 @@ +/* + * This file is part of Theoretical Diary. + * Copyright (C) 2022 someretical + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef DIARYCALENDARBUTTON_H +#define DIARYCALENDARBUTTON_H + +class DiaryEditor; + +#include +#include + +#include "../core/internalmanager.h" +#include "misc.h" + +static int const SIZE = 86; // Should be even. +static int const BORDER_WIDTH = 4; // Should be even. +static int const ROUNDNESS = 8; + +class DiaryCalendarButton : public QAbstractButton { + Q_OBJECT + +signals: + void sig_clicked(int const day); + +public: + DiaryCalendarButton(td::CalendarButtonData const &d, QWidget *p = nullptr) : QAbstractButton(p) + { + setText(QString::number(*d.day)); + setFixedSize(QSize(SIZE, SIZE)); + data = d; + mouse_down = false; + + repaint(); + } + + ~DiaryCalendarButton() {} + + td::CalendarButtonData data; + bool mouse_down; + +public slots: + void re_render(td::CalendarButtonData const &d) + { + if (d.important) + data.important = d.important; + + if (d.rating) + data.rating = d.rating; + + if (d.selected) + data.selected = d.selected; + + repaint(); + } + +protected: + void enterEvent(QEvent *) + { + repaint(); + } + + void leaveEvent(QEvent *) + { + repaint(); + } + + void mousePressEvent(QMouseEvent *) + { + mouse_down = true; + repaint(); + } + + void mouseReleaseEvent(QMouseEvent *e) + { + mouse_down = false; + + // Mouse move events are not broadcast when the mouse is held down. + if (rect().contains(e->pos())) + emit sig_clicked(*data.day); + + repaint(); + } + + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + p.drawPixmap(0, 0, generate_background()); + + if (*data.important) + p.drawPixmap(0, 0, generate_star()); + + p.drawPixmap(0, 0, generate_text()); + } + +private: + QPixmap generate_background() + { + QString key = QString("calendarbutton:bkg:%1:%2:%3") + .arg(QString::number(static_cast(*data.rating)), + QString::number(static_cast(InternalManager::instance()->get_theme())), + QString::number(get_state())); + QPixmap pixmap; + + if (!QPixmapCache::find(key, pixmap)) { + pixmap = QPixmap(SIZE, SIZE); + pixmap.fill(Qt::transparent); + + QPainter p(&pixmap); + p.setRenderHint(QPainter::Antialiasing); + + QPainterPath path; + auto topleft_offset = BORDER_WIDTH / 2; + auto adjusted_size = SIZE - BORDER_WIDTH; + 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); + + // Set background color. + QColor color = misc::rating_to_colour(*data.rating); + if (mouse_down) { + p.fillPath(path, QBrush(color.darker(120))); + } + // else if (underMouse()) { + // p.fillPath(path, QBrush(color.lighter(110))); + // } + else { + p.fillPath(path, QBrush(color)); + } + + // Set border color. + if (mouse_down || underMouse() || *data.selected) { + if (InternalManager::instance()->get_theme() == td::Theme::Light) { + p.strokePath(path, QPen(QBrush(color.lighter(110)), BORDER_WIDTH)); + } + else { + p.strokePath(path, QPen(QBrush(color.darker(130)), BORDER_WIDTH)); + } + } + else { + p.setCompositionMode(QPainter::CompositionMode_Clear); // This will actually erase. + p.strokePath(path, QPen(QBrush(Qt::transparent), BORDER_WIDTH)); + } + + QPixmapCache::insert(key, pixmap); + } + + return pixmap; + } + + QPixmap generate_text() + { + QString day = QString::number(*data.day); + QPixmap pixmap; + + if (*data.current_day) { + + pixmap = QPixmap(SIZE, SIZE); + pixmap.fill(Qt::transparent); + + QPainter p(&pixmap); + p.setRenderHint(QPainter::Antialiasing); + + auto bold_font = QApplication::font(); + bold_font.setBold(true); + bold_font.setItalic(true); + bold_font.setPointSize(16); + p.setFont(bold_font); + + QRectF rect; + rect = p.boundingRect(pixmap.rect(), Qt::AlignTop | Qt::AlignRight, day); + rect.translate(-12, 8); + + p.setPen(misc::theme_to_text(misc::rating_to_theme(*data.rating))); + p.drawText(rect, Qt::AlignTop | Qt::AlignRight, day); + + return pixmap; + } + + auto theme = QString::number(static_cast(misc::rating_to_theme(*data.rating))); + QString key = QString("calendarbutton:text:%1:%2").arg(day, theme); + + if (!QPixmapCache::find(key, pixmap)) { + pixmap = QPixmap(SIZE, SIZE); + pixmap.fill(Qt::transparent); + + QPainter p(&pixmap); + p.setRenderHint(QPainter::Antialiasing); + + auto bold_font = QApplication::font(); + bold_font.setBold(true); + bold_font.setPointSize(16); + QRectF rect; + + p.setFont(bold_font); + rect = p.boundingRect(pixmap.rect(), Qt::AlignTop | Qt::AlignRight, day); + rect.translate(-10, 8); + + p.setPen(misc::theme_to_text(misc::rating_to_theme(*data.rating))); + p.drawText(rect, Qt::AlignTop | Qt::AlignRight, day); + + QPixmapCache::insert(key, pixmap); + } + + return pixmap; + } + + QPixmap generate_star() + { + auto theme_str = misc::rating_to_theme(*data.rating) == td::Theme::Dark ? "dark" : "light"; + QString key = QString("calendarbutton:star:%1:%2").arg(theme_str, QString::number(get_state())); + QPixmap pixmap; + + if (!QPixmapCache::find(key, pixmap)) { + pixmap = QPixmap(SIZE, SIZE); + pixmap.fill(Qt::transparent); + + QPainter p(&pixmap); + p.setRenderHint(QPainter::Antialiasing); + + if (mouse_down) { + p.setOpacity(0.4); + } + else if (underMouse()) { + p.setOpacity(0.4); + } + else { + p.setOpacity(0.5); + } + + auto overlay = QIcon(QString(":/themes/%1/star.svg").arg(theme_str)).pixmap(SIZE * 0.8, SIZE * 0.8); + + // Draw overlay on the centre of the pixmap. + auto x = ((rect().bottomRight().x() - overlay.rect().bottomRight().x()) / 2); + // y is the same as x since it's a square. + + p.drawPixmap(x, x, overlay); + + QPixmapCache::insert(key, pixmap); + } + + return pixmap; + } + + int get_state() + { + // If the mouse is NOT hovering over and NOT clicking, state is 0. + // If the mouse IS hovering over but not clicking, state is 1. + // If the mouse IS hovering over AND clicking, state is 2. + + if (mouse_down) + return 2; + + if (underMouse() || *data.selected) + return 1; + + return 0; + } +}; + +#endif // DIARYCALENDARBUTTON_H diff --git a/src/util/diarycomparisonlabel.h b/src/util/diarycomparisonlabel.h index 32062a7..f590fc9 100644 --- a/src/util/diarycomparisonlabel.h +++ b/src/util/diarycomparisonlabel.h @@ -47,12 +47,13 @@ class DiaryComparisonLabel : public QLabel { QPixmap generate_pixmap() { if (special) { - auto theme_str = InternalManager::instance()->get_theme() == td::Theme::Light ? "light" : "dark"; + auto theme_str = InternalManager::instance()->get_theme_str(true); auto svg = QIcon(QString(":/themes/%1/star.svg").arg(theme_str)).pixmap(size()); QPixmap bkg(SIZE, SIZE); bkg.fill(Qt::transparent); QPainter p(&bkg); + p.setRenderHint(QPainter::Antialiasing); p.setOpacity(0.5); p.drawPixmap(0, 0, svg); return bkg; @@ -61,8 +62,9 @@ class DiaryComparisonLabel : public QLabel { QPixmap bkg(SIZE, SIZE); bkg.fill(Qt::transparent); - QColor bkg_color = misc::rating_to_color(rating); + QColor bkg_color = misc::rating_to_colour(rating); QPainter p(&bkg); + p.setRenderHint(QPainter::Antialiasing); if (InternalManager::instance()->get_theme() == td::Theme::Light) p.setOpacity(0.8); @@ -90,6 +92,7 @@ class DiaryComparisonLabel : public QLabel { } QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); p.drawPixmap(0, 0, pixmap); } }; diff --git a/src/util/diarypixellabel.h b/src/util/diarypixellabel.h index 22f9423..c9ffc88 100644 --- a/src/util/diarypixellabel.h +++ b/src/util/diarypixellabel.h @@ -70,11 +70,12 @@ public slots: } QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); p.drawPixmap(0, 0, pixmap); // Since starred days are supposed to be a lot less common, caching isn't done for them. if (special) { - auto theme_str = misc::rating_to_theme(rating) == td::Theme::Light ? "light" : "dark"; + auto theme_str = misc::rating_to_theme(rating) == td::Theme::Dark ? "dark" : "light"; QPixmap svg_overlay = QIcon(QString(":/themes/%1/star.svg").arg(theme_str)).pixmap(size_); p.setOpacity(0.5); @@ -87,14 +88,15 @@ public slots: { QPixmap bkg(size_.width(), size_.width()); bkg.fill(Qt::transparent); - QColor bkg_color = misc::rating_to_color(rating); + QColor bkg_colour = misc::rating_to_colour(rating); QPainter p(&bkg); + p.setRenderHint(QPainter::Antialiasing); if (InternalManager::instance()->get_theme() == td::Theme::Light) p.setOpacity(0.8); - p.setPen(bkg_color); - p.setBrush(QBrush(bkg_color)); + p.setPen(bkg_colour); + p.setBrush(QBrush(bkg_colour)); p.drawRoundedRect(0, 0, size_.width(), size_.width(), 5, 5); return bkg; diff --git a/src/util/misc.cpp b/src/util/misc.cpp index dfff3b1..fc92d84 100644 --- a/src/util/misc.cpp +++ b/src/util/misc.cpp @@ -18,7 +18,7 @@ #include -#include "../gui/styles/statecolorpalette.h" +#include "../core/internalmanager.h" #include "misc.h" namespace misc { @@ -80,13 +80,6 @@ void extend_top_line(std::string &top, long unsigned int const max_line_len) top.append(max_line_len - top.size(), ' '); } -QString get_danger_stylesheet() -{ - QFile file(QString(":/%1/dangerbutton.qss").arg(InternalManager::instance()->get_theme_str())); - file.open(QIODevice::ReadOnly); - return QString(file.readAll()); -} - void clear_message_boxes() { QWidget *w; @@ -103,33 +96,38 @@ void clear_message_boxes() } } -QColor rating_to_color(const td::Rating rating) +QColor rating_to_colour(const td::Rating rating) { - auto const &c = InternalManager::instance()->state_color_palette; + auto intman = InternalManager::instance(); switch (rating) { case td::Rating::Unknown: - return c.color(StateColorPalette::ColorRole::Unknown); + return intman->colour(td::ColourRole::Unknown); case td::Rating::VeryBad: - return c.color(StateColorPalette::ColorRole::VeryBad); + return intman->colour(td::ColourRole::VeryBad); case td::Rating::Bad: - return c.color(StateColorPalette::ColorRole::Bad); + return intman->colour(td::ColourRole::Bad); case td::Rating::Ok: - return c.color(StateColorPalette::ColorRole::Ok); + return intman->colour(td::ColourRole::Ok); case td::Rating::Good: - return c.color(StateColorPalette::ColorRole::Good); + return intman->colour(td::ColourRole::Good); case td::Rating::VeryGood: - return c.color(StateColorPalette::ColorRole::VeryGood); + return intman->colour(td::ColourRole::VeryGood); } // This can never happen, it's only here to shut down the compiler warning. - return c.color(StateColorPalette::ColorRole::Unknown); + return intman->colour(td::ColourRole::Unknown); } td::Theme rating_to_theme(const td::Rating rating) { switch (rating) { case td::Rating::Unknown: + if (InternalManager::instance()->get_theme() == td::Theme::Light) + return td::Theme::Dark; + else + return td::Theme::Light; + case td::Rating::VeryBad: case td::Rating::Bad: case td::Rating::Ok: @@ -142,4 +140,27 @@ td::Theme rating_to_theme(const td::Rating rating) // This can never happen, it's only here to shut down the compiler warning. return td::Theme::Dark; } + +static const auto light_text = QColor("#CACBCE"); +static const auto dark_text = QColor("#1D1D20"); + +QColor theme_to_text(const td::Theme theme) +{ + if (td::Theme::Light == theme) { + return light_text; + } + else { + return dark_text; + } +} + +QString sanitise_html(std::string const &str) +{ + return QString::fromStdString(str) + .replace("&", "&") + .replace("<", "<") + .replace(">", ">") + .replace("\n", "
"); +} + } // namespace misc diff --git a/src/util/misc.h b/src/util/misc.h index a77af72..2c09975 100644 --- a/src/util/misc.h +++ b/src/util/misc.h @@ -49,10 +49,11 @@ inline std::string &trim(std::string &s) } void extend_top_line(std::string &top, long unsigned int const max_line_len); -QString get_danger_stylesheet(); void clear_message_boxes(); -QColor rating_to_color(td::Rating const rating); +QColor rating_to_colour(td::Rating const rating); td::Theme rating_to_theme(const td::Rating rating); +QColor theme_to_text(const td::Theme theme); +QString sanitise_html(std::string const &str); } // namespace misc #endif // MISC_H diff --git a/src/util/passwordlineedit.cpp b/src/util/passwordlineedit.cpp deleted file mode 100644 index 36ccbc3..0000000 --- a/src/util/passwordlineedit.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of Theoretical Diary. - * Copyright (C) 2022 someretical - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -// The code in this file was adapted from https://stackoverflow.com/a/51194796. - -#include "passwordlineedit.h" -#include "../core/internalmanager.h" - -PasswordLineEdit::PasswordLineEdit(QWidget *parent) : QLineEdit(parent) -{ - setEchoMode(QLineEdit::Password); - - auto monospaced = QFontDatabase::systemFont(QFontDatabase::FixedFont); - monospaced.setLetterSpacing(QFont::PercentageSpacing, 110); - setFont(monospaced); - - QAction *action = addAction(QIcon(get_eye_icon(false)), QLineEdit::TrailingPosition); - button = qobject_cast(action->associatedWidgets().last()); - button->setCursor(QCursor(Qt::PointingHandCursor)); - connect(button, &QToolButton::pressed, this, &PasswordLineEdit::on_pressed, Qt::QueuedConnection); - connect(button, &QToolButton::released, this, &PasswordLineEdit::on_released, Qt::QueuedConnection); -} - -void PasswordLineEdit::on_pressed() -{ - QToolButton *button = qobject_cast(sender()); - button->setIcon(QIcon(get_eye_icon(true))); - setEchoMode(QLineEdit::Normal); -} - -void PasswordLineEdit::on_released() -{ - QToolButton *button = qobject_cast(sender()); - button->setIcon(QIcon(get_eye_icon(false))); - setEchoMode(QLineEdit::Password); -} - -QString PasswordLineEdit::get_eye_icon(bool const on) -{ - return QString(":/themes/%1/%2.svg").arg(InternalManager::instance()->get_theme_str(), on ? "eye_on" : "eye_off"); -} diff --git a/src/util/passwordlineedit.h b/src/util/passwordlineedit.h index bc6e1ad..dd5cb9d 100644 --- a/src/util/passwordlineedit.h +++ b/src/util/passwordlineedit.h @@ -23,18 +23,59 @@ #include +#include "../core/internalmanager.h" + +// The code in this file was adapted from https://stackoverflow.com/a/51194796. + class PasswordLineEdit : public QLineEdit { public: - PasswordLineEdit(QWidget *parent = nullptr); + PasswordLineEdit(QWidget *parent = nullptr) : QLineEdit(parent) + { + setEchoMode(QLineEdit::Password); + + auto monospaced = QFontDatabase::systemFont(QFontDatabase::FixedFont); + monospaced.setLetterSpacing(QFont::PercentageSpacing, 110); + setFont(monospaced); + + QAction *action = addAction(QIcon(get_eye_icon(false)), QLineEdit::TrailingPosition); + button = qobject_cast(action->associatedWidgets().last()); + button->setCursor(QCursor(Qt::PointingHandCursor)); + connect(button, &QToolButton::pressed, this, &PasswordLineEdit::on_pressed, Qt::QueuedConnection); + connect(button, &QToolButton::released, this, &PasswordLineEdit::on_released, Qt::QueuedConnection); + + connect(InternalManager::instance(), &InternalManager::update_theme, this, &PasswordLineEdit::update_theme, + Qt::QueuedConnection); + } + +public slots: + void update_theme() + { + button->setIcon(QIcon(get_eye_icon(true))); + } private slots: - void on_pressed(); - void on_released(); + void on_pressed() + { + QToolButton *button = qobject_cast(sender()); + button->setIcon(QIcon(get_eye_icon(true))); + setEchoMode(QLineEdit::Normal); + } + + void on_released() + { + QToolButton *button = qobject_cast(sender()); + button->setIcon(QIcon(get_eye_icon(false))); + setEchoMode(QLineEdit::Password); + } private: QToolButton *button; - QString get_eye_icon(bool const on); + QString get_eye_icon(bool const on) + { + return QString(":/themes/%1/%2.svg") + .arg(InternalManager::instance()->get_theme_str(true), on ? "eye_on" : "eye_off"); + } }; #endif // PASSWORDLINEEDIT_H diff --git a/styles/dark/darkstyle.qss b/styles/dark/darkstyle.qss index a9aef28..ee7502c 100644 --- a/styles/dark/darkstyle.qss +++ b/styles/dark/darkstyle.qss @@ -1,10 +1,8 @@ -DatabaseWidget:!active, GroupView:!active, -EntryPreviewWidget QLineEdit:!active, EntryPreviewWidget QTextEdit:!active { +GroupView:!active,QLineEdit:!active, QTextEdit:!active { background-color: #404042; } -DatabaseWidget:disabled, GroupView:disabled, -EntryPreviewWidget QLineEdit:disabled, EntryPreviewWidget QTextEdit:disabled { +GroupView:disabled, QLineEdit:disabled, QTextEdit:disabled { background-color: #424242; } @@ -26,3 +24,7 @@ QToolTip { QGroupBox { background-color: palette(light); } + +QTextEdit#entry_edit { + background-color: #39393C; +} diff --git a/styles/light/lightstyle.qss b/styles/light/lightstyle.qss index 5a8fe64..3818824 100644 --- a/styles/light/lightstyle.qss +++ b/styles/light/lightstyle.qss @@ -1,10 +1,8 @@ -DatabaseWidget:!active, GroupView:!active, -EntryPreviewWidget QLineEdit:!active, EntryPreviewWidget QTextEdit:!active { +GroupView:!active, QLineEdit:!active, QTextEdit:!active { background-color: #FCFCFC; } -DatabaseWidget:disabled, GroupView:disabled, -EntryPreviewWidget QLineEdit:disabled, EntryPreviewWidget QTextEdit:disabled { +GroupView:disabled, QLineEdit:disabled, QTextEdit:disabled { background-color: #EDEDED; } diff --git a/text/VERSION.txt b/text/VERSION.txt index 276cbf9..2bf1c1c 100644 --- a/text/VERSION.txt +++ b/text/VERSION.txt @@ -1 +1 @@ -2.3.0 +2.3.1 diff --git a/theoreticaldiary.pro b/theoreticaldiary.pro index 60e5c39..f2d9eb2 100644 --- a/theoreticaldiary.pro +++ b/theoreticaldiary.pro @@ -34,7 +34,6 @@ SOURCES += \ src/core/theoreticaldiary.cpp \ src/gui/aboutdialog.cpp \ src/gui/apiresponse.cpp \ - src/gui/calendarbutton.cpp \ src/gui/diaryeditor.cpp \ src/gui/diaryentryviewer.cpp \ src/gui/diarymenu.cpp \ @@ -48,13 +47,11 @@ SOURCES += \ src/gui/styles/base/phantomcolor.cpp \ src/gui/styles/dark/darkstyle.cpp \ src/gui/styles/light/lightstyle.cpp \ - src/gui/styles/statecolorpalette.cpp \ src/main.cpp \ src/util/alertlabel.cpp \ src/util/encryptor.cpp \ src/util/eventfilters.cpp \ src/util/misc.cpp \ - src/util/passwordlineedit.cpp \ src/util/runguard.cpp \ src/util/zipper.cpp @@ -65,7 +62,6 @@ HEADERS += \ src/core/theoreticaldiary.h \ src/gui/aboutdialog.h \ src/gui/apiresponse.h \ - src/gui/calendarbutton.h \ src/gui/diaryeditor.h \ src/gui/diaryentryviewer.h \ src/gui/diarymenu.h \ @@ -79,9 +75,9 @@ HEADERS += \ src/gui/styles/base/phantomcolor.h \ src/gui/styles/dark/darkstyle.h \ src/gui/styles/light/lightstyle.h \ - src/gui/styles/statecolorpalette.h \ src/util/alertlabel.h \ src/util/custommessageboxes.h \ + src/util/diarycalendarbutton.h \ src/util/diarycomparisonlabel.h \ src/util/diarypixellabel.h \ src/util/encryptor.h \