diff --git a/.gitignore b/.gitignore
index 0ff8f19..77e4c99 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,6 +4,7 @@ build-*
*/build-*
release/
debug/
+protobuf/
*.exe
*.dll
*.so
@@ -12,6 +13,7 @@ debug/
*.o
*.obj
*.app
+translations/*.qm
moc_*.cpp
ui_*.h
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 821a0f3..b8ae4ca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,9 +13,14 @@ find_package(Qt6 COMPONENTS Widgets Core Gui Sql REQUIRED)
add_subdirectory(scripts)
add_subdirectory(database)
+add_subdirectory(ui/profile-window)
add_subdirectory(ui/main-window)
add_subdirectory(ui/authorization-windows)
add_subdirectory(ui/note-widget)
+add_subdirectory(ui/style-manager)
+add_subdirectory(ui/settings-window)
+add_subdirectory(ui/analytics-window)
+add_subdirectory(ui/language-manager)
add_subdirectory(proto)
add_executable(EfficioTaskTracker main.cpp)
@@ -28,7 +33,12 @@ target_link_libraries(EfficioTaskTracker PRIVATE
efficio-rpc
Database
Scripts
+ StyleManager
+ LanguageManager
AuthorizationWindows
+ ProfileWindow
MainWindow
NoteWidget
-)
\ No newline at end of file
+ SettingsWindow
+ AnalyticsWindow
+)
diff --git a/README.md b/README.md
index d2242e4..cbfcd75 100644
--- a/README.md
+++ b/README.md
@@ -30,6 +30,8 @@ git clone git@github.com:toximu/efficio-task-tracker.git
sudo service postgresql start && sudo -u postgres psql
```
+> If you use fish shell, replace `service` with `systemctl`
+
3. Create **efficio** user
```SQL
@@ -39,15 +41,7 @@ GRANT ALL PRIVILEGES ON DATABASE efficio TO efficio;
\q
```
-4. Enter under **efficio** profile
-
-```bash
-psql -U efficio -d efficio -h localhost
-```
-
-> After that run the server on address **localhost** and **port** 5432 in your pgAdmin4
-
-5. Build and start app
+4. Build and start app
```bash
mkdir -p build && cd build
@@ -56,6 +50,11 @@ make
./EfficioTaskTracker -platform xcb
```
+## Current result
+
+
+
+
## Technologies Used
- Qt 6.8.2
- PostgreSQL 17.4
@@ -64,4 +63,4 @@ make
## License
-This project is licensed under the **MIT License**. See the [LICENSE](https://github.com/toximu/efficio-task-tracker/blob/main/LICENSE) file for details.
\ No newline at end of file
+This project is licensed under the **MIT License**. See the [LICENSE](https://github.com/toximu/efficio-task-tracker/blob/main/LICENSE) file for details.
diff --git a/database/include/lr_dao.hpp b/database/include/lr_dao.hpp
index de8d5fb..d4eed41 100644
--- a/database/include/lr_dao.hpp
+++ b/database/include/lr_dao.hpp
@@ -7,6 +7,7 @@ class LRDao {
public:
LRDao() = default;
static int try_register_user(const QString &login, const QString &password);
+ static bool try_delete_user(const QString &login);
static bool validate_user(const QString &login, const QString &password);
static bool add_project_to_user(std::string user_login, int project_id);
static bool
diff --git a/database/src/database_manager.cpp b/database/src/database_manager.cpp
index ad5b9ec..72a801a 100644
--- a/database/src/database_manager.cpp
+++ b/database/src/database_manager.cpp
@@ -13,10 +13,12 @@ DatabaseManager::DatabaseManager() {
database_.open();
QSqlQuery query(database_);
+
query.exec(
"CREATE TABLE IF NOT EXISTS notes ("
"id SERIAL PRIMARY KEY, "
"title TEXT NOT NULL, "
+ "type TEXT NOT NULL, "
"content TEXT, "
"members VARCHAR(50)[], "
"date VARCHAR(50), "
diff --git a/database/src/lr_dao.cpp b/database/src/lr_dao.cpp
index 3107f5b..5c60887 100644
--- a/database/src/lr_dao.cpp
+++ b/database/src/lr_dao.cpp
@@ -29,6 +29,15 @@ int LRDao::try_register_user(const QString &login, const QString &password) {
);
}
+bool LRDao::try_delete_user(const QString &login) {
+ QSqlQuery query;
+
+ return DatabaseManager::get_instance().execute_query(
+ query, "DELETE FROM users WHERE login = ?",
+ {login}
+ );
+}
+
bool LRDao::validate_user(const QString &login, const QString &password) {
QSqlQuery query;
diff --git a/database/src/note_dao.cpp b/database/src/note_dao.cpp
index 369f192..950bd3c 100644
--- a/database/src/note_dao.cpp
+++ b/database/src/note_dao.cpp
@@ -6,8 +6,8 @@ bool NoteDao::initialize_note(int &id) {
QSqlQuery query;
const auto is_successful = DatabaseManager::get_instance().execute_query(
query,
- "INSERT INTO notes (title, content) "
- "VALUES ('Пустая заметка', '')"
+ "INSERT INTO notes (title, type, content) "
+ "VALUES ('Пустая заметка', 'actual', '')"
"RETURNING id"
);
if (is_successful && query.next()) {
@@ -23,6 +23,7 @@ bool NoteDao::update_note(const Note ¬e) {
const QString sql_query =
"UPDATE notes SET "
"title = :title, "
+ "type = :type, "
"content = :content, "
"members = :members, "
"date = :date, "
@@ -31,6 +32,7 @@ bool NoteDao::update_note(const Note ¬e) {
const QVariantList params = {
QString::fromStdString(note.get_title()),
QString::fromStdString(note.get_text()),
+ QString::fromStdString(note.get_type()),
convert_string_set_to_postgres_array(note.get_members()),
QString::fromStdString(note.get_date()),
convert_tags_to_postgres_array(note.get_tags()),
@@ -58,6 +60,7 @@ std::vector NoteDao::get_all_notes() {
while (query.next()) {
auto id = query.value("id").toUInt();
auto title = query.value("title").toString().toStdString();
+ auto type = query.value("type").toString().toStdString();
auto text = query.value("content").toString().toStdString();
notes.emplace_back(id, title, text);
}
@@ -68,14 +71,15 @@ std::vector NoteDao::get_all_notes() {
Note NoteDao::get_note_by_id(int id) {
QSqlQuery query;
DatabaseManager::get_instance().execute_query(
- query, "SELECT title, content, array_to_string(tags, ','), date, array_to_string(members, ',') FROM notes WHERE id = ?", {id}
+ query, "SELECT title, type, content, array_to_string(tags, ','), date, array_to_string(members, ',') FROM notes WHERE id = ?", {id}
);
query.next();
auto title = query.value(0).toString().toStdString();
- auto text = query.value(1).toString().toStdString();
- auto date = query.value(3).toString().toStdString();
+ auto type = query.value(1).toString().toStdString();
+ auto text = query.value(2).toString().toStdString();
+ auto date = query.value(4).toString().toStdString();
Note result{id, title, text};
- auto tags_list = query.value(2).toString().split(",");
+ auto tags_list = query.value(3).toString().split(",");
if (!tags_list.empty() && tags_list[0] != "") {
for (const auto& tag_str : tags_list) {
@@ -83,7 +87,7 @@ Note NoteDao::get_note_by_id(int id) {
result.add_tag(tag_str.split(':')[0].toStdString(), tag_str.split(':')[1].toStdString());
}
}
- auto member_list = query.value(4).toString().split(",");
+ auto member_list = query.value(5).toString().split(",");
if (!member_list.empty() && member_list[0] != "") {
for (const auto& member : member_list) {
result.add_member(member.toStdString());
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..f16cc7c
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,50 @@
+#include
+#include
+#include
+#include
+#include
+#include "applicationwindow.h"
+#include "login_window.h"
+#include "style_manager.h"
+#include "language_manager.h"
+#include
+
+int main(int argc, char *argv[]) {
+ QApplication app(argc, argv);
+
+ app.setApplicationName("EFFICIO");
+ app.setApplicationDisplayName("EFFICIO");
+ app.setOrganizationName("EFFICIO");
+ app.setWindowIcon(QIcon(":/icons/app_icon.png"));
+
+ QTranslator appTranslator;
+ QTranslator qtTranslator;
+
+ QSettings settings;
+ QString language = settings.value("Language", QLocale::system().name()).toString();
+
+ if (appTranslator.load(":/translations/app_" + language + ".qm")) {
+ app.installTranslator(&appTranslator);
+ }
+
+ if (qtTranslator.load("qt_" + language, QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
+ app.installTranslator(&qtTranslator);
+ }
+
+ StyleManager* style_manager = StyleManager::instance();
+ LanguageManager* language_manager = LanguageManager::instance();
+
+ QMainWindow *app_window = new QMainWindow();
+ app_window->setWindowTitle("EFFICIO");
+ auto *login_window = new LoginWindow(app_window);
+
+ app_window->setCentralWidget(login_window);
+ const QRect screen_geometry = QApplication::primaryScreen()->availableGeometry();
+ const int x = (screen_geometry.width() - login_window->width()) / 2;
+ const int y = (screen_geometry.height() - login_window->height()) / 2;
+ app_window->move(x, y);
+ app_window->show();
+
+ return app.exec();
+
+}
\ No newline at end of file
diff --git a/scripts/include/note.hpp b/scripts/include/note.hpp
index e54e01a..4568a6f 100644
--- a/scripts/include/note.hpp
+++ b/scripts/include/note.hpp
@@ -20,11 +20,13 @@ class Note {
[[nodiscard]] const std::string &get_title() const;
[[nodiscard]] const std::string &get_text() const;
[[nodiscard]] const std::string &get_date() const;
+ [[nodiscard]] const std::string &get_type() const;
[[nodiscard]] const std::vector &get_tags() const;
[[nodiscard]] const std::unordered_set &get_members() const;
void set_title(const std::string &title);
void set_text(const std::string &text);
+ void set_type(const std::string &type);
void add_tag(const std::string &tag, const std::string &color = "#e7624b");
void set_date(const std::string &date);
void add_member(const std::string &member);
@@ -37,6 +39,7 @@ class Note {
std::string title_;
std::string text_;
std::string date_;
+ std::string type_;
std::vector tags_;
std::unordered_set members_;
};
diff --git a/scripts/src/note.cpp b/scripts/src/note.cpp
index dcb8391..8ea7d0e 100644
--- a/scripts/src/note.cpp
+++ b/scripts/src/note.cpp
@@ -20,6 +20,10 @@ Note::Note(const int id, std::string title, std::string text)
return text_;
}
+[[nodiscard]] const std::string &Note::get_type() const {
+ return type_;
+}
+
const std::string &Note::get_date() const {
return date_;
}
@@ -40,6 +44,10 @@ void Note::set_text(const std::string &text) {
text_ = text;
}
+void Note::set_type(const std::string &type) {
+ type_ = type;
+}
+
void Note::add_tag(const std::string &tag, const std::string &color) {
tags_.push_back({tag, color});
}
diff --git a/ui/analytics-window/CMakeLists.txt b/ui/analytics-window/CMakeLists.txt
new file mode 100644
index 0000000..9c3798e
--- /dev/null
+++ b/ui/analytics-window/CMakeLists.txt
@@ -0,0 +1,42 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(AnalyticsWindow LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Qt6 COMPONENTS Widgets Core Gui Sql Charts REQUIRED)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+set(SOURCES
+ src/analytics_window.cpp
+)
+
+set(HEADERS
+ include/analytics_window.h
+ include/analytics_window_style_sheet.h
+)
+
+add_library(AnalyticsWindow STATIC ${SOURCES} ${HEADERS})
+
+target_include_directories(AnalyticsWindow
+ PUBLIC
+ $
+ $
+)
+
+target_link_libraries(AnalyticsWindow
+ PRIVATE
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Sql
+ Database
+ StyleManager
+ LanguageManager
+ PUBLIC
+ Qt6::Widgets
+ Qt6::Charts
+)
\ No newline at end of file
diff --git a/ui/analytics-window/include/analytics_window.h b/ui/analytics-window/include/analytics_window.h
new file mode 100644
index 0000000..63dddd5
--- /dev/null
+++ b/ui/analytics-window/include/analytics_window.h
@@ -0,0 +1,45 @@
+#ifndef ANALYTICS_DIALOG_H
+#define ANALYTICS_DIALOG_H
+
+#include
+#include
+#include
+#include
+#include
+
+class AnalyticsWindow : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit AnalyticsWindow(
+ QWidget *parent = nullptr,
+ int created_count = 3,
+ int completed_count = 4,
+ int expired_count = 5
+ );
+ ~AnalyticsWindow();
+
+ static const std::vector THEMES;
+
+private:
+
+ void handle_theme_changed(int theme);
+ void handle_font_size_changed(std::string font_size);
+ void handle_language_changed(std::string new_language);
+ void on_switch_theme_clicked();
+ void setup_chart();
+
+ int m_created_count;
+ int m_completed_count;
+ int m_expired_count;
+
+ QChartView *chart_view;
+ QPieSeries *series;
+ QChart *chart;
+ QPieSlice *completed_slice;
+ QPieSlice *expired_slice;
+ QPieSlice *created_slice;
+};
+
+#endif // ANALYTICS_DIALOG_H
\ No newline at end of file
diff --git a/ui/analytics-window/include/analytics_window_style_sheet.h b/ui/analytics-window/include/analytics_window_style_sheet.h
new file mode 100644
index 0000000..fb146a7
--- /dev/null
+++ b/ui/analytics-window/include/analytics_window_style_sheet.h
@@ -0,0 +1,380 @@
+#ifndef ANALYTICS_WINDOW_STYLE_SHEET_H
+#define ANALYTICS_WINDOW_STYLE_SHEET_H
+
+#include
+
+namespace Ui {
+
+const QString analytics_window_light_autumn_theme = R"(
+#AnalyticsWindow {
+ background-color: #f5f5f5;
+ color: #444444;
+ font-family: 'Arial';
+}
+
+QTabWidget::pane {
+ border: 1px solid #d0d0d0;
+ border-radius: 4px;
+ margin: 5px;
+ background: #ffffff;
+}
+
+QTabBar::tab {
+ background: #e0e0e0;
+ color: #666666;
+ border: 1px solid #d0d0d0;
+ border-bottom: none;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ padding: 8px 15px;
+ margin-right: 2px;
+}
+
+QTabBar::tab:selected {
+ background: #ffffff;
+ color: #222222;
+ border-color: #d0d0d0;
+ font-weight: bold;
+}
+
+QTabBar::tab:hover {
+ background: #f0f0f0;
+}
+
+QDialogButtonBox {
+ border-top: 1px solid #d0d0d0;
+ padding-top: 10px;
+}
+
+QDialogButtonBox QPushButton {
+ background-color: #fea36b;
+ color: white;
+ border: 1px solid #e08c52;
+ border-radius: 3px;
+ padding: 5px 15px;
+ min-width: 80px;
+}
+
+QDialogButtonBox QPushButton:hover {
+ background-color: #f58c50;
+}
+
+QDialogButtonBox QPushButton:pressed {
+ background-color: #e07c40;
+}
+
+QChartView {
+ background-color: #ffffff;
+ border-radius: 5px;
+ border: 1px solid #d0d0d0;
+ margin: 10px;
+}
+
+QLegend::label {
+ color: #666666;
+}
+
+QAbstractAxis {
+ color: #888888;
+}
+)";
+
+const QString analytics_window_dark_autumn_theme = R"(
+#AnalyticsWindow {
+ background-color: #202020;
+ color: #BDD1BD;
+ font-family: 'Arial';
+}
+
+QTabWidget::pane {
+ border: 1px solid #333333;
+ border-radius: 4px;
+ margin: 5px;
+ background: #282828;
+}
+
+QTabBar::tab {
+ background: #323232;
+ color: #8a8a8a;
+ border: 1px solid #333333;
+ border-bottom: none;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ padding: 8px 15px;
+ margin-right: 2px;
+}
+
+QTabBar::tab:selected {
+ background: #3a3a3a;
+ color: #BDD1BD;
+ border-color: #333333;
+ font-weight: bold;
+}
+
+QTabBar::tab:hover {
+ background: #363636;
+}
+
+QDialogButtonBox {
+ border-top: 1px solid #333333;
+ padding-top: 10px;
+}
+
+QDialogButtonBox QPushButton {
+ background-color: #d38b5f;
+ color: #263238;
+ border: 1px solid #b3754d;
+ border-radius: 3px;
+ padding: 5px 15px;
+ min-width: 80px;
+}
+
+QDialogButtonBox QPushButton:hover {
+ background-color: #c07b4f;
+}
+
+QDialogButtonBox QPushButton:pressed {
+ background-color: #a86b3f;
+}
+
+QChartView {
+ background-color: #282828;
+ border-radius: 5px;
+ border: 1px solid #333333;
+ margin: 10px;
+}
+
+QLegend::label {
+ color: #a0a0a0;
+}
+
+QAbstractAxis {
+ color: #8a8a8a;
+}
+)";
+
+const QString analytics_window_light_purple_theme = R"(
+#AnalyticsWindow {
+ background-color: #9882B9;
+ color: rgb(42, 10, 25);
+ font-family: 'Arial';
+}
+
+QTabWidget::pane {
+ border: 1px solid #7a5d9b;
+ border-radius: 4px;
+ margin: 5px;
+ background: #b9a2d9;
+}
+
+QTabBar::tab {
+ background: #a992c9;
+ color: rgb(62, 20, 35);
+ border: 1px solid #7a5d9b;
+ border-bottom: none;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ padding: 8px 15px;
+ margin-right: 2px;
+}
+
+QTabBar::tab:selected {
+ background: #d9c2f9;
+ color: rgb(42, 10, 25);
+ border-color: #7a5d9b;
+ font-weight: bold;
+}
+
+QTabBar::tab:hover {
+ background: #c9b2e9;
+}
+
+QDialogButtonBox {
+ border-top: 1px solid #7a5d9b;
+ padding-top: 10px;
+}
+
+QDialogButtonBox QPushButton {
+ background-color: #722548;
+ color: #f5e5ff;
+ border: 1px solid #5a1538;
+ border-radius: 3px;
+ padding: 5px 15px;
+ min-width: 80px;
+}
+
+QDialogButtonBox QPushButton:hover {
+ background-color: #5a1538;
+}
+
+QDialogButtonBox QPushButton:pressed {
+ background-color: #4a0528;
+}
+
+QChartView {
+ background-color: #d9c2f9;
+ border-radius: 5px;
+ border: 1px solid #7a5d9b;
+ margin: 10px;
+}
+
+QLegend::label {
+ color: rgb(62, 20, 35);
+}
+
+QAbstractAxis {
+ color: rgb(82, 40, 55);
+}
+)";
+
+const QString analytics_window_dark_purple_theme = R"(
+#AnalyticsWindow {
+ background-color: #221932;
+ color: #9882B9;
+ font-family: 'Arial';
+}
+
+QTabWidget::pane {
+ border: 1px solid #3a2a4a;
+ border-radius: 4px;
+ margin: 5px;
+ background: #2a1f3a;
+}
+
+QTabBar::tab {
+ background: #322242;
+ color: #7a6a9a;
+ border: 1px solid #3a2a4a;
+ border-bottom: none;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ padding: 8px 15px;
+ margin-right: 2px;
+}
+
+QTabBar::tab:selected {
+ background: #4a3a5a;
+ color: #c9b2e9;
+ border-color: #5a4a6a;
+ font-weight: bold;
+}
+
+QTabBar::tab:hover {
+ background: #3a2a4a;
+}
+
+QDialogButtonBox {
+ border-top: 1px solid #3a2a4a;
+ padding-top: 10px;
+}
+
+QDialogButtonBox QPushButton {
+ background-color: #722548;
+ color: #d9c2f9;
+ border: 1px solid #5a1538;
+ border-radius: 3px;
+ padding: 5px 15px;
+ min-width: 80px;
+}
+
+QDialogButtonBox QPushButton:hover {
+ background-color: #5a1538;
+}
+
+QDialogButtonBox QPushButton:pressed {
+ background-color: #4a0528;
+}
+
+QChartView {
+ background-color: #322242;
+ border-radius: 5px;
+ border: 1px solid #3a2a4a;
+ margin: 10px;
+}
+
+QLegend::label {
+ color: #9a82b9;
+}
+
+QAbstractAxis {
+ color: #8a7aa9;
+}
+)";
+
+const QString analytics_window_blue_theme = R"(
+#AnalyticsWindow {
+ background-color: #07142B;
+ color: #BDD1BD;
+ font-family: 'Arial';
+}
+
+QTabWidget::pane {
+ border: 1px solid #1a2c4b;
+ border-radius: 4px;
+ margin: 5px;
+ background: #0f1c35;
+}
+
+QTabBar::tab {
+ background: #173C4C;
+ color: #8dacbd;
+ border: 1px solid #1a2c4b;
+ border-bottom: none;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ padding: 8px 15px;
+ margin-right: 2px;
+}
+
+QTabBar::tab:selected {
+ background: #1f4c5c;
+ color: #BDD1BD;
+ border-color: #1a2c4b;
+ font-weight: bold;
+}
+
+QTabBar::tab:hover {
+ background: #1b4454;
+}
+
+QDialogButtonBox {
+ border-top: 1px solid #1a2c4b;
+ padding-top: 10px;
+}
+
+QDialogButtonBox QPushButton {
+ background-color: #568F7C;
+ color: #07142B;
+ border: 1px solid #3a6f5c;
+ border-radius: 3px;
+ padding: 5px 15px;
+ min-width: 80px;
+}
+
+QDialogButtonBox QPushButton:hover {
+ background-color: #3a6f5c;
+}
+
+QDialogButtonBox QPushButton:pressed {
+ background-color: #2a5f4c;
+}
+
+QChartView {
+ background-color: #0f1c35;
+ border-radius: 5px;
+ border: 1px solid #1a2c4b;
+ margin: 10px;
+}
+
+QLegend::label {
+ color: #9dbdcd;
+}
+
+QAbstractAxis {
+ color: #7d9cad;
+}
+)";
+
+} // namespace Ui
+
+#endif // ANALYTICS_WINDOW_STYLE_SHEET_H
\ No newline at end of file
diff --git a/ui/analytics-window/src/analytics_window.cpp b/ui/analytics-window/src/analytics_window.cpp
new file mode 100644
index 0000000..e20c464
--- /dev/null
+++ b/ui/analytics-window/src/analytics_window.cpp
@@ -0,0 +1,158 @@
+#include "analytics_window.h"
+#include "style_manager.h"
+#include "language_manager.h"
+#include "analytics_window_style_sheet.h"
+#include
+
+const std::vector AnalyticsWindow::THEMES = {
+ Ui::analytics_window_light_autumn_theme,
+ Ui::analytics_window_dark_autumn_theme,
+ Ui::analytics_window_dark_purple_theme,
+ Ui::analytics_window_light_purple_theme,
+ Ui::analytics_window_blue_theme
+};
+
+AnalyticsWindow::AnalyticsWindow(QWidget *parent,
+ int created_count,
+ int completed_count,
+ int expired_count)
+ : QDialog(parent),
+ m_created_count(created_count),
+ m_completed_count(completed_count),
+ m_expired_count(expired_count),
+ chart_view(new QChartView(this)),
+ series(new QPieSeries()),
+ chart(new QChart())
+{
+ setFixedSize(700, 400);
+
+ QVBoxLayout *main_layout = new QVBoxLayout(this);
+
+ completed_slice = new QPieSlice();
+ completed_slice->setValue(m_completed_count);
+ completed_slice->setColor(QColor(46, 204, 113));
+
+ expired_slice = new QPieSlice();
+ expired_slice->setValue(m_expired_count);
+ expired_slice->setColor(QColor(231, 76, 60));
+
+ created_slice = new QPieSlice();
+ created_slice->setValue(m_created_count);
+ created_slice->setColor(QColor(52, 152, 219));
+
+ series->append(completed_slice);
+ series->append(expired_slice);
+ series->append(created_slice);
+
+ chart->addSeries(series);
+ chart->legend()->setAlignment(Qt::AlignBottom);
+ chart->setAnimationOptions(QChart::AllAnimations);
+
+ chart_view->setRenderHint(QPainter::Antialiasing);
+ chart_view->setChart(chart);
+
+ main_layout->addWidget(chart_view);
+ setLayout(main_layout);
+
+ connect(
+ StyleManager::instance(), &StyleManager::theme_changed,
+ this, &AnalyticsWindow::handle_theme_changed
+ );
+ connect(
+ StyleManager::instance(), &StyleManager::font_size_changed,
+ this, &AnalyticsWindow::handle_font_size_changed
+ );
+ connect(LanguageManager::instance(), &LanguageManager::language_changed,
+ this, &AnalyticsWindow::handle_language_changed
+ );
+ handle_font_size_changed(StyleManager::instance()->current_font_size());
+ handle_theme_changed(StyleManager::instance()->current_theme());
+ handle_language_changed(LanguageManager::instance()->current_language());
+}
+
+void AnalyticsWindow::setup_chart()
+{
+ series->append("Завершенные", m_completed_count);
+ series->append("Просроченные", m_expired_count);
+ series->append("Созданные", m_created_count);
+
+ QPieSlice *completed_slice = series->slices().at(0);
+ completed_slice->setColor(QColor(46, 204, 113));
+ completed_slice->setLabelVisible(true);
+
+ QPieSlice *expired_slice = series->slices().at(1);
+ expired_slice->setColor(QColor(231, 76, 60));
+ expired_slice->setLabelVisible(true);
+
+ QPieSlice *created_slice = series->slices().at(2);
+ created_slice->setColor(QColor(52, 152, 219));
+ created_slice->setLabelVisible(true);
+
+ for(QPieSlice *slice : series->slices()) {
+ slice->setLabel(slice->label() +
+ QString(": %1 (%2%)")
+ .arg(slice->value())
+ .arg(100 * slice->percentage(), 0, 'f', 1));
+ }
+
+ QChart *chart = new QChart();
+ chart->addSeries(series);
+ chart->setTitle("Статистика заметок");
+ chart->setTitleFont(QFont("Arial", 14, QFont::Bold));
+ chart->legend()->setAlignment(Qt::AlignBottom);
+ chart->setAnimationOptions(QChart::AllAnimations);
+
+ chart_view->setChart(chart);
+}
+
+AnalyticsWindow::~AnalyticsWindow(){}
+
+void AnalyticsWindow::handle_language_changed(std::string new_language) {
+ if (new_language == "RU") {
+ chart->setTitle("Статистика заметок");
+ completed_slice->setLabel("Завершенные");
+ expired_slice->setLabel("Просроченные");
+ created_slice->setLabel("Созданные");
+ setWindowTitle("Аналитическая панель");
+ }
+ else if (new_language == "EN") {
+ chart->setTitle("Notes Statistics");
+ completed_slice->setLabel("Completed");
+ expired_slice->setLabel("Expired");
+ created_slice->setLabel("Created");
+ setWindowTitle("Analytics Panel");
+ }
+ for (QPieSlice *slice : series->slices()) {
+ slice->setLabelVisible(true);
+ QString label = slice->label() +
+ QString(": %1 (%2%)")
+ .arg(slice->value())
+ .arg(100 * slice->percentage(), 0, 'f', 1);
+ slice->setLabel(label);
+ }
+}
+
+void AnalyticsWindow::handle_font_size_changed(std::string font_size) {
+
+ QString font_size_rule;
+ if(font_size == "small") {
+ font_size_rule = "QPushButton { font-size: 11px; }";
+ }
+ else if(font_size == "medium") {
+ font_size_rule = "QPushButton { font-size: 13px; }";
+ }
+ else if(font_size == "big") {
+ font_size_rule = "QPushButton { font-size: 15px; }";
+ }
+
+ this->setStyleSheet(THEMES[StyleManager::instance()->current_theme()] + font_size_rule);
+}
+
+void AnalyticsWindow::handle_theme_changed(int theme) {
+ this->setStyleSheet(THEMES[theme]);
+}
+
+void AnalyticsWindow::on_switch_theme_clicked() {
+ int next_theme = (StyleManager::instance()->current_theme() + 1) % 5;
+ StyleManager::instance()->apply_theme(next_theme);
+}
\ No newline at end of file
diff --git a/ui/authorization-windows/CMakeLists.txt b/ui/authorization-windows/CMakeLists.txt
index e61f562..566818b 100644
--- a/ui/authorization-windows/CMakeLists.txt
+++ b/ui/authorization-windows/CMakeLists.txt
@@ -16,6 +16,7 @@ set(CMAKE_AUTOUIC_SEARCH_PATHS ${CMAKE_CURRENT_SOURCE_DIR}/ui)
set(UI_FILES
${CMAKE_CURRENT_SOURCE_DIR}/ui/login_window.ui
${CMAKE_CURRENT_SOURCE_DIR}/ui/registration_window.ui
+ ${CMAKE_CURRENT_BINARY_DIR}
)
set(SOURCES
@@ -40,4 +41,4 @@ target_include_directories(AuthorizationWindows
$
)
-target_link_libraries(AuthorizationWindows PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui Qt6::Sql Database Scripts MainWindow)
\ No newline at end of file
+target_link_libraries(AuthorizationWindows PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui Qt6::Sql Database LanguageManager Scripts MainWindow StyleManager ProfileWindow)
\ No newline at end of file
diff --git a/ui/authorization-windows/include/login_window.h b/ui/authorization-windows/include/login_window.h
index 5aed300..21e2028 100644
--- a/ui/authorization-windows/include/login_window.h
+++ b/ui/authorization-windows/include/login_window.h
@@ -1,32 +1,35 @@
#pragma once
-#include
-#include
-#include
-#include
#include
-#include "database_manager.hpp"
-#include "lr_dao.hpp"
+#include
+#include
+#include
QT_BEGIN_NAMESPACE
-
-namespace Ui {
-class LoginWindow;
-}
-
+ namespace Ui {
+ class LoginWindow;
+ }
QT_END_NAMESPACE
-class LoginWindow : public QWidget {
+class LoginWindow : public QWidget
+{
Q_OBJECT
public:
explicit LoginWindow(QWidget *parent = nullptr);
- ~LoginWindow();
+ ~LoginWindow() override;
+
+ void handle_language_changed(std::string new_language);
private slots:
void on_switch_mode_clicked();
void on_push_enter_clicked();
+ void on_switch_language_clicked();
private:
- Ui::LoginWindow *ui;
+ std::shared_ptr ui;
+ int counter_on_switch_theme_clicks = 0;
+ void switch_window(QMainWindow *app_window, QWidget *new_window, int width, int height);
+ void switch_to_login_window(QMainWindow *app_window);
+ void switch_to_registration_window(QMainWindow *app_window);
};
\ No newline at end of file
diff --git a/ui/authorization-windows/include/login_window_style_sheet.h b/ui/authorization-windows/include/login_window_style_sheet.h
index 3a6d776..68fa3c4 100644
--- a/ui/authorization-windows/include/login_window_style_sheet.h
+++ b/ui/authorization-windows/include/login_window_style_sheet.h
@@ -3,58 +3,73 @@
#include "ui_login_window.h"
namespace Ui {
-QString login_window_light_theme = R"(
- QWidget {
- background-color: #f5f5f5;
- }
+ QString login_window_light_autumn_theme = R"(
+ QWidget {
+ background-color: #f5f5f5;
+ }
+
+ QLabel {
+ background-color: transparent;
+ font-family: 'Arial';
+ font-size: 13px;
+ color: #089083;
+ padding: 1px;
+ }
+
+ QPushButton#push_enter {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #fea36b;
+ color: white;
+ padding: 5px 10px;
+ }
+
+ QPushButton#switch_mode {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: white;
+ color: #fea36b;
+ padding: 5px 10px;
+ }
+
+ QPushButton#push_enter:hover {
+ background-color: #d58745;
+ }
+
+ QPushButton#switch_mode:hover {
+ background-color: #dadada;
+ }
+
+ QLineEdit {
+ border-radius: 10px;
+ border: 1px solid white;
+ background: white;
+ color: black;
+ padding: 5px;
+ }
+
+ QLineEdit::placeholder {
+ color: #727272;
+ }
- QLabel {
- font-family: 'Arial';
- font-weight: bold;
- font-size: 13px;
- color: #089083;
- padding: 1px;
- background-color: transparent;
- }
-
- QPushButton#pushEnter {
- font-family: 'Arial';
- font-weight: bold;
- border-radius: 10px;
- background-color: #fea36b;
- color: white;
- padding: 5px 10px;
- }
-
- QPushButton#switchMode {
- font-family: 'Arial';
- font-weight: bold;
- border-radius: 10px;
- background-color: white;
- color: #fea36b;
- padding: 5px 10px;
- }
-
- QPushButton#pushEnter:hover {
- background-color: #d58745;
- }
-
- QPushButton#switchMode:hover {
- background-color: #dadada;
- }
-
- QLineEdit {
- border-radius: 10px;
- border: 1px solid white;
- background: white;
- color: black;
- padding: 5px;
- }
-
- QLineEdit::placeholder {
- color: #727272;
- }
-
-)";
+ QPushButton#switch_theme {
+ background-color: #089083;
+ min-width: 20px;
+ min-height: 20px;
+ color: #f5f5f5;
+ padding: 2px;
+ font-size: 13px;
+ border-radius: 7px;
+ font-family: 'Arial' bold;
+ }
+ QPushButton#switch_theme:hover {
+ background-color: rgb(8, 82, 74);
+ color: #f5f5f5;
+ }
+ QPushButton::pressed#switch_theme {
+ background-color:rgb(3, 58, 54);
+ color: #f5f5f5;
+ }
+ )";
} // namespace Ui
\ No newline at end of file
diff --git a/ui/authorization-windows/include/registration_window.h b/ui/authorization-windows/include/registration_window.h
index 35f4bc4..61c1ef6 100644
--- a/ui/authorization-windows/include/registration_window.h
+++ b/ui/authorization-windows/include/registration_window.h
@@ -1,31 +1,28 @@
#pragma once
-#include
-#include
#include
-#include "database_manager.hpp"
-#include "lr_dao.hpp"
-
-QT_BEGIN_NAMESPACE
+#include
namespace Ui {
-class RegistrationWindow;
+ class RegistrationWindow;
}
-QT_END_NAMESPACE
-
class RegistrationWindow : public QWidget {
Q_OBJECT
public:
explicit RegistrationWindow(QWidget *parent = nullptr);
- ~RegistrationWindow();
+ ~RegistrationWindow() override;
+
bool is_strong_and_valid_password(const QString &password);
+ void handle_language_changed(std::string new_language);
private slots:
void on_switch_mode_clicked();
void on_push_registration_clicked();
+ void on_switch_language_clicked();
private:
- Ui::RegistrationWindow *ui;
+ std::shared_ptr ui;
+ int counter_on_switch_theme_clicks = 0;
};
\ No newline at end of file
diff --git a/ui/authorization-windows/include/registration_window_style_sheet.h b/ui/authorization-windows/include/registration_window_style_sheet.h
index dc7a1ca..21e2491 100644
--- a/ui/authorization-windows/include/registration_window_style_sheet.h
+++ b/ui/authorization-windows/include/registration_window_style_sheet.h
@@ -3,56 +3,73 @@
#include "ui_registration_window.h"
namespace Ui {
-QString registration_window_light_theme = R"(
- QWidget {
- background-color: #f5f5f5;
- }
-
- QLabel {
- font-family: 'Arial';
- background-color: transparent;
- font-size: 13px;
- color: #089083;
- padding: 1px;
- }
-
- QPushButton#pushRegistration {
- font-weight: bold;
- font-family: 'Arial';
- border-radius: 8px;
- background-color: #fea36b;
- color: white;
- padding: 5px 10px;
- }
-
- QPushButton#switchMode {
- font-family: 'Arial';
- border-radius: 10px;
- background-color: white;
- color: #fea36b;
- padding: 5px 10px;
- }
-
- QPushButton#pushRegistration:hover {
- background-color: #d58745;
- }
-
- QPushButton#switchMode:hover {
- background-color: #dadada;
- }
-
- QLineEdit {
- border-radius: 10px;
- border: 1px solid white;
- background: white;
- color: black;
- padding: 5px;
- }
-
- QLineEdit::placeholder {
- color: #727272;
- }
-
-)";
+ QString registration_window_light_autumn_theme = R"(
+ QWidget {
+ background-color: #f5f5f5;
+ }
+
+ QLabel {
+ font-family: 'Arial';
+ background-color: transparent;
+ color: #089083;
+ font-size: 14px;
+ padding: 12px;
+ }
+
+ QPushButton#push_registration {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #fea36b;
+ color: white;
+ padding: 5px 10px;
+ }
+
+ QPushButton#switch_mode {
+ font-family: 'Arial' bold;
+ border-radius: 10px;
+ background-color: white;
+ color: #fea36b;
+ padding: 5px 10px;
+ }
+
+ QPushButton#push_registration:hover {
+ background-color: #d58745;
+ }
+
+ QPushButton#switch_mode:hover {
+ background-color: #dadada;
+ }
+
+ QLineEdit {
+ border-radius: 10px;
+ border: 1px solid white;
+ background: white;
+ color: black;
+ padding: 5px;
+ }
+
+ QLineEdit::placeholder {
+ color: #727272;
+ }
+
+ QPushButton#switch_theme {
+ background-color: #089083;
+ min-width: 20px;
+ min-height: 20px;
+ color: #f5f5f5;
+ padding: 2px;
+ font-size: 13px;
+ border-radius: 7px;
+ font-family: 'Arial' bold;
+ }
+ QPushButton#switch_theme:hover {
+ background-color: rgb(8, 82, 74);
+ color: #f5f5f5;
+ }
+ QPushButton::pressed#switch_theme {
+ background-color:rgb(3, 58, 54);
+ color: #f5f5f5;
+ }
+ )";
} // namespace Ui
\ No newline at end of file
diff --git a/ui/authorization-windows/src/login_window.cpp b/ui/authorization-windows/src/login_window.cpp
index 0583ef5..0f85af3 100644
--- a/ui/authorization-windows/src/login_window.cpp
+++ b/ui/authorization-windows/src/login_window.cpp
@@ -1,118 +1,169 @@
#include "login_window.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
#include "applicationwindow.h"
-#include "bottombar.h"
-#include "database_manager.hpp"
-#include "login_window_style_sheet.h"
#include "lr_dao.hpp"
#include "mainwindow.h"
-#include "notelist.h"
#include "registration_window.h"
+#include "login_window_style_sheet.h"
#include "serialization.hpp"
+#include "style_manager.h"
+#include "language_manager.h"
+#include
+#include
+#include
LoginWindow::LoginWindow(QWidget *parent)
: QWidget(parent), ui(new Ui::LoginWindow) {
ui->setupUi(this);
setFixedSize(380, 480);
- ui->inputLogin->setPlaceholderText("Введите логин:");
- ui->inputPassword->setPlaceholderText("Введите пароль:");
- setStyleSheet(Ui::login_window_light_theme);
- ui->inputPassword->setEchoMode(QLineEdit::Password);
-
- connect(
- ui->switchMode, &QPushButton::clicked, this,
- &LoginWindow::on_switch_mode_clicked
- );
- connect(
- ui->pushEnter, &QPushButton::clicked, this,
- &LoginWindow::on_push_enter_clicked
+ ui->input_login->setPlaceholderText(tr("Введите логин:"));
+ ui->input_password->setPlaceholderText(tr("Введите пароль:"));
+ ui->input_password->setEchoMode(QLineEdit::Password);
+
+ connect(ui->switch_mode, &QPushButton::clicked, this,
+ &LoginWindow::on_switch_mode_clicked);
+ connect(ui->push_enter, &QPushButton::clicked, this,
+ &LoginWindow::on_push_enter_clicked);
+ connect(LanguageManager::instance(), &LanguageManager::language_changed,
+ this, &LoginWindow::handle_language_changed
);
+ connect(ui->switch_theme, &QPushButton::clicked, this,
+ &LoginWindow::on_switch_language_clicked, Qt::UniqueConnection);
+ handle_language_changed(LanguageManager::instance()->current_language());
+ setStyleSheet(Ui::login_window_light_autumn_theme);
}
-LoginWindow::~LoginWindow() {
- delete ui;
+void LoginWindow::handle_language_changed(std::string new_language) {
+ if (new_language == "RU") {
+ ui->input_login->setPlaceholderText(tr("Введите логин:"));
+ ui->enter_label->setText(tr("Вход"));
+ ui->input_password->setPlaceholderText(tr("Введите пароль:"));
+ ui->switch_mode->setText(tr("Еще нет аккаунта? Зарегестрируйтесь!"));
+ ui->switch_theme->setText(tr("RU"));
+ ui->push_enter->setText(tr("Войти"));
+ }
+ else if (new_language == "EN") {
+ ui->input_login->setPlaceholderText(tr("Enter login:"));
+ ui->enter_label->setText(tr("Enter"));
+ ui->input_password->setPlaceholderText(tr("Enter password:"));
+ ui->switch_mode->setText(tr("Don't have an account yet? Register!"));
+ ui->switch_theme->setText(tr("EN"));
+ ui->push_enter->setText(tr("Login"));
+ }
}
-void LoginWindow::on_switch_mode_clicked() {
- QWidget *parent = this->parentWidget();
-
- QMainWindow *app_window = qobject_cast(parent);
-
- if (QWidget *old = app_window->centralWidget()) {
- old->deleteLater();
+void LoginWindow::on_switch_language_clicked() {
+ if (ui->switch_theme->text() == tr("RU")) {
+ ui->switch_theme->setText(tr("EN"));
+ LanguageManager::instance()->apply_language("EN");
+ } else {
+ ui->switch_theme->setText(tr("RU"));
+ LanguageManager::instance()->apply_language("RU");
}
- project_storage_model::Storage storage;
- RegistrationWindow *registration_window =
- new RegistrationWindow(app_window);
+}
- app_window->setCentralWidget(registration_window);
- QRect screenGeometry = QApplication::primaryScreen()->availableGeometry();
- int x = (screenGeometry.width() - registration_window->width()) / 2;
- int y = (screenGeometry.height() - registration_window->height()) / 2;
- app_window->move(x, y);
+LoginWindow::~LoginWindow() = default;
- this->close();
+void LoginWindow::on_switch_mode_clicked() {
+ if (QMainWindow *app_window = qobject_cast(this->parentWidget())) {
+ RegistrationWindow *registration_window = new RegistrationWindow(app_window);
+ switch_window(app_window, registration_window, 380, 480);
+ this->close();
+ }
}
-
void LoginWindow::on_push_enter_clicked() {
- QString login = ui->inputLogin->text();
- QString password = ui->inputPassword->text();
-
- if (!login.isEmpty() && !password.isEmpty()) {
- if (login.size() > 50) {
- QMessageBox::warning(
- this, "Ошибка",
- "Длина логина не должна превышать пятидесяти символов"
- );
- } else if (password.size() > 50) {
- QMessageBox::warning(
- this, "Ошибка",
- "Длина пароля не должна превышать пятидесяти символов"
- );
- } else if (LRDao::validate_user(login, password)) {
- QMessageBox::information(
- this, "Вход", "Вы успешно вошли! Добро пожаловать :)"
- );
- QWidget *parent = this->parentWidget();
-
- QMainWindow *app_window = qobject_cast(parent);
-
- if (QWidget *old = app_window->centralWidget()) {
- old->deleteLater();
- }
- // todo load all projects of user to storage
- project_storage_model::Storage *storage =
- new project_storage_model::Storage();
+ if ((this->counter_on_switch_theme_clicks++) % 2) {
+ QString login = ui->input_login->text().trimmed();
+ QString password = ui->input_password->text();
+ std::string lang = LanguageManager::instance()->current_language();
+
+ // if (login.isEmpty() || password.isEmpty()) {
+ // if (lang == "RU") {
+ // QMessageBox::warning(this, "Ошибка ввода данных", "Пожалуйста, заполните все поля!");
+ // } else {
+ // QMessageBox::warning(this, "Input Error", "Please fill in all the fields!");
+ // }
+ // return;
+ // }
+
+ // if (login.size() > 50) {
+ // if (lang == "RU") {
+ // QMessageBox::warning(this, "Ошибка", "Длина логина не должна превышать пятидесяти символов");
+ // } else {
+ // QMessageBox::warning(this, "Error", "Login must not exceed fifty characters");
+ // }
+ // return;
+ // }
+
+ // if (password.size() > 50) {
+ // if (lang == "RU") {
+ // QMessageBox::warning(this, "Ошибка", "Длина пароля не должна превышать пятидесяти символов");
+ // } else {
+ // QMessageBox::warning(this, "Error", "Password must not exceed fifty characters");
+ // }
+ // return;
+ // }
+
+ // if (!LRDao::validate_user(login, password)) {
+ // if (lang == "RU") {
+ // QMessageBox::warning(this, "Ошибка ввода данных", "Неверный логин или пароль!");
+ // } else {
+ // QMessageBox::warning(this, "Login Error", "Incorrect login or password!");
+ // }
+ // return;
+ // }
+
+ if (lang == "RU") {
+ QMessageBox::information(this, "Вход", "Вы успешно вошли. Добро пожаловать!");
+ } else {
+ QMessageBox::information(this, "Login", "You have successfully logged in. Welcome!");
+ }
+
+ if (QMainWindow *app_window = qobject_cast(this->parentWidget())) {
+ this->deleteLater();
+ project_storage_model::Storage *storage = new project_storage_model::Storage();
Serialization::get_storage(*storage, login.toStdString());
- Ui::MainWindow *main_window =
- new Ui::MainWindow(app_window, login.toStdString(), storage);
+ Ui::MainWindow *main_window = new Ui::MainWindow(app_window, login.toStdString(), storage);
+
+ connect(main_window, &Ui::MainWindow::logout_requested, app_window, [app_window, this]() {
+ switch_to_login_window(app_window);
+ });
+
+ connect(main_window, &Ui::MainWindow::delete_account_requested, app_window, [app_window, this]() {
+ switch_to_registration_window(app_window);
+ });
+
+ switch_window(app_window, main_window, 800, 600);
+ }
+ }
+}
- app_window->setCentralWidget(main_window);
- app_window->resize(800, 600);
- QRect screenGeometry =
- QApplication::primaryScreen()->availableGeometry();
- int x = (screenGeometry.width() - main_window->width()) / 2;
- int y = (screenGeometry.height() - main_window->height()) / 2;
- app_window->move(x, y);
- this->close();
- } else {
- QMessageBox::warning(
- this, "Ошибка ввода данных", "Неверный логин или пароль!"
- );
- }
- } else {
- QMessageBox::warning(
- this, "Ошибка ввода данных", "Пожалуйста, заполните все поля!"
- );
+void LoginWindow::switch_window(QMainWindow *app_window, QWidget *new_window, int width, int height) {
+ if (QWidget *old = app_window->centralWidget()) {
+ old->deleteLater();
}
+
+ app_window->setCentralWidget(new_window);
+ if (width > 0 && height > 0) {
+ app_window->resize(width, height);
+ }
+
+ QRect screen_geometry = QApplication::primaryScreen()->availableGeometry();
+ app_window->move(
+ (screen_geometry.width() - width) / 2,
+ (screen_geometry.height() - height) / 2
+ );
+ app_window->show();
+}
+
+void LoginWindow::switch_to_login_window(QMainWindow *app_window) {
+ LoginWindow *login_window = new LoginWindow(app_window);
+ switch_window(app_window, login_window, 380, 480);
+}
+
+void LoginWindow::switch_to_registration_window(QMainWindow *app_window) {
+ RegistrationWindow *registration_window = new RegistrationWindow(app_window);
+ switch_window(app_window, registration_window, 380, 480);
}
\ No newline at end of file
diff --git a/ui/authorization-windows/src/registration_window.cpp b/ui/authorization-windows/src/registration_window.cpp
index f30f7d8..13cce80 100644
--- a/ui/authorization-windows/src/registration_window.cpp
+++ b/ui/authorization-windows/src/registration_window.cpp
@@ -1,86 +1,114 @@
#include "registration_window.h"
-#include
-#include
-#include
-#include
+#include
#include
-#include
-#include
-#include "applicationwindow.h"
-#include "bottombar.h"
-#include "database_manager.hpp"
-#include "login_window.h"
#include "lr_dao.hpp"
-#include "mainwindow.h"
-#include "notelist.h"
-#include "registration_window.h"
+#include "login_window.h"
+#include "style_manager.h"
+#include "language_manager.h"
#include "registration_window_style_sheet.h"
+#include
RegistrationWindow::RegistrationWindow(QWidget *parent)
: QWidget(parent), ui(new Ui::RegistrationWindow) {
ui->setupUi(this);
-
setFixedSize(380, 480);
- ui->createLogin->setPlaceholderText("Введите логин:");
- ui->createPassword->setPlaceholderText("Введите пароль:");
- ui->repeatPassword->setPlaceholderText("Повторите пароль:");
- setStyleSheet(Ui::registration_window_light_theme);
- ui->createPassword->setEchoMode(QLineEdit::Password);
- ui->repeatPassword->setEchoMode(QLineEdit::Password);
+ ui->create_login->setPlaceholderText(tr("Введите логин:"));
+ ui->create_password->setPlaceholderText(tr("Введите пароль:"));
+ ui->repeat_password->setPlaceholderText(tr("Повторите пароль:"));
+ ui->create_password->setEchoMode(QLineEdit::Password);
+ ui->repeat_password->setEchoMode(QLineEdit::Password);
- connect(
- ui->pushRegistration, &QPushButton::clicked, this,
- &RegistrationWindow::on_push_registration_clicked
- );
- connect(
- ui->switchMode, &QPushButton::clicked, this,
- &RegistrationWindow::on_switch_mode_clicked
+ setAttribute(Qt::WA_StyledBackground, true);
+
+ connect(ui->push_registration, &QPushButton::clicked, this,
+ &RegistrationWindow::on_push_registration_clicked, Qt::UniqueConnection);
+ connect(ui->switch_mode, &QPushButton::clicked, this,
+ &RegistrationWindow::on_switch_mode_clicked, Qt::UniqueConnection);
+ connect(ui->switch_theme, &QPushButton::clicked, this,
+ &RegistrationWindow::on_switch_language_clicked, Qt::UniqueConnection);
+
+ connect(LanguageManager::instance(), &LanguageManager::language_changed,
+ this, &RegistrationWindow::handle_language_changed
);
+ handle_language_changed(LanguageManager::instance()->current_language());
+ this->setStyleSheet(Ui::registration_window_light_autumn_theme);
}
-RegistrationWindow::~RegistrationWindow() {
- delete ui;
+void RegistrationWindow::handle_language_changed(std::string new_language) {
+ if (new_language == "RU") {
+ ui->create_login->setPlaceholderText(tr("Введите логин:"));
+ ui->registration_label->setText(tr("Регистрация"));
+ ui->create_password->setPlaceholderText(tr("Введите пароль:"));
+ ui->repeat_password->setPlaceholderText(tr("Повторите пароль:"));
+ ui->switch_mode->setText(tr("Уже есть аккаунт? Войдите!"));
+ ui->switch_theme->setText(tr("RU"));
+ ui->push_registration->setText(tr("Зарегистрироваться"));
+ }
+ else if (new_language == "EN") {
+ ui->create_login->setPlaceholderText(tr("Enter login:"));
+ ui->registration_label->setText(tr("Registration"));
+ ui->create_password->setPlaceholderText(tr("Enter password:"));
+ ui->repeat_password->setPlaceholderText(tr("Repeat password:"));
+ ui->switch_mode->setText(tr("Already have an account? Login!"));
+ ui->switch_theme->setText(tr("EN"));
+ ui->push_registration->setText(tr("Register"));
+ }
}
-void RegistrationWindow::on_switch_mode_clicked() {
- QWidget *parent = this->parentWidget();
-
- QMainWindow *app_window = qobject_cast(parent);
-
- if (QWidget *old = app_window->centralWidget()) {
- old->deleteLater();
+void RegistrationWindow::on_switch_language_clicked() {
+ if (ui->switch_theme->text() == tr("RU")) {
+ ui->switch_theme->setText(tr("EN"));
+ LanguageManager::instance()->apply_language("EN");
+ } else {
+ ui->switch_theme->setText(tr("RU"));
+ LanguageManager::instance()->apply_language("RU");
}
- project_storage_model::Storage storage;
- LoginWindow *login_window = new LoginWindow(app_window);
+}
- app_window->setCentralWidget(login_window);
- QRect screenGeometry = QApplication::primaryScreen()->availableGeometry();
- int x = (screenGeometry.width() - login_window->width()) / 2;
- int y = (screenGeometry.height() - login_window->height()) / 2;
- app_window->move(x, y);
+RegistrationWindow::~RegistrationWindow() = default;
- this->close();
+void RegistrationWindow::on_switch_mode_clicked() {
+ if (QMainWindow *app_window = qobject_cast(this->parentWidget())) {
+ if (QWidget *old = app_window->centralWidget()) {
+ old->deleteLater();
+ }
+
+ LoginWindow *login_window = new LoginWindow(app_window);
+ app_window->setCentralWidget(login_window);
+
+ QRect screen_geometry = QApplication::primaryScreen()->availableGeometry();
+ app_window->move(
+ (screen_geometry.width() - login_window->width()) / 2,
+ (screen_geometry.height() - login_window->height()) / 2
+ );
+
+ this->close();
+ }
}
bool RegistrationWindow::is_strong_and_valid_password(const QString &password) {
+ std::string lang = LanguageManager::instance()->current_language();
+
if (password.length() < 8) {
- QMessageBox::warning(
- nullptr, "Ошибка: недостаточно надежный пароль",
- "Пароль должен содержать не менее восьми символов"
- );
+ if (lang == "RU") {
+ QMessageBox::warning(nullptr, "Ошибка: недостаточно надежный пароль", "Пароль должен содержать не менее восьми символов");
+ } else {
+ QMessageBox::warning(nullptr, "Error: Weak Password", "Password must be at least 8 characters long");
+ }
return false;
}
bool has_digit = false;
bool has_latin_letter = false;
- for (const QChar ch : password) {
+ for (const QChar &ch : password) {
if (!ch.isLetter() && !ch.isDigit()) {
- QMessageBox::warning(
- nullptr, "Ошибка",
- "Пароль должен содержать только символы латиницы и цифры"
- );
+ if (lang == "RU") {
+ QMessageBox::warning(nullptr, "Ошибка", "Пароль должен содержать только символы латиницы и цифры");
+ } else {
+ QMessageBox::warning(nullptr, "Error", "Password must contain only Latin letters and digits");
+ }
return false;
} else if (ch.isLetter()) {
has_latin_letter = true;
@@ -90,17 +118,20 @@ bool RegistrationWindow::is_strong_and_valid_password(const QString &password) {
}
if (!has_latin_letter) {
- QMessageBox::warning(
- nullptr, "Ошибка: недостаточно надежный пароль",
- "Пароль должен содержать хотя бы одну букву"
- );
+ if (lang == "RU") {
+ QMessageBox::warning(nullptr, "Ошибка: недостаточно надежный пароль", "Пароль должен содержать хотя бы одну букву");
+ } else {
+ QMessageBox::warning(nullptr, "Error: Weak Password", "Password must contain at least one letter");
+ }
return false;
}
+
if (!has_digit) {
- QMessageBox::warning(
- nullptr, "Ошибка: недостаточно надежный пароль",
- "Пароль должен содержать хотя бы одну цифру"
- );
+ if (lang == "RU") {
+ QMessageBox::warning(nullptr, "Ошибка: недостаточно надежный пароль", "Пароль должен содержать хотя бы одну цифру");
+ } else {
+ QMessageBox::warning(nullptr, "Error: Weak Password", "Password must contain at least one digit");
+ }
return false;
}
@@ -108,47 +139,77 @@ bool RegistrationWindow::is_strong_and_valid_password(const QString &password) {
}
void RegistrationWindow::on_push_registration_clicked() {
- QString created_login = ui->createLogin->text();
- QString created_password = ui->createPassword->text();
- QString repeated_password = ui->repeatPassword->text();
+ if ((this->counter_on_switch_theme_clicks++) % 2) {
+ QString created_login = ui->create_login->text().trimmed();
+ QString created_password = ui->create_password->text();
+ QString repeated_password = ui->repeat_password->text();
+
+ std::string lang = LanguageManager::instance()->current_language();
+
+ if (created_login.isEmpty() || created_password.isEmpty() || repeated_password.isEmpty()) {
+ if (lang == "RU") {
+ QMessageBox::warning(this, "Ошибка", "Пожалуйста, заполните все поля.");
+ } else {
+ QMessageBox::warning(this, "Error", "Please fill in all the fields.");
+ }
+ return;
+ }
- if (!created_login.isEmpty() && !created_password.isEmpty() &&
- !repeated_password.isEmpty()) {
if (created_password != repeated_password) {
- QMessageBox::warning(this, "Ошибка", "Пароли не совпадают!");
- } else if (created_login.size() > 50) {
- QMessageBox::warning(
- this, "Ошибка",
- "Длина логина не должна превышать пятидесяти символов"
- );
- } else if (created_password.size() > 50) {
- QMessageBox::warning(
- this, "Ошибка",
- "Длина пароля не должна превышать пятидесяти символов"
- );
- } else if (is_strong_and_valid_password(created_password)) {
- int try_register_user =
- LRDao::try_register_user(created_login, created_password);
- if (try_register_user == 0) {
- QMessageBox::warning(
- this, "Ошибка",
- "Извините, разрабы дауны и не подключили толком бд."
- );
- } else if (try_register_user == -1) {
- QMessageBox::warning(
- this, "Ошибка",
- "Пользователь с таким именем уже существует. Пожалуйста, "
- "придумайте другое!"
- );
+ if (lang == "RU") {
+ QMessageBox::warning(this, "Ошибка", "Пароли не совпадают!");
} else {
- QMessageBox::information(
- this, "Регистрация",
- "Вы успешно зарегистрировались! Пожалуйста, выполните вход."
- );
- on_switch_mode_clicked(); // TODO: fix
+ QMessageBox::warning(this, "Error", "Passwords do not match!");
}
+ return;
+ }
+
+ if (created_login.size() > 50) {
+ if (lang == "RU") {
+ QMessageBox::warning(this, "Ошибка", "Длина логина не должна превышать пятидесяти символов");
+ } else {
+ QMessageBox::warning(this, "Error", "Login must not exceed fifty characters.");
+ }
+ return;
+ }
+
+ if (created_password.size() > 50) {
+ if (lang == "RU") {
+ QMessageBox::warning(this, "Ошибка", "Длина пароля не должна превышать пятидесяти символов");
+ } else {
+ QMessageBox::warning(this, "Error", "Password must not exceed fifty characters.");
+ }
+ return;
+ }
+
+ if (!is_strong_and_valid_password(created_password)) {
+ return;
+ }
+
+ int try_register_user = LRDao::try_register_user(created_login, created_password);
+ switch (try_register_user) {
+ case 0:
+ if (lang == "RU") {
+ QMessageBox::warning(this, "Ошибка", "Извините, внутренняя ошибка с базами данных.");
+ } else {
+ QMessageBox::warning(this, "Error", "Sorry, an internal database error occurred.");
+ }
+ break;
+ case -1:
+ if (lang == "RU") {
+ QMessageBox::warning(this, "Ошибка", "Пользователь с таким именем уже существует. Пожалуйста, придумайте другое!");
+ } else {
+ QMessageBox::warning(this, "Error", "A user with this name already exists. Please choose a different one!");
+ }
+ break;
+ default:
+ if (lang == "RU") {
+ QMessageBox::information(this, "Регистрация", "Вы успешно зарегистрировались! Пожалуйста, выполните вход.");
+ } else {
+ QMessageBox::information(this, "Registration", "You have successfully registered! Please log in.");
+ }
+ on_switch_mode_clicked();
+ break;
}
- } else {
- QMessageBox::warning(this, "Ошибка", "Пожалуйста, заполните все поля.");
}
-}
\ No newline at end of file
+}
diff --git a/ui/authorization-windows/ui/login_window.ui b/ui/authorization-windows/ui/login_window.ui
index 02ffce3..a9ea57e 100644
--- a/ui/authorization-windows/ui/login_window.ui
+++ b/ui/authorization-windows/ui/login_window.ui
@@ -22,7 +22,7 @@
501
-
+
120
@@ -39,10 +39,10 @@ border-radius: 10px;
Войти
-
+
- 140
+ 133
130
91
41
@@ -55,7 +55,7 @@ border-radius: 10px;
Вход
-
+
62
@@ -71,7 +71,7 @@ border-radius: 10px;
Логин
-
+
62
@@ -87,7 +87,7 @@ border-radius: 10px;
Пароль
-
+
80
@@ -104,6 +104,28 @@ border-radius: 10px;
Еще нет аккаунта? Зарегистрируйтесь!
+
+
+
+ 350
+ 455
+ 20
+ 20
+
+
+
+
+ 20
+ 20
+
+
+
+
+ 20
+ 20
+
+
+
-
+
110
@@ -47,7 +69,7 @@ border-radius: 10px;
Уже есть аккаунт? Войдите!
-
+
60
@@ -57,7 +79,7 @@ border-radius: 10px;
-
+
60
@@ -67,7 +89,7 @@ border-radius: 10px;
-
+
60
@@ -77,10 +99,10 @@ border-radius: 10px;
-
+
- 100
+ 94
90
201
51
diff --git a/ui/language-manager/CMakeLists.txt b/ui/language-manager/CMakeLists.txt
new file mode 100644
index 0000000..151f92e
--- /dev/null
+++ b/ui/language-manager/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(LanguageManager LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Qt6 COMPONENTS Core Gui Widgets Core Gui Sql REQUIRED)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+
+set(SOURCES
+ src/language_manager.cpp
+)
+
+set(HEADERS
+ include/language_manager.h
+)
+
+add_library(LanguageManager STATIC ${SOURCES} ${HEADERS})
+
+target_include_directories(LanguageManager
+ PUBLIC
+ $
+ $
+)
+
+target_link_libraries(LanguageManager PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui Qt6::Sql Database Scripts)
+
diff --git a/ui/language-manager/include/language_manager.h b/ui/language-manager/include/language_manager.h
new file mode 100644
index 0000000..88ee68d
--- /dev/null
+++ b/ui/language-manager/include/language_manager.h
@@ -0,0 +1,29 @@
+#ifndef style_manager_H
+#define style_manager_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+class LanguageManager : public QObject {
+ Q_OBJECT
+
+public:
+ static LanguageManager* instance();
+
+ void apply_language(std::string new_language_);
+ std::string current_language() const;
+
+signals:
+ void language_changed(std::string new_language_);
+
+private:
+ explicit LanguageManager(QObject *parent = nullptr);
+ static LanguageManager* m_instance;
+ std::string current_language_;
+};
+
+#endif // style_manager_H
\ No newline at end of file
diff --git a/ui/language-manager/src/language_manager.cpp b/ui/language-manager/src/language_manager.cpp
new file mode 100644
index 0000000..f0b52ea
--- /dev/null
+++ b/ui/language-manager/src/language_manager.cpp
@@ -0,0 +1,28 @@
+#include "language_manager.h"
+#include
+#include
+#include
+
+LanguageManager* LanguageManager::m_instance = nullptr;
+
+LanguageManager::LanguageManager(QObject *parent)
+ : QObject(parent) {
+ std::string language = "RU";
+ apply_language(language);
+}
+
+LanguageManager* LanguageManager::instance() {
+ if (!m_instance) {
+ m_instance = new LanguageManager();
+ }
+ return m_instance;
+}
+
+void LanguageManager::apply_language(std::string new_language_) {
+ this->current_language_ = new_language_;
+ emit language_changed(this->current_language_);
+}
+
+std::string LanguageManager::current_language() const {
+ return current_language_;
+}
\ No newline at end of file
diff --git a/ui/main-window/CMakeLists.txt b/ui/main-window/CMakeLists.txt
index c8e1f85..c36aa37 100644
--- a/ui/main-window/CMakeLists.txt
+++ b/ui/main-window/CMakeLists.txt
@@ -36,4 +36,8 @@ target_link_libraries(MainWindow PRIVATE
Scripts
Database
NoteWidget
+ StyleManager
+ ProfileWindow
+ AuthorizationWindows
+ LanguageManager
)
\ No newline at end of file
diff --git a/ui/main-window/include/bottombar.h b/ui/main-window/include/bottombar.h
index cc7945c..8ac2cb7 100644
--- a/ui/main-window/include/bottombar.h
+++ b/ui/main-window/include/bottombar.h
@@ -3,21 +3,30 @@
#include
#include
+#include
+#include
#include
#include
namespace Ui {
class BottomBar : public QWidget {
- QHBoxLayout *main_layout_;
- QLabel *project_name_;
- QLabel *username_;
+ Q_OBJECT
public:
BottomBar(
- QWidget *parent_,
- std::string username_,
- std::string project_name_
+ QWidget *parent,
+ const std::string &username,
+ QString project_name
);
+
+signals:
+ void profile_button_clicked();
+
+private:
+ QHBoxLayout *main_layout_;
+ QLabel *project_name_;
+ QLabel *username_;
+ QPushButton *profile_button_;
};
} // namespace Ui
diff --git a/ui/main-window/include/main_window_style.hpp b/ui/main-window/include/main_window_style.hpp
index 3e594c1..5651dc5 100644
--- a/ui/main-window/include/main_window_style.hpp
+++ b/ui/main-window/include/main_window_style.hpp
@@ -4,7 +4,7 @@
namespace Ui {
-QString main_window_style = R"(
+QString main_window_light_autumn_theme = R"(
#main-window {
background-color : #f5f5f5;
}
@@ -14,22 +14,31 @@ QString main_window_style = R"(
}
QScrollBar:vertical {
+ width: 7px;
+}
+QScrollBar:horizontal {
+ height: 7px;
+}
+QScrollBar:vertical, QScrollBar:horizontal {
border: none;
background: transparent;
- width: 10px;
margin: 0;
}
-QScrollBar::handle:vertical {
+QScrollBar::handle:vertical, QScrollBar::handle:horizontal {
background: #c0c0c0;
- border-radius: 5px;
+ border-radius: 3px;
min-height: 20px;
+ min-width: 20px;
}
-
QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical,
- QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {
- background: none;
- height: 0px;
- }
+QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal,
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical,
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
+ background: none;
+ height: 0;
+ width: 0;
+}
+
QScrollArea {
border: none;
background: transparent;
@@ -42,7 +51,7 @@ QScrollArea {
outline: 0;
font-family: 'Arial';
font-weight: bold;
- font-size: 14px;
+ font-size: 13px;
color:rgb(44, 44, 44);
}
@@ -64,30 +73,37 @@ QScrollArea {
}
#ProjectList QScrollBar:vertical {
+ width: 7px;
+}
+#ProjectList QScrollBar:horizontal {
+ height: 7px;
+}
+#ProjectList QScrollBar:vertical,
+#ProjectList QScrollBar:horizontal {
border: none;
- background: #FED6BC;
- width: 10px;
+ background: transparent;
margin: 0;
}
-
-#ProjectList QScrollBar::handle:vertical {
+#ProjectList QScrollBar::handle:vertical,
+#ProjectList QScrollBar::handle:horizontal {
background: #c0c0c0;
- border-radius: 5px;
+ border-radius: 3px;
min-height: 20px;
+ min-width: 20px;
}
-
#ProjectList QScrollBar::add-line:vertical,
-#ProjectList QScrollBar::sub-line:vertical {
- background: none;
-}
-
+#ProjectList QScrollBar::sub-line:vertical,
+#ProjectList QScrollBar::add-line:horizontal,
+#ProjectList QScrollBar::sub-line:horizontal,
#ProjectList QScrollBar::add-page:vertical,
-#ProjectList QScrollBar::sub-page:vertical {
+#ProjectList QScrollBar::sub-page:vertical,
+#ProjectList QScrollBar::add-page:horizontal,
+#ProjectList QScrollBar::sub-page:horizontal {
background: none;
}
#BottomBar {
- background-color: rgb(33, 44, 50);
+ background-color: #212c32;
border-radius: 8px;
padding: 8px;
outline: 0;
@@ -96,12 +112,66 @@ QScrollArea {
#BottomBar QLabel {
color : white;
font-family: 'Arial';
- font-size: 14px;
+ font-size: 13px;
+}
+
+#BottomBar QPushButton {
+ background-color: transparent;
+ color: white;
+ font-family: 'Arial';
+ font-size: 13px;
+ padding: 0px 0px;
+ min-width: 0px;
+ min-height: 0px;
+}
+
+#BottomBar QPushButton:hover {
+ color:rgb(182, 181, 181);
+ font-family: 'Arial';
+ font-size: 13px;
+}
+
+QTabWidget {
+ background-color: white;
+ border-radius: 8px;
+ padding: 5px;
+}
+
+QTabWidget::pane {
+ background-color: white;
+ border-radius: 8px;
+ margin-top: 5px;
+}
+
+QTabBar::tab {
+ color: rgb(33, 44, 50);
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ background: #e0e0e0;
+ padding: 6px 8px;
+ border-top-right-radius: 4px;
+ border-top-left-radius: 4px;
+ margin-right: 2px;
+}
+
+QTabBar::tab:hover {
+ background: #e8e8e8;
+}
+
+QTabBar::tab:selected {
+ background: white;
+ border-bottom-color: white;
+}
+
+QTabBar::tab:pressed {
+ background: white;
+ border-bottom-color: white;
}
#NoteList {
- border-radius : 8px;
background-color: white;
+ border-radius: 8px;
}
#NoteWidget {
@@ -119,6 +189,10 @@ QScrollArea {
padding: 5px 10px;
}
+#NoteWidget QPushButton:hover {
+ background-color:rgb(213, 167, 88);
+}
+
QPushButton {
font-family: 'Arial';
font-size: 13px;
@@ -126,13 +200,820 @@ QPushButton {
border-radius: 10px;
background-color: #fea36b;
color: white;
+ padding: 10px 10px;
+ min-width: 40px;
+}
+
+QPushButton::hover {
+ background-color:rgb(245, 148, 89);
+}
+
+QPushButton::pressed {
+ background-color:rgb(238, 122, 50);
+}
+
+QPushButton#switch_theme_button_ {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ border-radius: 7px;
+ padding: 0;
+ margin-bottom: 2px;
+ border: 2px solid #fea36b;
+ background-color: transparent;
+}
+QPushButton::hover#switch_theme_button_ {
+ background-color: #fea36b;
+}
+QPushButton::pressed#switch_theme_button_ {
+ background-color: rgb(185, 117, 61);
+}
+)";
+
+QString main_window_dark_autumn_theme = R"(
+ #main-window {
+ background-color: #202020;
+ }
+
+ #main-window QLabel {
+ font-weight: bold;
+ color: #BDD1BD;
+ }
+
+ QScrollBar:vertical {
+ width: 7px;
+ }
+ QScrollBar:horizontal {
+ height: 7px;
+ }
+ QScrollBar:vertical, QScrollBar:horizontal {
+ border: none;
+ background: transparent;
+ margin: 0;
+ }
+ QScrollBar::handle:vertical, QScrollBar::handle:horizontal {
+ background: #c0c0c0;
+ border-radius: 3px;
+ min-height: 20px;
+ min-width: 20px;
+ }
+ QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical,
+ QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal,
+ QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical,
+ QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
+ background: none;
+ height: 0;
+ width: 0;
+ }
+
+ QScrollArea {
+ border: none;
+ background: transparent;
+ }
+
+ #ProjectList {
+ background-color: black;
+ border-radius: 8px;
+ padding: 8px;
+ outline: 0;
+ font-family: 'Arial';
+ font-weight: bold;
+ font-size: 13px;
+ color: #BDD1BD;
+ }
+
+ #ProjectList::item {
+ background-color: rgb(32, 53, 51);
+ color: #ffffff;
+ border: none;
+ padding: 10px;
+ margin: 2px;
+ border-radius: 6px;
+ }
+
+ #ProjectList::item:hover {
+ background-color: rgb(64, 89, 87);
+ }
+
+ #ProjectList::item:selected {
+ background-color: #089083;
+ color: rgb(33, 44, 50);
+ }
+
+ #ProjectList QScrollBar:vertical {
+ width: 7px;
+ }
+ #ProjectList QScrollBar:horizontal {
+ height: 7px;
+ }
+ #ProjectList QScrollBar:vertical,
+ #ProjectList QScrollBar:horizontal {
+ border: none;
+ background: transparent;
+ margin: 0;
+ }
+ #ProjectList QScrollBar::handle:vertical,
+ #ProjectList QScrollBar::handle:horizontal {
+ background: #c0c0c0;
+ border-radius: 3px;
+ min-height: 20px;
+ min-width: 20px;
+ }
+ #ProjectList QScrollBar::add-line:vertical,
+ #ProjectList QScrollBar::sub-line:vertical,
+ #ProjectList QScrollBar::add-line:horizontal,
+ #ProjectList QScrollBar::sub-line:horizontal,
+ #ProjectList QScrollBar::add-page:vertical,
+ #ProjectList QScrollBar::sub-page:vertical,
+ #ProjectList QScrollBar::add-page:horizontal,
+ #ProjectList QScrollBar::sub-page:horizontal {
+ background: none;
+ }
+
+ #BottomBar {
+ background-color:rgb(0, 0, 0);
+ border-radius: 8px;
+ padding: 8px;
+ outline: 0;
+ }
+
+ #BottomBar QLabel {
+ color: #c0c0c0;
+ font-family: 'Arial';
+ font-size: 13px;
+ }
+
+ #BottomBar QPushButton {
+ background-color: transparent;
+ color: #c0c0c0;
+ font-family: 'Arial';
+ font-size: 13px;
+ padding: 0px 0px;
+ min-width: 0px;
+ min-height: 0px;
+ }
+
+ #BottomBar QPushButton:hover {
+ color:rgb(236, 234, 234);
+ font-family: 'Arial';
+ font-size: 13px;
+ }
+
+
+ #NoteList {
+ border-radius: 8px;
+ background-color: black;
+ }
+
+ #NoteWidget {
+ background-color:rgb(179, 156, 116);
+ border-radius: 8px;
+ }
+
+ #NoteWidget QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ background-color: #ffdda2;
+ color: #202020;
+ padding: 5px 10px;
+ }
+
+ #NoteWidget QPushButton:hover {
+ background-color:rgb(255, 236, 203);
+ }
+
+ QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ background-color:rgb(211, 139, 95);
+ color: #263238;
+ padding: 10px 10px;
+ min-width: 40px;
+
+ }
+
+ QPushButton:hover {
+ background-color:rgb(181, 114, 59);
+ }
+
+ QPushButton:pressed {
+ background-color:rgb(143, 88, 44);
+ }
+
+ QPushButton#switch_theme_button_ {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ border-radius: 7px;
+ padding: 0;
+ margin-bottom: 2px;
+ border: 2px solid rgb(211, 139, 95);
+ background-color: transparent;
+ }
+ QPushButton::hover#switch_theme_button_ {
+ background-color: rgb(211, 139, 95);
+ }
+ QPushButton::pressed#switch_theme_button_ {
+ background-color: rgb(211, 139, 95);
+ }
+ )";
+
+QString main_window_light_purple_theme = R"(
+#main-window {
+ background: #9882B9;
+}
+
+#main-window QLabel {
+ font-weight: bold;
+ color: rgb(42, 10, 25);
+}
+
+QScrollBar:vertical {
+ width: 7px;
+}
+QScrollBar:horizontal {
+ height: 7px;
+}
+QScrollBar:vertical, QScrollBar:horizontal {
+ border: none;
+ background: transparent;
+ margin: 0;
+}
+QScrollBar::handle:vertical, QScrollBar::handle:horizontal {
+ background: white;
+ border-radius: 3px;
+ min-height: 20px;
+ min-width: 20px;
+}
+QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical,
+QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal,
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical,
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
+ background: none;
+ height: 0;
+ width: 0;
+}
+
+QScrollArea {
+ border: none;
+ background: transparent;
+}
+
+#ProjectList {
+ background-color: rgb(221, 210, 238);
+ border-radius: 8px;
+ padding: 8px;
+ outline: 0;
+ font-family: 'Arial';
+ font-weight: bold;
+ font-size: 13px;
+ color: rgb(42, 10, 25);
+}
+
+#ProjectList::item {
+ background-color: rgb(206, 193, 224);
+ border: none;
+ padding: 10px;
+ margin: 2px;
+ border-radius: 6px;
+}
+
+#ProjectList::item:hover {
+ background-color: rgb(163, 148, 184);
+}
+
+#ProjectList::item:selected {
+ background-color:rgb(121, 103, 148);
+ color: rgb(221, 210, 238);
+}
+
+#ProjectList QScrollBar:vertical {
+ width: 7px;
+}
+#ProjectList QScrollBar:horizontal {
+ height: 7px;
+}
+#ProjectList QScrollBar:vertical,
+#ProjectList QScrollBar:horizontal {
+ border: none;
+ background: transparent;
+ margin: 0;
+}
+#ProjectList QScrollBar::handle:vertical,
+#ProjectList QScrollBar::handle:horizontal {
+ background: white;
+ border-radius: 3px;
+ min-height: 20px;
+ min-width: 20px;
+}
+#ProjectList QScrollBar::add-line:vertical,
+#ProjectList QScrollBar::sub-line:vertical,
+#ProjectList QScrollBar::add-line:horizontal,
+#ProjectList QScrollBar::sub-line:horizontal,
+#ProjectList QScrollBar::add-page:vertical,
+#ProjectList QScrollBar::sub-page:vertical,
+#ProjectList QScrollBar::add-page:horizontal,
+#ProjectList QScrollBar::sub-page:horizontal {
+ background: none;
+}
+
+#BottomBar {
+ background-color: rgb(42, 10, 25);
+ border-radius: 8px;
+ padding: 8px;
+ outline: 0;
+}
+
+#BottomBar QLabel {
+ color: #9882B9;
+ font-family: 'Arial';
+ font-size: 13px;
+}
+
+#BottomBar QPushButton {
+ background-color: transparent;
+ color: #9882B9;
+ font-family: 'Arial';
+ font-size: 13px;
+ padding: 0px 0px;
+ min-width: 0px;
+ min-height: 0px;
+}
+
+#BottomBar QPushButton:hover {
+ color:rgb(208, 193, 231);
+ font-family: 'Arial';
+ font-size: 13px;
+}
+
+
+
+#NoteList {
+ border-radius: 8px;
+ background-color: rgb(221, 210, 238);
+}
+
+#NoteWidget {
+ background-color: #D4A5C9;
+ border-radius: 8px;
+}
+
+#NoteWidget QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ background-color: #C98BB8;
+ color: rgb(42, 10, 25);
+ padding: 5px 10px;
+}
+
+#NoteWidget QPushButton:hover {
+ background-color:rgb(134, 82, 120);
+}
+
+QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ background-color: #722548;
+ color: #9882B9;
+ padding: 10px 10px;
+ min-width: 40px;
+
+}
+
+QPushButton:hover {
+ background-color:rgb(69, 24, 44);
+}
+
+QPushButton:pressed {
+ background-color:rgb(47, 16, 30);
+}
+
+QPushButton#switch_theme_button_ {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ border-radius: 7px;
+ padding: 0;
+ margin-bottom: 2px;
+ border: 2px solid #722548;
+ background-color: transparent;
+}
+
+QPushButton::hover#switch_theme_button_ {
+ background-color:rgb(86, 26, 53);
+}
+QPushButton::pressed#switch_theme_button_ {
+ background-color: rgb(80, 27, 51);
+}
+)";
+
+QString main_window_dark_purple_theme = R"(
+#main-window {
+ background-color: rgb(9, 6, 10);
+}
+
+#main-window QLabel {
+ font-weight: bold;
+ color: #9882B9;
+}
+
+QScrollBar:vertical {
+ width: 7px;
+}
+QScrollBar:horizontal {
+ height: 7px;
+}
+QScrollBar:vertical, QScrollBar:horizontal {
+ border: none;
+ background: transparent;
+ margin: 0;
+}
+QScrollBar::handle:vertical, QScrollBar::handle:horizontal {
+ background: #775E88;
+ border-radius: 3px;
+ min-height: 20px;
+ min-width: 20px;
+}
+QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical,
+QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal,
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical,
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
+ background: none;
+ height: 0;
+ width: 0;
+}
+
+QScrollArea {
+ border: none;
+ background: transparent;
+}
+
+#ProjectList {
+ background-color: #221932;
+ border-radius: 8px;
+ padding: 8px;
+ outline: 0;
+ font-family: 'Arial';
+ font-weight: bold;
+ font-size: 13px;
+ color: #9882B9;
+}
+
+#ProjectList::item {
+ background-color:rgb(50, 41, 66);
+ border: none;
+ padding: 10px;
+ margin: 2px;
+ border-radius: 6px;
+}
+
+#ProjectList::item:hover {
+ background-color:rgb(97, 82, 123);
+}
+
+#ProjectList::item:selected {
+ background-color:rgb(205, 146, 172);
+ color: #221932;
+}
+
+#ProjectList QScrollBar:vertical {
+ width: 7px;
+}
+#ProjectList QScrollBar:horizontal {
+ height: 7px;
+}
+#ProjectList QScrollBar:vertical,
+#ProjectList QScrollBar:horizontal {
+ border: none;
+ background: transparent;
+ margin: 0;
+}
+#ProjectList QScrollBar::handle:vertical,
+#ProjectList QScrollBar::handle:horizontal {
+ background: #775E88;
+ border-radius: 3px;
+ min-height: 20px;
+ min-width: 20px;
+}
+#ProjectList QScrollBar::add-line:vertical,
+#ProjectList QScrollBar::sub-line:vertical,
+#ProjectList QScrollBar::add-line:horizontal,
+#ProjectList QScrollBar::sub-line:horizontal,
+#ProjectList QScrollBar::add-page:vertical,
+#ProjectList QScrollBar::sub-page:vertical,
+#ProjectList QScrollBar::add-page:horizontal,
+#ProjectList QScrollBar::sub-page:horizontal {
+ background: none;
+}
+
+#BottomBar {
+ background-color: #221932;
+ border-radius: 8px;
+ padding: 8px;
+ outline: 0;
+}
+
+#BottomBar QLabel {
+ color: #9882B9;
+ font-family: 'Arial';
+ font-size: 13px;
+}
+
+#BottomBar QPushButton {
+ background-color: transparent;
+ color: #9882B9;
+ font-family: 'Arial';
+ font-size: 13px;
+ padding: 0px 0px;
+ min-width: 0px;
+ min-height: 0px;
+}
+
+#BottomBar QPushButton:hover {
+ color:rgb(198, 183, 221);
+ font-family: 'Arial';
+ font-size: 13px;
+}
+
+#NoteList {
+ border-radius: 8px;
+ background-color: #221932;
+}
+
+#NoteWidget {
+ background-color: #9882B9;
+ border-radius: 8px;
+}
+
+#NoteWidget QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ background-color:rgb(113, 97, 137);
+ color: #221932;
padding: 5px 10px;
- min-width: 60px;
- min-height: 25px;
}
+#NoteWidget QPushButton:hover {
+ background-color:rgb(69, 58, 87);
+}
+
+QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ background-color: #722548;
+ color: #060407;
+ padding: 10px 10px;
+ min-width: 40px;
+
+}
+
+QPushButton:hover {
+ background-color: rgb(79, 25, 50);
+}
+
+QPushButton:pressed {
+ background-color:rgb(59, 16, 35);
+}
+QPushButton#switch_theme_button_ {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ border-radius: 7px;
+ padding: 0;
+ margin-bottom: 2px;
+ border: 2px solid #722548;
+ background-color: transparent;
+}
+QPushButton::hover#switch_theme_button_ {
+ background-color: #722548;
+}
+QPushButton::pressed#switch_theme_button_ {
+ background-color:rgb(80, 27, 51);
+}
)";
+QString main_window_blue_theme = R"(
+#main-window {
+ background: #173C4C;
+}
+
+#main-window QLabel {
+ font-weight: bold;
+ color: #BDD1BD;
+}
+
+QScrollBar:vertical {
+ width: 7px;
+}
+QScrollBar:horizontal {
+ height: 7px;
+}
+QScrollBar:vertical, QScrollBar:horizontal {
+ border: none;
+ background: transparent;
+ margin: 0;
+}
+QScrollBar::handle:vertical, QScrollBar::handle:horizontal {
+ background: rgb(103, 155, 177);
+ border-radius: 3px;
+ min-height: 20px;
+ min-width: 20px;
+}
+QScrollBar::add-line:vertical, QScrollBar::sub-line:vertical,
+QScrollBar::add-line:horizontal, QScrollBar::sub-line:horizontal,
+QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical,
+QScrollBar::add-page:horizontal, QScrollBar::sub-page:horizontal {
+ background: none;
+ height: 0;
+ width: 0;
+}
+
+QScrollArea {
+ border: none;
+ background: transparent;
+}
+
+#ProjectList {
+ background-color: #07142B;
+ border-radius: 8px;
+ padding: 8px;
+ outline: 0;
+ font-family: 'Arial';
+ font-weight: bold;
+ font-size: 13px;
+ color: #BDD1BD;
+ border: 1px solid;
+}
+
+#ProjectList::item {
+ background-color: #173C4C;
+ border: none;
+ padding: 10px;
+ margin: 2px;
+ border-radius: 6px;
+}
+
+#ProjectList::item:hover {
+ background-color:rgb(37, 92, 115);
+}
+
+#ProjectList::item:selected {
+ background-color:rgb(73, 159, 158);
+ color: #07142B;
+}
+
+#ProjectList QScrollBar:vertical {
+ width: 7px;
+}
+#ProjectList QScrollBar:horizontal {
+ height: 7px;
+}
+#ProjectList QScrollBar:vertical,
+#ProjectList QScrollBar:horizontal {
+ border: none;
+ background: transparent;
+ margin: 0;
+}
+#ProjectList QScrollBar::handle:vertical,
+#ProjectList QScrollBar::handle:horizontal {
+ background: rgb(103, 155, 177);
+ border-radius: 3px;
+ min-height: 20px;
+ min-width: 20px;
+}
+#ProjectList QScrollBar::add-line:vertical,
+#ProjectList QScrollBar::sub-line:vertical,
+#ProjectList QScrollBar::add-line:horizontal,
+#ProjectList QScrollBar::sub-line:horizontal,
+#ProjectList QScrollBar::add-page:vertical,
+#ProjectList QScrollBar::sub-page:vertical,
+#ProjectList QScrollBar::add-page:horizontal,
+#ProjectList QScrollBar::sub-page:horizontal {
+ background: none;
+}
+
+#BottomBar {
+ background-color: #07142B;
+ border-radius: 8px;
+ padding: 8px;
+ outline: 0;
+ border: 1px solid;
+}
+
+#BottomBar QLabel {
+ color: #BDD1BD;
+ font-family: 'Arial';
+ font-size: 13px;
+}
+
+#BottomBar QPushButton {
+ background-color: transparent;
+ color: #BDD1BD;
+ font-family: 'Arial';
+ font-size: 13px;
+ padding: 0px 0px;
+ min-width: 0px;
+ min-height: 0px;
+}
+
+#BottomBar QPushButton:hover {
+ color:rgb(238, 242, 238);
+ font-family: 'Arial';
+ font-size: 13px;
+}
+
+#NoteList {
+ border-radius: 8px;
+ background-color: #07142B;
+ border: 1px solid;
+}
+
+#NoteWidget {
+ background-color:rgb(103, 155, 177);
+ border-radius: 8px;
+ border: 1px solid;
+}
+
+#NoteWidget QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ background-color:rgb(61, 104, 122);
+ color: #BDD1BD;
+ padding: 5px 10px;
+}
+
+#NoteWidget QPushButton:hover {
+ background-color:rgb(24, 54, 66);
+}
+
+QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ background-color: #568F7C;
+ color: #07142B;
+ padding: 10px 10px;
+ min-width: 40px;
+
+ border: none;
+}
+
+QPushButton:hover {
+ background-color: #326D6C;
+}
+
+QPushButton:pressed {
+ background-color: #173C4C;
+}
+
+QPushButton#switch_theme_button_ {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ border-radius: 7px;
+ padding: 0;
+ margin-bottom: 2px;
+ border: 2px solid #568F7C;
+ background-color: transparent;
+}
+
+QPushButton::hover#switch_theme_button_ {
+ background-color: #568F7C;
+}
+QPushButton::pressed#switch_theme_button_ {
+ background-color:rgb(68, 107, 94);
+}
+)";
} // namespace Ui
diff --git a/ui/main-window/include/mainwindow.h b/ui/main-window/include/mainwindow.h
index e5242f7..24fb581 100644
--- a/ui/main-window/include/mainwindow.h
+++ b/ui/main-window/include/mainwindow.h
@@ -6,22 +6,34 @@
#include
#include
#include
+#include
#include
#include
+#include
#include "bottombar.h"
#include "notelist.h"
+#include "profile_window.h"
#include "projectlist.h"
#include "storage.hpp"
+namespace Ui {
+class MainWindow;
+}
+
namespace Ui {
class MainWindow : public QWidget {
Q_OBJECT
std::string username;
+ std::string font_size_ = "medium";
QVBoxLayout *main_layout_;
+ QTabWidget *tab_widget_;
BottomBar *top_bar_;
QHBoxLayout *content_layout_;
ProjectList *project_list_;
- NoteList *note_list_;
+ NoteList *actual_notes_;
+ NoteList *overdue_notes_;
+ NoteList *completed_notes_;
+ NoteList *deleted_notes_;
QWidget *content_widget_;
QPushButton *new_project_button_;
QPushButton *new_note_button_;
@@ -31,6 +43,10 @@ class MainWindow : public QWidget {
private slots:
void add_project();
void add_note();
+ void on_profile_button_click();
+signals:
+ void logout_requested();
+ void delete_account_requested();
public:
explicit MainWindow(
@@ -38,6 +54,13 @@ private slots:
std::string username = "none",
project_storage_model::Storage *storage = nullptr
);
+ static const std::vector THEMES;
+ void on_logout_button_click();
+ void on_delete_account_button_click();
+ void handle_theme_changed(int theme);
+ void handle_language_changed(std::string new_language);
+ void handle_font_size_changed(std::string font_size_);
+ QScrollArea *create_scroll_area(NoteList *note_list);
};
} // namespace Ui
#endif // MAINWINDOW_H
\ No newline at end of file
diff --git a/ui/main-window/include/notelist.h b/ui/main-window/include/notelist.h
index f406536..534d837 100644
--- a/ui/main-window/include/notelist.h
+++ b/ui/main-window/include/notelist.h
@@ -5,6 +5,8 @@
#include
#include
#include "note.hpp"
+#include "notewidget.h"
+#include "projectitem.h"
namespace Ui {
class NoteList : public QWidget {
@@ -16,11 +18,15 @@ class NoteList : public QWidget {
std::vector vertical_layouts_;
int note_counter_ = 0;
+ const std::string type_;
public:
- void add_note_widget(const project_storage_model::Note *note);
+ void add_note_widget(
+ const project_storage_model::Note *note,
+ QListWidgetItem *p
+ );
void clear_note_list();
- NoteList(QWidget *parent);
+ NoteList(QWidget *parent, const std::string type_);
public slots:
void load_project_notes(QListWidgetItem *project);
diff --git a/ui/main-window/include/notewidget.h b/ui/main-window/include/notewidget.h
index f1f8f6a..a0f31b9 100644
--- a/ui/main-window/include/notewidget.h
+++ b/ui/main-window/include/notewidget.h
@@ -7,6 +7,7 @@
#include
#include
#include "note.hpp"
+#include "projectitem.h"
namespace Ui {
class NoteWidget : public QWidget {
@@ -14,18 +15,30 @@ class NoteWidget : public QWidget {
const project_storage_model::Note *model_note_;
QVBoxLayout *main_layout_;
QPushButton *open_button_;
+ QPushButton *delete_button_;
QLabel *title_label_;
QLabel *text_label_;
public:
explicit NoteWidget(
QWidget *parent = nullptr,
- const project_storage_model::Note *model_note = nullptr
+ const project_storage_model::Note *model_note = nullptr,
+ const std::string type = "actual",
+ QListWidgetItem *p = nullptr
);
+ std::string type_;
+ QListWidgetItem *project_;
+ void handle_font_size_changed(std::string font_size_);
+ void handle_language_changed(std::string new_language);
+ QListWidgetItem *get_project() const;
private slots:
void open_note_window() const;
+ void delete_note();
+ void change_type(std::string new_type);
+signals:
+ void change_type_requested(QListWidgetItem *project);
};
} // namespace Ui
#endif // NOTEWIDGET_H
\ No newline at end of file
diff --git a/ui/main-window/include/projectitem.h b/ui/main-window/include/projectitem.h
index 8b4a4a2..c74ceef 100644
--- a/ui/main-window/include/projectitem.h
+++ b/ui/main-window/include/projectitem.h
@@ -7,10 +7,14 @@
#include "project.hpp"
namespace Ui {
+
+class NoteWidget;
+
class ProjectItem : public QListWidgetItem {
project_storage_model::Project *project_;
- friend NoteList;
+ friend class NoteList;
friend class MainWindow;
+ friend class NoteWidget;
public:
ProjectItem(QListWidget *listview, project_storage_model::Project *project);
diff --git a/ui/main-window/src/bottombar.cpp b/ui/main-window/src/bottombar.cpp
index ee63c71..1407c5d 100644
--- a/ui/main-window/src/bottombar.cpp
+++ b/ui/main-window/src/bottombar.cpp
@@ -1,31 +1,36 @@
#include "bottombar.h"
#include
#include
-#include
-#include
+#include
namespace Ui {
BottomBar::BottomBar(
QWidget *parent,
- std::string username,
- std::string project_name
+ const std::string &username,
+ QString project_name
)
: QWidget(parent),
main_layout_(new QHBoxLayout()),
- username_(new QLabel(username.c_str())),
- project_name_(new QLabel(project_name.c_str())) {
+ project_name_(new QLabel(project_name)),
+ profile_button_(new QPushButton(username.c_str())) {
this->setObjectName("BottomBar");
this->setLayout(main_layout_);
this->setFixedHeight(40);
+ profile_button_->setObjectName("profile_button");
+
project_name_->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
- username_->setAlignment(Qt::AlignVCenter | Qt::AlignRight);
- this->setSizePolicy(
- QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum)
+ main_layout_->addWidget(project_name_);
+ main_layout_->addStretch();
+ main_layout_->addWidget(profile_button_);
+
+ connect(
+ profile_button_, &QPushButton::clicked, this,
+ &BottomBar::profile_button_clicked
);
- main_layout_->addWidget(project_name_);
- main_layout_->addWidget(username_);
+ this->setLayout(main_layout_);
+ this->setAttribute(Qt::WA_StyledBackground);
}
} // namespace Ui
\ No newline at end of file
diff --git a/ui/main-window/src/mainwindow.cpp b/ui/main-window/src/mainwindow.cpp
index 907f902..d956e3e 100644
--- a/ui/main-window/src/mainwindow.cpp
+++ b/ui/main-window/src/mainwindow.cpp
@@ -1,15 +1,22 @@
#include "mainwindow.h"
+#include
#include
#include
#include
#include
+#include
#include
#include
+#include
+#include
#include
#include
-#include
#include
+#include
+#include "applicationwindow.h"
#include "bottombar.h"
+#include "language_manager.h"
+#include "login_window.h"
#include "lr_dao.hpp"
#include "main_window_style.hpp"
#include "note_dao.hpp"
@@ -18,8 +25,17 @@
#include "project_dao.hpp"
#include "projectitem.h"
#include "projectlist.h"
+#include "registration_window.h"
+#include "style_manager.h"
namespace Ui {
+
+const std::vector MainWindow::THEMES = {
+ Ui::main_window_light_autumn_theme, Ui::main_window_dark_autumn_theme,
+ Ui::main_window_dark_purple_theme, Ui::main_window_light_purple_theme,
+ Ui::main_window_blue_theme
+};
+
MainWindow::MainWindow(
QWidget *parent,
std::string username,
@@ -28,41 +44,78 @@ MainWindow::MainWindow(
: QWidget(parent),
username(username),
main_layout_(new QVBoxLayout(this)),
- top_bar_(new BottomBar(this, username, "EFFICIO :: Таск-Трекер")),
+ top_bar_(new BottomBar(this, username, "EFFICIO :: Task-Tracker")),
content_layout_(new QHBoxLayout(this)),
project_list_(new ProjectList(this)),
- note_list_(new NoteList(this)),
+ actual_notes_(new NoteList(this, "actual")),
+ overdue_notes_(new NoteList(this, "overdue")),
+ completed_notes_(new NoteList(this, "completed")),
+ deleted_notes_(new NoteList(this, "deleted")),
content_widget_(new QWidget(this)),
new_project_button_(new QPushButton("Новый проект", this)),
new_note_button_(new QPushButton("Новая заметка", this)),
- storage_(storage) {
+ storage_(storage),
+ tab_widget_(new QTabWidget(this)) {
this->setObjectName("main-window");
this->setAttribute(Qt::WA_StyledBackground);
- this->setMinimumSize(QSize(800, 600));
- this->setStyleSheet(main_window_style);
+
+ tab_widget_->addTab(create_scroll_area(actual_notes_), "Актуальные");
+ tab_widget_->addTab(create_scroll_area(overdue_notes_), "Просроченные");
+ tab_widget_->addTab(create_scroll_area(completed_notes_), "Выполненные");
+ tab_widget_->addTab(create_scroll_area(deleted_notes_), "Удаленные");
+
+ tab_widget_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ actual_notes_->setSizePolicy(
+ QSizePolicy::Expanding, QSizePolicy::Expanding
+ );
+ overdue_notes_->setSizePolicy(
+ QSizePolicy::Expanding, QSizePolicy::Expanding
+ );
+ completed_notes_->setSizePolicy(
+ QSizePolicy::Expanding, QSizePolicy::Expanding
+ );
+ deleted_notes_->setSizePolicy(
+ QSizePolicy::Expanding, QSizePolicy::Expanding
+ );
main_layout_->addWidget(top_bar_, Qt::AlignTop);
main_layout_->setAlignment(Qt::AlignCenter);
- main_layout_->addWidget(content_widget_);
- content_widget_->setLayout(content_layout_);
- auto right_layout = new QVBoxLayout(content_widget_);
+
+ QWidget *right_panel = new QWidget(this);
+ QVBoxLayout *right_layout = new QVBoxLayout(right_panel);
+ // right_layout->setContentsMargins(0, 34, 0, 0); // Верхний отступ 10px
right_layout->addWidget(project_list_);
right_layout->addWidget(new_project_button_);
right_layout->addWidget(new_note_button_);
- QScrollArea* scrollArea = new QScrollArea(content_widget_);
- scrollArea->setWidgetResizable(true);
- scrollArea->setWidget(note_list_);
- content_layout_->addWidget(scrollArea, Qt::AlignRight);
- content_layout_->addLayout(right_layout);
- main_layout_->addWidget(content_widget_);
- this->setLayout(main_layout_);
+ right_panel->setFixedWidth(210);
+ tab_widget_->tabBar()->setExpanding(true);
+
+ content_layout_->addWidget(tab_widget_);
+ content_layout_->addWidget(right_panel);
- this->project_list_->load_projects(storage);
+ main_layout_->addWidget(top_bar_);
+ main_layout_->addLayout(content_layout_);
+ project_list_->load_projects(storage);
+
+ connect(
+ project_list_, &QListWidget::itemClicked, actual_notes_,
+ &NoteList::load_project_notes
+ );
+ connect(
+ project_list_, &QListWidget::itemClicked, overdue_notes_,
+ &NoteList::load_project_notes
+ );
connect(
- project_list_, &QListWidget::itemClicked, note_list_,
+ project_list_, &QListWidget::itemClicked, completed_notes_,
&NoteList::load_project_notes
);
+ connect(
+ project_list_, &QListWidget::itemClicked, deleted_notes_,
+ &NoteList::load_project_notes
+ );
+
connect(
new_note_button_, &QPushButton::clicked, this, &Ui::MainWindow::add_note
);
@@ -70,25 +123,137 @@ MainWindow::MainWindow(
new_project_button_, &QPushButton::clicked, this,
&Ui::MainWindow::add_project
);
+ connect(
+ top_bar_, &Ui::BottomBar::profile_button_clicked, this,
+ &MainWindow::on_profile_button_click
+ );
+ connect(
+ StyleManager::instance(), &StyleManager::theme_changed, this,
+ &MainWindow::handle_theme_changed
+ );
+ connect(
+ StyleManager::instance(), &StyleManager::font_size_changed, this,
+ &MainWindow::handle_font_size_changed
+ );
+ connect(
+ LanguageManager::instance(), &LanguageManager::language_changed, this,
+ &MainWindow::handle_language_changed
+ );
+ handle_theme_changed(StyleManager::instance()->current_theme());
+ handle_font_size_changed(StyleManager::instance()->current_font_size());
+ handle_language_changed(LanguageManager::instance()->current_language());
+}
+
+QScrollArea *MainWindow::create_scroll_area(NoteList *note_list) {
+ QScrollArea *scrollArea = new QScrollArea();
+ scrollArea->setWidgetResizable(true);
+ scrollArea->setWidget(note_list);
+ scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ scrollArea->setFrameShape(QFrame::NoFrame);
+ return scrollArea;
+}
+
+void MainWindow::handle_language_changed(std::string new_language) {
+ if (new_language == "RU") {
+ new_project_button_->setText("Новый проект");
+ new_note_button_->setText("Новая заметка");
+ } else if (new_language == "EN") {
+ new_project_button_->setText("New project");
+ new_note_button_->setText("New note");
+ }
+}
+
+void MainWindow::on_delete_account_button_click() {
+ this->deleteLater();
+ emit delete_account_requested();
+}
+
+void MainWindow::on_logout_button_click() {
+ this->deleteLater();
+ emit logout_requested();
+}
+
+void MainWindow::handle_theme_changed(int theme) {
+ this->setStyleSheet(THEMES[theme]);
+}
+
+void MainWindow::handle_font_size_changed(std::string font_size_) {
+ QString font_rule;
+ if (font_size_ == "small") {
+ font_rule =
+ "#ProjectList, #BottomBar QLabel, #BottomBar QPushButton, "
+ "#NoteWidget QPushButton, QPushButton { font-size: 11px; }";
+ } else if (font_size_ == "medium") {
+ font_rule =
+ "#ProjectList, #BottomBar QLabel, #BottomBar QPushButton, "
+ "#NoteWidget QPushButton, QPushButton { font-size: 13px; }";
+ } else if (font_size_ == "big") {
+ font_rule =
+ "#ProjectList, #BottomBar QLabel, #BottomBar QPushButton, "
+ "#NoteWidget QPushButton, QPushButton { font-size: 15px; }";
+ }
+
+ this->setStyleSheet(
+ THEMES[StyleManager::instance()->current_theme()] + font_rule
+ );
+}
+
+void MainWindow::on_profile_button_click() {
+ this->setEnabled(false);
+ ProfileWindow *new_profile_window = new ProfileWindow(
+ QString::fromStdString(this->username), this->parentWidget()
+ );
+ new_profile_window->setAttribute(Qt::WA_DeleteOnClose);
+ connect(
+ new_profile_window, &ProfileWindow::logout_requested, this,
+ &MainWindow::on_logout_button_click
+ );
+ connect(
+ new_profile_window, &ProfileWindow::delete_account_requested, this,
+ &MainWindow::on_delete_account_button_click
+ );
+ connect(new_profile_window, &ProfileWindow::destroyed, this, [this]() {
+ this->setEnabled(true);
+ });
+ new_profile_window->show();
+ new_profile_window->raise();
+ new_profile_window->activateWindow();
}
void MainWindow::add_project() {
bool ok;
- QString name_of_project = QInputDialog::getText(
- nullptr, "Название проекта:", "Введите название", QLineEdit::Normal, "",
- &ok
- );
- if (ok) {
+ QString name_of_project;
+ if (LanguageManager::instance()->current_language() == "RU") {
+ name_of_project = QInputDialog::getText(
+ nullptr, "Название проекта:", "Введите название", QLineEdit::Normal,
+ "", &ok
+ );
+ } else if (LanguageManager::instance()->current_language() == "EN") {
+ name_of_project = QInputDialog::getText(
+ nullptr, "Name of project:", "Create a name", QLineEdit::Normal, "",
+ &ok
+ );
+ }
+ if (ok && name_of_project.trimmed() == "") {
+ if (LanguageManager::instance()->current_language() == "RU") {
+ QMessageBox::warning(this, "Ошибка", "Введите название!");
+ } else {
+ QMessageBox::warning(this, "Error", "Please enter a name!");
+ }
+ } else if (ok) {
int id = 0;
- if (DB::ProjectDAO::create_project(name_of_project.toStdString(), id)) {
+ if (DB::ProjectDAO::create_project(
+ name_of_project.trimmed().toStdString(), id
+ )) {
LRDao::add_project_to_user(username, id);
auto &project = storage_->add_project(
- Project(id, name_of_project.toStdString(), "")
+ Project(id, name_of_project.trimmed().toStdString(), "")
);
project_list_->add_project(&project);
}
}
+ handle_font_size_changed(StyleManager::instance()->current_font_size());
}
void MainWindow::add_note() {
@@ -101,11 +266,15 @@ void MainWindow::add_note() {
);
auto ¬e =
project_item->project_->add_note({id, "Пустая заметка", ""});
- note_list_->add_note_widget(¬e);
+ actual_notes_->add_note_widget(¬e, project_list_->currentItem());
}
} else {
QMessageBox msg;
- msg.setText("Проект не выбран!");
+ if (LanguageManager::instance()->current_language() == "RU") {
+ msg.setText("Сперва выберите проект!");
+ } else if (LanguageManager::instance()->current_language() == "EN") {
+ msg.setText("Choose a project first!");
+ }
msg.exec();
}
}
diff --git a/ui/main-window/src/notelist.cpp b/ui/main-window/src/notelist.cpp
index 4af7558..dd9083a 100644
--- a/ui/main-window/src/notelist.cpp
+++ b/ui/main-window/src/notelist.cpp
@@ -5,19 +5,17 @@
#include
#include
#include "note.hpp"
-#include "notewidget.h"
-#include "projectitem.h"
namespace Ui {
-NoteList::NoteList(QWidget *parent)
+NoteList::NoteList(QWidget *parent, const std::string type)
: QWidget(parent),
main_layout_(new QHBoxLayout(this)),
- vertical_layouts_(std::vector()){
-
+ vertical_layouts_(std::vector()),
+ type_(type) {
this->setAttribute(Qt::WA_StyledBackground);
this->setObjectName("NoteList");
this->setLayout(main_layout_);
- vertical_layouts_.resize(4, nullptr);
+ vertical_layouts_.resize(3, nullptr);
for (auto &layout : vertical_layouts_) {
layout = new QVBoxLayout(this);
@@ -25,15 +23,21 @@ NoteList::NoteList(QWidget *parent)
}
}
-void NoteList::add_note_widget(const project_storage_model::Note *note) {
- auto current_layout = vertical_layouts_[note_counter_ % 4];
+void NoteList::add_note_widget(
+ const project_storage_model::Note *note,
+ QListWidgetItem *project
+) {
+ auto current_layout = vertical_layouts_[note_counter_ % 3];
if (current_layout->count() > 1) {
current_layout->removeItem(
current_layout->itemAt(current_layout->count() - 1)
);
}
- vertical_layouts_[note_counter_ % 4]->addWidget(
- new NoteWidget(this, note), 0, Qt::AlignTop
+ auto *new_note = new NoteWidget(this, note, this->type_, project);
+ vertical_layouts_[note_counter_ % 3]->addWidget(new_note, 0, Qt::AlignTop);
+ connect(
+ new_note, &NoteWidget::change_type_requested, this,
+ &NoteList::load_project_notes
);
current_layout->addStretch();
note_counter_++;
@@ -41,14 +45,12 @@ void NoteList::add_note_widget(const project_storage_model::Note *note) {
void NoteList::load_project_notes(QListWidgetItem *project) {
ProjectItem *p = dynamic_cast(project);
- assert(p != nullptr);
- qDebug() << "Адрес проекта"
- << QString::fromStdString(p->project_->get_name()) << ":"
- << p->project_;
this->clear_note_list();
note_counter_ = 0;
for (const auto ¬e : p->project_->get_notes()) {
- this->add_note_widget(¬e);
+ if (note.get_type() == this->type_) {
+ this->add_note_widget(¬e, project);
+ }
}
}
diff --git a/ui/main-window/src/notewidget.cpp b/ui/main-window/src/notewidget.cpp
index 3ced750..f4a5c77 100644
--- a/ui/main-window/src/notewidget.cpp
+++ b/ui/main-window/src/notewidget.cpp
@@ -1,28 +1,39 @@
#include "notewidget.h"
#include
+#include
#include
#include
+#include "language_manager.h"
#include "note.hpp"
#include "note_edit_dialog.h"
+#include "style_manager.h"
namespace Ui {
NoteWidget::NoteWidget(
QWidget *parent,
- const project_storage_model::Note *model_note
+ const Note *model_note,
+ const std::string type,
+ QListWidgetItem *p
)
: QWidget(parent),
model_note_(model_note),
main_layout_(new QVBoxLayout(this)),
- open_button_(new QPushButton("Открыть")) {
+ open_button_(new QPushButton(tr("Открыть"))),
+ delete_button_(new QPushButton(tr("Удалить"))),
+ type_(type),
+ project_(p) {
this->setObjectName("NoteWidget");
this->setMinimumWidth(100);
this->setFixedHeight(100);
- title_label_ = new QLabel(model_note_->get_title().c_str(), this);
- text_label_ = new QLabel(model_note_->get_text().c_str(), this);
-
- title_label_->setStyleSheet("color: rgb(33, 44, 50);");
- text_label_->setStyleSheet("color: rgb(33, 44, 50);");
-
+
+ title_label_ =
+ new QLabel(QString::fromStdString(model_note_->get_title()), this);
+ text_label_ =
+ new QLabel(QString::fromStdString(model_note_->get_text()), this);
+
+ title_label_->setStyleSheet("color: rgb(33, 44, 50); font-size: 15px;");
+ text_label_->setStyleSheet("color: rgb(33, 44, 50); font-size: 15px;");
+
main_layout_->addWidget(title_label_);
main_layout_->addWidget(text_label_);
@@ -30,24 +41,101 @@ NoteWidget::NoteWidget(
title_label_->setWordWrap(false);
text_label_->setTextInteractionFlags(Qt::TextSelectableByMouse);
- main_layout_->addWidget(open_button_);
+ QHBoxLayout *buttons_layout = new QHBoxLayout;
+
+ buttons_layout->addWidget(open_button_);
+ buttons_layout->addWidget(delete_button_);
+
+ if (type_ == "deleted") {
+ delete_button_->setText("Восстановить");
+ }
+
+ main_layout_->addLayout(buttons_layout);
connect(
open_button_, &QPushButton::clicked, this, &NoteWidget::open_note_window
);
+ connect(
+ delete_button_, &QPushButton::clicked, this, &NoteWidget::delete_note
+ );
+ connect(
+ StyleManager::instance(), &StyleManager::font_size_changed, this,
+ &NoteWidget::handle_font_size_changed
+ );
this->setLayout(main_layout_);
this->setAttribute(Qt::WA_StyledBackground);
+ connect(
+ LanguageManager::instance(), &LanguageManager::language_changed, this,
+ &NoteWidget::handle_language_changed
+ );
+ handle_language_changed(LanguageManager::instance()->current_language());
+ handle_font_size_changed(StyleManager::instance()->current_font_size());
+}
+
+void NoteWidget::handle_language_changed(std::string new_language) {
+ if (new_language == "RU") {
+ open_button_->setText(tr("Открыть"));
+ if (title_label_->text() == "Empty note") {
+ title_label_->setText("Пустая заметка");
+ }
+ if (type_ == "deleted") {
+ delete_button_->setText("Восстановить");
+ } else {
+ delete_button_->setText("Удалить");
+ }
+ } else if (new_language == "EN") {
+ open_button_->setText(tr("Open"));
+ if (title_label_->text() == "Пустая заметка") {
+ title_label_->setText("Empty note");
+ }
+ if (type_ == "deleted") {
+ delete_button_->setText("Восстановить");
+ } else {
+ delete_button_->setText("Удалить");
+ }
+ }
+}
+
+void NoteWidget::handle_font_size_changed(std::string font_size_) {
+ QString font_rule;
+ if (font_size_ == "small") {
+ title_label_->setStyleSheet("color: rgb(33, 44, 50); font-size: 13px;");
+ } else if (font_size_ == "medium") {
+ title_label_->setStyleSheet("color: rgb(33, 44, 50); font-size: 15px;");
+ } else if (font_size_ == "big") {
+ title_label_->setStyleSheet("color: rgb(33, 44, 50); font-size: 17px;");
+ }
}
void NoteWidget::open_note_window() const {
auto dialog = new ::NoteEditDialog(
+ dynamic_cast(project_)->project_->get_name(),
const_cast(qobject_cast(this)),
const_cast(model_note_)
);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->exec();
- text_label_->setText(model_note_->get_text().c_str());
- title_label_->setText(model_note_->get_title().c_str());
+ title_label_->setText(QString::fromStdString(model_note_->get_title()));
+ main_layout_->update();
+}
+
+void NoteWidget::change_type(std::string new_type) {
+ type_ = new_type;
+ handle_language_changed(LanguageManager::instance()->current_language());
main_layout_->update();
+ emit change_type_requested(this->project_);
+}
+
+void NoteWidget::delete_note() {
+ if (type_ == "deleted") {
+ this->change_type("actual");
+ } else {
+ this->change_type("deleted");
+ }
}
+
+QListWidgetItem *NoteWidget::get_project() const {
+ return this->project_;
+}
+
} // namespace Ui
\ No newline at end of file
diff --git a/ui/note-widget/CMakeLists.txt b/ui/note-widget/CMakeLists.txt
index d062724..9dcfe1d 100644
--- a/ui/note-widget/CMakeLists.txt
+++ b/ui/note-widget/CMakeLists.txt
@@ -37,4 +37,4 @@ target_include_directories(NoteWidget
$
)
-target_link_libraries(NoteWidget PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui Qt6::Sql Database Scripts)
\ No newline at end of file
+target_link_libraries(NoteWidget PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui Qt6::Sql Database LanguageManager Scripts StyleManager)
\ No newline at end of file
diff --git a/ui/note-widget/include/note_edit_dialog.h b/ui/note-widget/include/note_edit_dialog.h
index 46048a3..0dbcda5 100644
--- a/ui/note-widget/include/note_edit_dialog.h
+++ b/ui/note-widget/include/note_edit_dialog.h
@@ -23,10 +23,15 @@ class NoteEditDialog final : public QDialog {
public:
explicit NoteEditDialog(
- QWidget* parent = nullptr,
- Note* note = new Note(0, "NULL", "NULL")
+ std::string project_name = "TODO",
+ QWidget *parent = nullptr,
+ Note *note = new Note(0, "NULL", "NULL")
);
~NoteEditDialog() override;
+ static const std::vector THEMES;
+ void handle_theme_changed(int theme);
+ void handle_font_size_changed(std::string font_size);
+ void handle_language_changed(std::string new_language);
private slots:
void on_save_button_click();
@@ -40,19 +45,20 @@ private slots:
void setup_connections();
void setup_ui();
- void add_member_avatar(const std::string& member);
+ void add_member_avatar(const std::string &member);
void clear_member_avatars();
void update_tags_display();
- static QString create_tag_style_sheet(const QString& color);
+ static QString create_tag_style_sheet(const QString &color);
[[nodiscard]] bool try_save_note() const;
- Ui::NoteEditDialog* ui_{};
+ Ui::NoteEditDialog *ui_{};
std::vector> member_avatars_;
std::vector> tag_labels_;
QList selected_tags_;
- Note* note_;
+ Note *note_;
+ std::string project_name_;
};
-#endif // NOTE_EDIT_DIALOG_H
\ No newline at end of file
+#endif // NOTE_EDIT_DIALOG_H
\ No newline at end of file
diff --git a/ui/note-widget/include/note_edit_dialog_styles.h b/ui/note-widget/include/note_edit_dialog_styles.h
index 5ad1b63..898475f 100644
--- a/ui/note-widget/include/note_edit_dialog_styles.h
+++ b/ui/note-widget/include/note_edit_dialog_styles.h
@@ -4,7 +4,8 @@
#include
namespace Ui {
-QString light_theme = R"(
+QString note_edit_dialog_light_autumn_theme = R"(
+
QDialog {
background-color: #f5f5f5;
}
@@ -45,10 +46,6 @@ QString light_theme = R"(
padding: 5px;
}
- QTextEdit#descriptionTextEdit::placeholder {
- color: #727272;
- }
-
/* Основные кнопки */
QHBoxLayout#buttonsLayout {
@@ -79,7 +76,17 @@ QString light_theme = R"(
background-color: #dadada;
}
- /* Боковое меню */
+ QPushButton#deleteButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: white;
+ color: #fea36b;
+ padding: 5px 10px;
+ }
+
+ QPushButton#deleteButton:hover {
+ background-color: #dadada;
+ }
QPushButton#joinButton,
QPushButton#addMembersButton,
@@ -115,8 +122,6 @@ QString light_theme = R"(
color: #727272;
}
- /* Дополнительные элементы заметки */
-
QDateEdit#dateEdit {
font-family: 'Arial';
border-radius: 5px;
@@ -132,10 +137,9 @@ QString light_theme = R"(
QDateEdit#dateEdit::drop-down {
border: none;
width: 20px;
+ border-radius: 5px;
}
- /* Окно с сообщением */
-
QMessageBox {
background-color: #ffffff;
}
@@ -167,6 +171,754 @@ QString light_theme = R"(
background-color: #d58745;
border-color: #d58745;
}
+
+ QPushButton#switch_theme {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ background-color: transparent;
+ border-radius: 7px;
+ border: 2px solid #089083;
+ padding: 0;
+ }
+ QPushButton::hover#switch_theme {
+ background-color: #089083;
+ }
+ QPushButton::pressed#switch_theme {
+ background-color:rgb(7, 110, 100);
+ }
+)";
+
+QString note_edit_dialog_dark_autumn_theme = R"(
+ QDialog {
+ background-color: #202020;
+ }
+
+ QLineEdit#titleLineEdit {
+ font-family: 'Arial';
+ font-size: 25px;
+ font-weight: bold;
+ color: #089083;
+ border: none;
+ padding: 0;
+ background: transparent;
+ }
+
+ QLabel#projectNameLabel {
+ font-family: 'Arial';
+ font-size: 13px;
+ color: #727272;
+ padding: 1px;
+ }
+
+ QLabel#descriptionLabel {
+ font-family: 'Arial';
+ font-size: 18px;
+ font-weight: bold;
+ color:rgb(202, 202, 202);
+ }
+
+ QTextEdit#descriptionTextEdit {
+ border-radius: 10px;
+ border: 1px solid #000000;
+ background: #000000;
+ color: #727272;
+ padding: 5px;
+ }
+
+ QHBoxLayout#buttonsLayout {
+ align: left;
+ }
+
+ QPushButton#saveButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #fea36b;
+ color: #263238;
+ padding: 5px 10px;
+ }
+
+ QPushButton#saveButton:hover {
+ background-color: #d58745;
+ }
+
+ QPushButton#cancelButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #089083;
+ color: white;
+ padding: 5px 10px;
+ }
+
+ QPushButton#cancelButton:hover {
+ background-color: #01635d;
+ }
+
+ QPushButton#deleteButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #089083;
+ color: white;
+ padding: 5px 10px;
+ }
+
+ QPushButton#deleteButton:hover {
+ background-color: #01635d;
+ }
+
+ QPushButton#joinButton,
+ QPushButton#addMembersButton,
+ QPushButton#addDateButton,
+ QPushButton#addTagsButton {
+ font-family: 'Arial';
+ background-color: #089083;
+ color: #ffffff;
+ padding: 5px 10px;
+ border-radius: 10px;
+ font-weight: bold;
+ text-align: left;
+ }
+
+ QPushButton#joinButton:hover,
+ QPushButton#addMembersButton:hover,
+ QPushButton#addDateButton:hover,
+ QPushButton#addTagsButton:hover {
+ background-color: #01635d;
+ }
+
+ QLabel#sidePanelLabel,
+ QLabel#sidePanelLabel_2 {
+ font-family: 'Arial';
+ font-size: 14px;
+ font-weight: bold;
+ color: #727272;
+ }
+
+ QLabel#membersLabel,
+ QLabel#tagsLabel,
+ QLabel#dateLabel {
+ color: #727272;
+ }
+
+ QDateEdit#dateEdit {
+ font-family: 'Arial';
+ border-radius: 5px;
+ background-color: #ffdda2;
+ color: #050505;
+ padding: 5px 5px;
+ border: none;
+ width: 70px;
+ height: 22px;
+ text-align: center;
+ font-weight: bold;
+ }
+ QDateEdit#dateEdit::drop-down {
+ border: none;
+ width: 20px;
+ }
+
+ QMessageBox {
+ background-color: #263238;
+ }
+
+ QMessageBox QLabel {
+ font-family: 'Arial';
+ font-size: 14px;
+ color: #ffffff;
+ }
+
+ QMessageBox QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ color: #263238;
+ background-color: #fea36b;
+ border-radius: 10px;
+ padding: 5px 15px;
+ min-width: 60px;
+ min-height: 25px;
+ }
+
+ QMessageBox QPushButton:hover {
+ background-color: #d58745;
+ }
+
+ QMessageBox QPushButton:pressed {
+ background-color: #d58745;
+ border-color: #d58745;
+ }
+
+ QPushButton#switch_theme {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ background-color: transparent;
+ border-radius: 7px;
+ border: 2px solid #089083;
+ padding: 0;
+ }
+ QPushButton::hover#switch_theme {
+ background-color: #089083;
+ }
+ QPushButton::pressed#switch_theme {
+ background-color:rgb(7, 110, 100);
+ }
+)";
+
+QString note_edit_dialog_light_purple_theme = R"(
+ QDialog {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 #9882B9, stop:0.5 rgb(176, 157, 205), stop:1 rgb(125, 109, 148));
+ }
+
+ QLineEdit#titleLineEdit {
+ font-family: 'Arial';
+ font-size: 25px;
+ font-weight: bold;
+ color: rgb(42, 10, 25);
+ border: none;
+ padding: 0;
+ background: transparent;
+ }
+
+ QLabel#projectNameLabel {
+ font-family: 'Arial';
+ font-size: 13px;
+ color: rgb(218, 207, 235);
+ padding: 1px;
+ }
+
+ QLabel#descriptionLabel {
+ font-family: 'Arial';
+ font-size: 18px;
+ font-weight: bold;
+ color: rgb(42, 10, 25);
+ }
+
+ QTextEdit#descriptionTextEdit {
+ border-radius: 10px;
+ border: 1px solid rgb(221, 210, 238);
+ background: rgb(221, 210, 238);
+ color: #221932;
+ padding: 5px;
+ }
+
+ QHBoxLayout#buttonsLayout {
+ align: left;
+ }
+
+ QPushButton#saveButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #722548;
+ color: rgb(206, 193, 224);
+ padding: 5px 10px;
+ }
+
+ QPushButton#saveButton:hover {
+ background-color: rgb(98, 27, 59);
+ }
+
+ QPushButton#cancelButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: rgb(42, 10, 25);
+ color: rgb(218, 207, 235);
+ padding: 5px 10px;
+ }
+
+ QPushButton#cancelButton:hover {
+ background-color: rgb(27, 6, 16);
+ }
+
+ QPushButton#deleteButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: rgb(42, 10, 25);
+ color: rgb(218, 207, 235);
+ padding: 5px 10px;
+ }
+
+ QPushButton#deleteButton:hover {
+ background-color: rgb(27, 6, 16);
+ }
+
+ QPushButton#joinButton,
+ QPushButton#addMembersButton,
+ QPushButton#addDateButton,
+ QPushButton#addTagsButton {
+ font-family: 'Arial';
+ background-color: rgb(42, 10, 25);
+ color: rgb(218, 207, 235);
+ padding: 5px 10px;
+ border-radius: 10px;
+ font-weight: bold;
+ text-align: left;
+ }
+
+ QPushButton#joinButton:hover,
+ QPushButton#addMembersButton:hover,
+ QPushButton#addDateButton:hover,
+ QPushButton#addTagsButton:hover {
+ background-color: rgb(27, 6, 16);
+ }
+
+ QLabel#sidePanelLabel,
+ QLabel#sidePanelLabel_2 {
+ font-family: 'Arial';
+ font-size: 14px;
+ font-weight: bold;
+ color: rgb(218, 207, 235);
+ }
+
+ QLabel#membersLabel,
+ QLabel#tagsLabel,
+ QLabel#dateLabel {
+ color: rgb(218, 207, 235);
+ }
+
+ QDateEdit#dateEdit {
+ font-family: 'Arial';
+ border-radius: 5px;
+ background-color: #C98BB8;
+ color: rgb(42, 10, 25);
+ padding: 5px 5px;
+ border: none;
+ width: 70px;
+ height: 22px;
+ text-align: center;
+ font-weight: bold;
+ }
+ QDateEdit#dateEdit::drop-down {
+ border: none;
+ width: 20px;
+ }
+
+ QMessageBox {
+ background-color: rgb(221, 210, 238);
+ }
+
+ QMessageBox QLabel {
+ font-family: 'Arial';
+ font-size: 14px;
+ color: #221932;
+ }
+
+ QMessageBox QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ color: rgb(206, 193, 224);
+ background-color: #722548;
+ border-radius: 10px;
+ padding: 5px 15px;
+ min-width: 60px;
+ min-height: 25px;
+ }
+
+ QMessageBox QPushButton:hover {
+ background-color: rgb(98, 27, 59);
+ }
+
+ QMessageBox QPushButton:pressed {
+ background-color: rgb(98, 27, 59);
+ border-color: rgb(98, 27, 59);
+ }
+
+ QPushButton#switch_theme {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ background-color: transparent;
+ border-radius: 7px;
+ border: 2px solid rgb(42, 10, 25);
+ padding: 0;
+ }
+ QPushButton::hover#switch_theme {
+ background-color: rgb(42, 10, 25);
+ }
+ QPushButton::pressed#switch_theme {
+ background-color:rgb(26, 6, 15);
+ }
+)";
+
+QString note_edit_dialog_dark_purple_theme = R"(
+ QDialog {
+ background-color:rgb(9, 6, 10);
+ }
+
+ QLineEdit#titleLineEdit {
+ font-family: 'Arial';
+ font-size: 25px;
+ font-weight: bold;
+ color: #9882B9;
+ border: none;
+ padding: 0;
+ background: transparent;
+ }
+
+ QLabel#projectNameLabel {
+ font-family: 'Arial';
+ font-size: 13px;
+ color: rgb(176, 170, 185);
+ padding: 1px;
+ }
+
+ QLabel#descriptionLabel {
+ font-family: 'Arial';
+ font-size: 18px;
+ font-weight: bold;
+ color: #9882B9;
+ }
+
+ QTextEdit#descriptionTextEdit {
+ border-radius: 10px;
+ border: 1px solid #221932;
+ background: #221932;
+ color: rgb(176, 170, 185);
+ padding: 5px;
+ }
+
+ QHBoxLayout#buttonsLayout {
+ align: left;
+ }
+
+ QPushButton#saveButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #722548;
+ color: #060407;
+ padding: 5px 10px;
+ }
+
+ QPushButton#saveButton:hover {
+ background-color: rgb(98, 27, 59);
+ }
+
+ QPushButton#cancelButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: rgb(42, 10, 25);
+ color: #9882B9;
+ padding: 5px 10px;
+ }
+
+ QPushButton#cancelButton:hover {
+ background-color: rgb(27, 6, 16);
+ }
+
+ QPushButton#deleteButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: rgb(42, 10, 25);
+ color: #9882B9;
+ padding: 5px 10px;
+ }
+
+ QPushButton#deleteButton:hover {
+ background-color: rgb(27, 6, 16);
+ }
+
+ QPushButton#joinButton,
+ QPushButton#addMembersButton,
+ QPushButton#addDateButton,
+ QPushButton#addTagsButton {
+ font-family: 'Arial';
+ background-color: rgb(42, 10, 25);
+ color: #9882B9;
+ padding: 5px 10px;
+ border-radius: 10px;
+ font-weight: bold;
+ text-align: left;
+ }
+
+ QPushButton#joinButton:hover,
+ QPushButton#addMembersButton:hover,
+ QPushButton#addDateButton:hover,
+ QPushButton#addTagsButton:hover {
+ background-color: rgb(27, 6, 16);
+ }
+
+ QLabel#sidePanelLabel,
+ QLabel#sidePanelLabel_2 {
+ font-family: 'Arial';
+ font-size: 14px;
+ font-weight: bold;
+ color: #9882B9;
+ }
+
+ QLabel#membersLabel,
+ QLabel#tagsLabel,
+ QLabel#dateLabel {
+ color: #9882B9;
+ }
+
+ QDateEdit#dateEdit {
+ font-family: 'Arial';
+ border-radius: 5px;
+ background-color: rgb(113, 97, 137);
+ color: #221932;
+ padding: 5px 5px;
+ border: none;
+ width: 70px;
+ height: 22px;
+ text-align: center;
+ font-weight: bold;
+ }
+ QDateEdit#dateEdit::drop-down {
+ border: none;
+ width: 20px;
+ }
+
+ QMessageBox {
+ background-color: #221932;
+ }
+
+ QMessageBox QLabel {
+ font-family: 'Arial';
+ font-size: 14px;
+ color: #9882B9;
+ }
+
+ QMessageBox QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ color: #060407;
+ background-color: #722548;
+ border-radius: 10px;
+ padding: 5px 15px;
+ min-width: 60px;
+ min-height: 25px;
+ }
+
+ QMessageBox QPushButton:hover {
+ background-color: rgb(98, 27, 59);
+ }
+
+ QMessageBox QPushButton:pressed {
+ background-color: rgb(98, 27, 59);
+ border-color: rgb(98, 27, 59);
+ }
+
+ QPushButton#switch_theme {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ background-color: transparent;
+ border-radius: 7px;
+ border: 2px solid #9882B9;
+ padding: 0;
+ }
+ QPushButton::hover#switch_theme {
+ background-color: #9882B9;
+ }
+ QPushButton::pressed#switch_theme {
+ background-color:rgb(116, 99, 140);
+ }
+)";
+
+QString note_edit_dialog_blue_theme = R"(
+ QDialog {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 #173C4C, stop:0.5 rgb(30, 66, 65), stop:1 #07142B);
+ }
+
+ QLineEdit#titleLineEdit {
+ font-family: 'Arial';
+ font-size: 25px;
+ font-weight: bold;
+ color: #BDD1BD;
+ border: none;
+ padding: 0;
+ background: transparent;
+ }
+
+ QLabel#projectNameLabel {
+ font-family: 'Arial';
+ font-size: 13px;
+ color: #BDD1BD;
+ padding: 1px;
+ }
+
+ QLabel#descriptionLabel {
+ font-family: 'Arial';
+ font-size: 18px;
+ font-weight: bold;
+ color: #BDD1BD;
+ }
+
+ QTextEdit#descriptionTextEdit {
+ border-radius: 10px;
+ border: 1px solid #568F7C;
+ background: #07142B;
+ color: #BDD1BD;
+ padding: 5px;
+ }
+
+ QHBoxLayout#buttonsLayout {
+ align: left;
+ }
+
+ QPushButton#saveButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #568F7C;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ border: none;
+ font-weight: bold;
+ }
+
+ QPushButton#saveButton:hover {
+ background-color: #326D6C;
+ }
+
+ QPushButton#saveButton:pressed {
+ background-color: #07142B;
+ }
+
+ QPushButton#cancelButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #326D6C;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ border: 1px solid #568F7C;
+ }
+
+ QPushButton#cancelButton:hover {
+ background-color: #568F7C;
+ color: #07142B;
+ }
+
+ QPushButton#deleteButton {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #326D6C;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ border: 1px solid #568F7C;
+ }
+
+ QPushButton#deleteButton:hover {
+ background-color: #568F7C;
+ color: #07142B;
+ }
+
+ QPushButton#joinButton,
+ QPushButton#addMembersButton,
+ QPushButton#addDateButton,
+ QPushButton#addTagsButton {
+ font-family: 'Arial';
+ background-color: #326D6C;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ border-radius: 10px;
+ font-weight: bold;
+ text-align: left;
+ }
+
+ QPushButton#joinButton:hover,
+ QPushButton#addMembersButton:hover,
+ QPushButton#addDateButton:hover,
+ QPushButton#addTagsButton:hover {
+ background-color: #568F7C;
+ color: #07142B;
+ }
+
+ QLabel#sidePanelLabel,
+ QLabel#sidePanelLabel_2 {
+ font-family: 'Arial';
+ font-size: 14px;
+ font-weight: bold;
+ color: #BDD1BD;
+ }
+
+ QLabel#membersLabel,
+ QLabel#tagsLabel,
+ QLabel#dateLabel {
+ color: #BDD1BD;
+ }
+
+ QDateEdit#dateEdit {
+ font-family: 'Arial';
+ border-radius: 5px;
+ background-color: rgb(61, 104, 122);
+ color: #BDD1BD;
+ padding: 5px 5px;
+ border: none;
+ width: 70px;
+ height: 22px;
+ text-align: center;
+ font-weight: bold;
+ }
+ QDateEdit#dateEdit::drop-down {
+ border: none;
+ width: 20px;
+ }
+
+ QMessageBox {
+ background-color: #07142B;
+ }
+
+ QMessageBox QLabel {
+ font-family: 'Arial';
+ font-size: 14px;
+ color: #BDD1BD;
+ }
+
+ QMessageBox QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ color: #BDD1BD;
+ background-color: #568F7C;
+ border-radius: 10px;
+ padding: 5px 15px;
+ min-width: 60px;
+ min-height: 25px;
+ }
+
+ QMessageBox QPushButton:hover {
+ background-color: #326D6C;
+ }
+
+ QMessageBox QPushButton:pressed {
+ background-color: #07142B;
+ border-color: #07142B;
+ }
+
+ QPushButton#switch_theme {
+ width: 20px;
+ height: 20px;
+ min-width: 20px;
+ min-height: 20px;
+ max-width: 20px;
+ max-height: 20px;
+ background-color: transparent;
+ border-radius: 7px;
+ border: 2px solid #326D6C;
+ padding: 0;
+ }
+ QPushButton::hover#switch_theme {
+ background-color: #326D6C;
+ }
+ QPushButton::pressed#switch_theme {
+ background-color:rgb(33, 74, 74);
+ }
)";
} // namespace Ui
diff --git a/ui/note-widget/include/tags_dialog.h b/ui/note-widget/include/tags_dialog.h
index f8496c0..b4dcea1 100644
--- a/ui/note-widget/include/tags_dialog.h
+++ b/ui/note-widget/include/tags_dialog.h
@@ -6,12 +6,17 @@
#include
#include
#include
+#include
#include
+#include
class TagsDialog final : public QDialog {
Q_OBJECT
public:
+ const static std::vector THEMES;
+ void handle_theme_changed(int theme);
+ void handle_language_changed(std::string new_language);
const int MAX_TAGS_COUNT = 5;
const std::pair DIALOG_SIZE = std::make_pair(300, 250);
diff --git a/ui/note-widget/include/tags_dialog_styles.h b/ui/note-widget/include/tags_dialog_styles.h
index 15fd320..dd9f013 100644
--- a/ui/note-widget/include/tags_dialog_styles.h
+++ b/ui/note-widget/include/tags_dialog_styles.h
@@ -4,7 +4,7 @@
#include "tags_dialog.h"
namespace Ui {
-QString tags_dialog_light_theme = R"(
+QString tags_dialog_light_autumn_theme = R"(
QDialog {
background-color: #f5f5f5;
}
@@ -14,6 +14,7 @@ QString tags_dialog_light_theme = R"(
font-family: 'Arial';
color: #727272;
spacing: 5px;
+ background-color: transparent;
}
QCheckBox::indicator {
@@ -21,17 +22,15 @@ QString tags_dialog_light_theme = R"(
height: 16px;
border-radius: 3px;
border: 1px solid #727272;
- background-color: #ffffff;
+ background-color: transparent;
}
QCheckBox::indicator:checked {
- background-color: #fea36b;
- border: 1px solid #fea36b;
- image: url(:/images/check.png);
+ background-color: #727272;
}
QCheckBox::indicator:hover {
- border: 1px solid #fea36b;
+ background-color: rgb(33, 44, 50);
}
/* Выпадающие списки цветов */
@@ -108,16 +107,445 @@ QString tags_dialog_light_theme = R"(
background-color: white;
color: #fea36b;
padding: 5px 10px;
- font-weight: bold;
+ }
+
+ QPushButton#cancel_button:hover {
+ background-color: #dadada;
+ }
+)";
+
+QString tags_dialog_dark_autumn_theme = R"(
+ QDialog {
+ background-color: #202020;
+ }
+
+ /* Чекбоксы */
+ QCheckBox {
+ font-family: 'Arial';
+ color: #727272;
+ spacing: 5px;
+ background-color: transparent;
+ }
+ QCheckBox::indicator {
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: 1px solid #727272;
+ background-color: transparent;
+ }
+ QCheckBox::indicator:hover {
+ background-color: #727272;
+ }
+ QCheckBox::indicator:checked {
+ background-color:rgb(0, 0, 0);
+ }
+
+ /* Выпадающие списки цветов */
+ QComboBox {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #363636;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ border: 1px solid #505050;
+ }
+
+ QComboBox:hover {
+ border: 1px solid #fea36b;
+ }
+
+ QComboBox::drop-down {
+ width: 20px;
+ border: none;
+ }
+
+ QComboBox::down-arrow {
+ image: url(:/images/down_arrow_light.png);
+ }
+
+ QComboBox QAbstractItemView {
+ background-color: #363636;
+ color: #BDD1BD;
+ selection-background-color: #089083;
+ selection-color: white;
+ border: 1px solid #505050;
+ border-radius: 5px;
+ }
+
+ /* Поля ввода имени тега */
+ QLineEdit {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #363636;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ border: 1px solid #505050;
+ }
+
+ QLineEdit:hover,
+ QLineEdit:focus {
border: 1px solid #fea36b;
+ }
+
+ QLineEdit::placeholder {
+ color: #727272;
+ }
+
+ /* Кнопка OK */
+ QPushButton#ok_button {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #fea36b;
+ color: #263238;
+ padding: 5px 10px;
+ font-weight: bold;
width: 30px;
height: 25px;
}
+ QPushButton#ok_button:hover {
+ background-color: #d58745;
+ }
+
+ /* Кнопка Отмена */
+ QPushButton#cancel_button {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #089083;
+ color: white;
+ padding: 5px 10px;
+ }
+
QPushButton#cancel_button:hover {
- background-color: #dadada;
+ background-color: #01635d;
+ }
+
+)";
+
+QString tags_dialog_light_purple_theme = R"(
+ QDialog {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 #9882B9, stop:0.5 rgb(176, 157, 205), stop:1 rgb(125, 109, 148));
+ }
+
+ /* Чекбоксы */
+ QCheckBox {
+ font-family: 'Arial';
+ color: rgb(42, 10, 25);
+ spacing: 5px;
+ background-color: transparent;
+ }
+ QCheckBox::indicator {
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: 1px solid rgb(42, 10, 25);
+ background-color: transparent;
+ }
+ QCheckBox::indicator:hover {
+ background-color: rgb(218, 207, 235);
+ }
+ QCheckBox::indicator:checked {
+ background-color: rgb(42, 10, 25);
+ }
+
+ /* Выпадающие списки цветов */
+ QComboBox {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #E8C9E1;
+ color: #221932;
+ padding: 5px 10px;
+ border: 1px solid #C98BB8;
+ }
+
+ QComboBox:hover {
+ border: 1px solid #722548;
+ }
+
+ QComboBox::drop-down {
+ width: 20px;
+ border: none;
+ }
+
+ QComboBox::down-arrow {
+ image: url(:/images/down_arrow_purple.png);
+ }
+
+ QComboBox QAbstractItemView {
+ background-color: #E8C9E1;
+ color: #221932;
+ selection-background-color: #722548;
+ selection-color: white;
+ border: 1px solid #C98BB8;
+ border-radius: 5px;
+ }
+
+ /* Поля ввода имени тега */
+ QLineEdit {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #E8C9E1;
+ color: #221932;
+ padding: 5px 10px;
+ border: 1px solid #C98BB8;
+ }
+
+ QLineEdit:hover,
+ QLineEdit:focus {
+ border: 1px solid #722548;
+ }
+
+ QLineEdit::placeholder {
+ color: #7A6A9A;
+ }
+
+ /* Кнопка OK */
+ QPushButton#ok_button {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #722548;
+ color: #E8C9E1;
+ padding: 5px 10px;
+ font-weight: bold;
+ width: 30px;
+ height: 25px;
+ }
+
+ QPushButton#ok_button:hover {
+ background-color: #5A1538;
+ }
+
+ /* Кнопка Отмена */
+ QPushButton#cancel_button {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: rgb(42, 10, 25);
+ color: rgb(218, 207, 235);
+ padding: 5px 10px;
+ }
+
+ QPushButton#cancel_button:hover {
+ background-color: rgb(27, 6, 16);
+ }
+)";
+
+QString tags_dialog_dark_purple_theme = R"(
+ QDialog {
+ background-color: rgb(9, 6, 10);
+ }
+
+ /* Чекбоксы */
+ QCheckBox {
+ font-family: 'Arial';
+ color: #9882B9;
+ spacing: 5px;
+ background-color: transparent;
+ }
+ QCheckBox::indicator {
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: 1px solid #9882B9;
+ background-color: transparent;
+ }
+ QCheckBox::indicator:hover {
+ background-color: #221932;
+ }
+ QCheckBox::indicator:checked {
+ background-color: #9882B9;
+ }
+
+ /* Выпадающие списки цветов */
+ QComboBox {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #322242;
+ color: #9882B9;
+ padding: 5px 10px;
+ border: 1px solid #775E88;
+ }
+
+ QComboBox:hover {
+ border: 1px solid #722548;
+ }
+
+ QComboBox::drop-down {
+ width: 20px;
+ border: none;
+ }
+
+ QComboBox::down-arrow {
+ image: url(:/images/down_arrow_purple.png);
+ }
+
+ QComboBox QAbstractItemView {
+ background-color: #322242;
+ color: #9882B9;
+ selection-background-color: #722548;
+ selection-color: white;
+ border: 1px solid #775E88;
+ border-radius: 5px;
+ }
+
+ /* Поля ввода имени тега */
+ QLineEdit {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #322242;
+ color: #9882B9;
+ padding: 5px 10px;
+ border: 1px solid #775E88;
+ }
+
+ QLineEdit:hover,
+ QLineEdit:focus {
+ border: 1px solid #722548;
+ }
+
+ QLineEdit::placeholder {
+ color: #7A6A9A;
+ }
+
+ /* Кнопка OK */
+ QPushButton#ok_button {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #722548;
+ color: rgb(9, 6, 10);
+ padding: 5px 10px;
+ font-weight: bold;
+ width: 30px;
+ height: 25px;
+ }
+
+ QPushButton#ok_button:hover {
+ background-color: #5A1538;
+ }
+
+ /* Кнопка Отмена */
+ QPushButton#cancel_button {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: rgb(42, 10, 25);
+ color: #9882B9;
+ padding: 5px 10px;
+ }
+
+ QPushButton#cancel_button:hover {
+ background-color: rgb(27, 6, 16);
+ }
+)";
+
+QString tags_dialog_blue_theme = R"(
+ QDialog {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 #173C4C, stop:0.5 rgb(30, 66, 65), stop:1 #07142B);
+ }
+
+ /* Чекбоксы */
+ QCheckBox {
+ font-family: 'Arial';
+ color: #BDD1BD;
+ spacing: 5px;
+ background-color: transparent;
+ }
+ QCheckBox::indicator {
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: 1px solid #BDD1BD;
+ background-color: transparent;
+ }
+ QCheckBox::indicator:hover {
+ background-color: #BDD1BD;
+ }
+ QCheckBox::indicator:checked {
+ background-color: #07142B;
+ }
+
+ /* Выпадающие списки цветов */
+ QComboBox {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #173C4C;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ border: 1px solid #326D6C;
+ }
+
+ QComboBox:hover {
+ border: 1px solid #568F7C;
+ }
+
+ QComboBox::drop-down {
+ width: 20px;
+ border: none;
+ }
+
+ QComboBox::down-arrow {
+ image: url(:/images/down_arrow_blue.png);
+ }
+
+ QComboBox QAbstractItemView {
+ background-color: #173C4C;
+ color: #BDD1BD;
+ selection-background-color: #568F7C;
+ selection-color: white;
+ border: 1px solid #326D6C;
+ border-radius: 5px;
+ }
+
+ /* Поля ввода имени тега */
+ QLineEdit {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #173C4C;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ border: 1px solid #326D6C;
+ }
+
+ QLineEdit:hover,
+ QLineEdit:focus {
+ border: 1px solid #568F7C;
+ }
+
+ QLineEdit::placeholder {
+ color: #7D9CAD;
+ }
+
+ /* Кнопка OK */
+ QPushButton#ok_button {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #568F7C;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ font-weight: bold;
+ width: 30px;
+ height: 25px;
+ }
+
+ QPushButton#ok_button:hover {
+ background-color: #326D6C;
+ }
+
+ /* Кнопка Отмена */
+ QPushButton#cancel_button {
+ font-family: 'Arial';
+ border-radius: 10px;
+ background-color: #326D6C;
+ color: #BDD1BD;
+ padding: 5px 10px;
+ border: 1px solid #568F7C;
+ }
+
+ QPushButton#cancel_button:hover {
+ background-color: #568F7C;
+ color: #07142B;
}
)";
-}
+} // namespace Ui
#endif // TAGS_DIALOG_STYLES_H
\ No newline at end of file
diff --git a/ui/note-widget/src/note_edit_dialog.cpp b/ui/note-widget/src/note_edit_dialog.cpp
index ed18200..28d23a6 100644
--- a/ui/note-widget/src/note_edit_dialog.cpp
+++ b/ui/note-widget/src/note_edit_dialog.cpp
@@ -1,4 +1,5 @@
#include "note_edit_dialog.h"
+#include
#include
#include
#include
@@ -6,15 +7,29 @@
#include
#include
#include
-#include
+#include
#include "./ui_note_edit_dialog.h"
+#include "language_manager.h"
#include "note_edit_dialog_styles.h"
+#include "style_manager.h"
#include "tags_dialog.h"
-NoteEditDialog::NoteEditDialog(QWidget* parent, Note* note)
+const std::vector NoteEditDialog::THEMES = {
+ Ui::note_edit_dialog_light_autumn_theme,
+ Ui::note_edit_dialog_dark_autumn_theme,
+ Ui::note_edit_dialog_dark_purple_theme,
+ Ui::note_edit_dialog_light_purple_theme, Ui::note_edit_dialog_blue_theme
+};
+
+NoteEditDialog::NoteEditDialog(
+ std::string project_name,
+ QWidget *parent,
+ Note *note
+)
: QDialog(parent),
ui_(new Ui::NoteEditDialog),
- note_(note) {
+ note_(note),
+ project_name_(std::move(project_name)) {
ui_->setupUi(this);
setWindowTitle("EFFICIO");
@@ -22,20 +37,31 @@ NoteEditDialog::NoteEditDialog(QWidget* parent, Note* note)
init_additional_fields();
setup_connections();
setup_ui();
+
+ handle_theme_changed(StyleManager::instance()->current_theme());
+ handle_font_size_changed(StyleManager::instance()->current_font_size());
}
-NoteEditDialog::~NoteEditDialog() {
- delete ui_;
+void NoteEditDialog::handle_theme_changed(int theme) {
+ this->setStyleSheet(THEMES[theme]);
}
void NoteEditDialog::init_basic_fields() {
ui_->titleLineEdit->setText(QString::fromStdString(note_->get_title()));
- ui_->descriptionTextEdit->setText(QString::fromStdString(note_->get_text()));
+ ui_->descriptionTextEdit->setText(QString::fromStdString(note_->get_text())
+ );
+ ui_->projectNameLabel->setTextFormat(Qt::RichText);
+}
+
+NoteEditDialog::~NoteEditDialog() {
+ delete ui_;
}
void NoteEditDialog::init_additional_fields() {
if (!note_->get_date().empty()) {
- QDate date = QDate::fromString(QString::fromStdString(note_->get_date()), "yyyy-MM-dd");
+ QDate date = QDate::fromString(
+ QString::fromStdString(note_->get_date()), "yyyy-MM-dd"
+ );
if (date.isValid()) {
ui_->dateEdit->setDate(date);
ui_->dateLabel->setVisible(true);
@@ -45,7 +71,7 @@ void NoteEditDialog::init_additional_fields() {
if (!note_->get_members().empty()) {
ui_->membersLabel->setVisible(true);
- for (const auto& member : note_->get_members()) {
+ for (const auto &member : note_->get_members()) {
add_member_avatar(member);
}
ui_->joinButton->setText("Покинуть");
@@ -53,7 +79,7 @@ void NoteEditDialog::init_additional_fields() {
if (!note_->get_tags().empty()) {
ui_->tagsLabel->setVisible(true);
- for (const auto& tag : note_->get_tags()) {
+ for (const auto &tag : note_->get_tags()) {
TagsDialog::Tag tag_info;
tag_info.is_checked = true;
tag_info.color = QString::fromStdString(tag.color);
@@ -69,31 +95,169 @@ void NoteEditDialog::init_additional_fields() {
}
void NoteEditDialog::setup_connections() {
- connect(ui_->saveButton, &QPushButton::clicked, this, &NoteEditDialog::on_save_button_click);
- connect(ui_->cancelButton, &QPushButton::clicked, this, &NoteEditDialog::reject);
- connect(ui_->joinButton, &QPushButton::clicked, this, &NoteEditDialog::on_join_button_click);
- connect(ui_->addMembersButton, &QPushButton::clicked, this, &NoteEditDialog::on_add_members_button_click);
+ connect(
+ ui_->saveButton, &QPushButton::clicked, this,
+ &NoteEditDialog::on_save_button_click
+ );
+ connect(
+ ui_->cancelButton, &QPushButton::clicked, this, &NoteEditDialog::reject
+ );
+ connect(
+ ui_->joinButton, &QPushButton::clicked, this,
+ &NoteEditDialog::on_join_button_click
+ );
+ connect(
+ ui_->addMembersButton, &QPushButton::clicked, this,
+ &NoteEditDialog::on_add_members_button_click
+ );
connect(ui_->addDateButton, &QPushButton::clicked, this, [this]() {
const bool is_visible = ui_->dateLabel->isVisible();
ui_->dateLabel->setVisible(!is_visible);
ui_->dateEdit->setVisible(!is_visible);
});
- connect(ui_->addTagsButton, &QPushButton::clicked, this, &NoteEditDialog::on_add_tags_button_click);
+ connect(
+ StyleManager::instance(), &StyleManager::theme_changed, this,
+ &NoteEditDialog::handle_theme_changed
+ );
+ connect(
+ ui_->addTagsButton, &QPushButton::clicked, this,
+ &NoteEditDialog::on_add_tags_button_click
+ );
+ connect(
+ StyleManager::instance(), &StyleManager::font_size_changed, this,
+ &NoteEditDialog::handle_font_size_changed
+ );
+ connect(
+ LanguageManager::instance(), &LanguageManager::language_changed, this,
+ &NoteEditDialog::handle_language_changed
+ );
+ handle_language_changed(LanguageManager::instance()->current_language());
+}
+
+void NoteEditDialog::handle_language_changed(std::string new_language) {
+ if (new_language == "RU") {
+ setWindowTitle("EFFICIO");
+ ui_->saveButton->setText("Сохранить");
+ ui_->dateLabel->setText("Срок");
+ ui_->cancelButton->setText("Отмена");
+ ui_->joinButton->setText(
+ ui_->membersLabel->isVisible() ? "Покинуть" : "Присоединиться"
+ );
+ ui_->addMembersButton->setText("Участники");
+ ui_->addDateButton->setText("Дата");
+ ui_->addTagsButton->setText("Теги");
+ ui_->projectNameLabel->setText(
+ QString("в проекте: %1")
+ .arg(QString::fromStdString(project_name_))
+ );
+ ui_->descriptionLabel->setText("Описание:");
+ if (note_->get_title() == "" or note_->get_title() == "Empty note") {
+ ui_->titleLineEdit->setText("Пустая заметка");
+ }
+ if (note_->get_text() == "" or
+ note_->get_text() == "Add a detailed description of your note") {
+ ui_->descriptionTextEdit->setPlaceholderText(
+ "Добавьте подробное описание вашей заметки"
+ );
+ }
+ ui_->sidePanelLabel->setText("Добавить к заметке");
+ ui_->sidePanelLabel_2->setText("Предложения");
+ } else if (new_language == "EN") {
+ setWindowTitle("EFFICIO");
+ ui_->saveButton->setText("Save");
+ ui_->dateLabel->setText("Deadline");
+ ui_->cancelButton->setText("Cancel");
+ ui_->joinButton->setText(
+ ui_->membersLabel->isVisible() ? "Leave" : "Join"
+ );
+ ui_->addMembersButton->setText("Members");
+ ui_->addDateButton->setText("Date");
+ ui_->addTagsButton->setText("Tags");
+ ui_->projectNameLabel->setText(
+ QString("in project: %1")
+ .arg(QString::fromStdString(project_name_))
+ );
+ ui_->descriptionLabel->setText("Description:");
+ if (note_->get_title() == "" or
+ note_->get_title() == "Пустая заметка") {
+ ui_->titleLineEdit->setText("Empty note");
+ }
+
+ if (note_->get_text() == "" or
+ note_->get_text() == "Добавьте подробное описание вашей заметки") {
+ ui_->descriptionTextEdit->setPlaceholderText(
+ "Add a detailed description of your note"
+ );
+ }
+ ui_->sidePanelLabel->setText("Add to note");
+ ui_->sidePanelLabel_2->setText("Suggestions");
+ }
+}
+
+void NoteEditDialog::handle_font_size_changed(std::string font_size_) {
+ QString current_style = this->styleSheet();
+
+ QString font_rules;
+ if (font_size_ == "small") {
+ font_rules =
+ "QLineEdit#titleLineEdit { font-size: 20px; }"
+ "QLabel#projectNameLabel { font-size: 11px; }"
+ "QLabel#descriptionLabel { font-size: 14px; }"
+ "QLabel#sidePanelLabel, QLabel#sidePanelLabel_2 { font-size: 12px; "
+ "}"
+ "QMessageBox QLabel { font-size: 12px; }"
+ "QMessageBox QPushButton { font-size: 11px; }";
+ } else if (font_size_ == "big") {
+ font_rules =
+ "QLineEdit#titleLineEdit { font-size: 30px; }"
+ "QLabel#projectNameLabel { font-size: 16px; }"
+ "QLabel#descriptionLabel { font-size: 21px; }"
+ "QLabel#sidePanelLabel, QLabel#sidePanelLabel_2 { font-size: 17px; "
+ "}"
+ "QMessageBox QLabel { font-size: 17px; }"
+ "QMessageBox QPushButton { font-size: 16px; }";
+ }
+
+ this->setStyleSheet(
+ THEMES[StyleManager::instance()->current_theme()] + font_rules
+ );
}
void NoteEditDialog::setup_ui() {
setFixedSize(700, 480);
- setStyleSheet(Ui::light_theme);
+ setStyleSheet(THEMES[StyleManager::instance()->current_theme()]);
ui_->buttonsLayout->setAlignment(Qt::AlignLeft);
}
void NoteEditDialog::on_save_button_click() {
if (try_save_note()) {
- QMessageBox::information(this, "Заметка сохранена",
- QString("Заголовок: %1\nСодержимое: %2")
- .arg(ui_->titleLineEdit->text(), ui_->descriptionTextEdit->toPlainText()));
+ if (LanguageManager::instance()->current_language() == "RU") {
+ QMessageBox::information(
+ this, "Заметка сохранена",
+ QString("Заголовок: %1\nСодержимое: %2")
+ .arg(
+ ui_->titleLineEdit->text(),
+ ui_->descriptionTextEdit->toPlainText()
+ )
+ );
+ } else {
+ QMessageBox::information(
+ this, "Note Saved",
+ QString("Title: %1\nDescription: %2")
+ .arg(
+ ui_->titleLineEdit->text(),
+ ui_->descriptionTextEdit->toPlainText()
+ )
+ );
+ }
} else {
- QMessageBox::information(this, "Ошибка", "Не удалось сохранить заметку");
+ if (LanguageManager::instance()->current_language() == "RU") {
+ QMessageBox::information(
+ this, "Ошибка", "Не удалось сохранить заметку"
+ );
+ } else {
+ QMessageBox::information(this, "Error", "Failed to save the note");
+ }
}
close();
}
@@ -114,7 +278,7 @@ void NoteEditDialog::on_join_button_click() {
}
}
-void NoteEditDialog::add_member_avatar(const std::string& member) {
+void NoteEditDialog::add_member_avatar(const std::string &member) {
QPixmap pixmap(32, 32);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
@@ -130,14 +294,22 @@ void NoteEditDialog::add_member_avatar(const std::string& member) {
}
void NoteEditDialog::clear_member_avatars() {
- for (auto& avatar : member_avatars_) {
+ for (auto &avatar : member_avatars_) {
ui_->avatarsLayout->removeWidget(avatar.get());
}
member_avatars_.clear();
}
void NoteEditDialog::on_add_members_button_click() {
- QMessageBox::information(this, "Ошибка", "Другие участники не найдены :(");
+ if (LanguageManager::instance()->current_language() == "RU") {
+ QMessageBox::information(
+ this, "Ошибка", "Другие участники не найдены."
+ );
+ } else {
+ QMessageBox::information(
+ this, "Error", "No other participants were found."
+ );
+ }
}
void NoteEditDialog::on_add_tags_button_click() {
@@ -149,7 +321,7 @@ void NoteEditDialog::on_add_tags_button_click() {
}
void NoteEditDialog::update_tags_display() {
- for (auto& tag_label : tag_labels_) {
+ for (auto &tag_label : tag_labels_) {
ui_->tagsLayout->removeWidget(tag_label.get());
}
tag_labels_.clear();
@@ -165,18 +337,19 @@ void NoteEditDialog::update_tags_display() {
}
}
-QString NoteEditDialog::create_tag_style_sheet(const QString& color) {
+QString NoteEditDialog::create_tag_style_sheet(const QString &color) {
return QString(
- "background-color: %1; "
- "color: white; "
- "padding: 9px 10px; "
- "border-radius: 5px; "
- "font-family: 'Arial'; "
- "font-size: 12px; "
- "font-weight: bold;"
- "width: 40px;"
- "height: 25px;"
- ).arg(color);
+ "background-color: %1; "
+ "color: white; "
+ "padding: 9px 10px; "
+ "border-radius: 5px; "
+ "font-family: 'Arial'; "
+ "font-size: 12px; "
+ "font-weight: bold;"
+ "width: 40px;"
+ "height: 25px;"
+ )
+ .arg(color);
}
bool NoteEditDialog::try_save_note() const {
diff --git a/ui/note-widget/src/tags_dialog.cpp b/ui/note-widget/src/tags_dialog.cpp
index 5a3d61e..0459371 100644
--- a/ui/note-widget/src/tags_dialog.cpp
+++ b/ui/note-widget/src/tags_dialog.cpp
@@ -2,8 +2,16 @@
#include
#include
#include
+#include "language_manager.h"
+#include "style_manager.h"
#include "tags_dialog_styles.h"
+const std::vector TagsDialog::THEMES = {
+ Ui::tags_dialog_light_autumn_theme, Ui::tags_dialog_dark_autumn_theme,
+ Ui::tags_dialog_dark_purple_theme, Ui::tags_dialog_light_purple_theme,
+ Ui::tags_dialog_blue_theme
+};
+
TagsDialog::TagsDialog(const QList &initial_tags, QWidget *parent)
: QDialog(parent) {
setup_ui();
@@ -23,7 +31,58 @@ TagsDialog::TagsDialog(const QList &initial_tags, QWidget *parent)
setWindowTitle("Добавить теги");
setModal(true);
setFixedSize(DIALOG_SIZE.first, DIALOG_SIZE.second);
- setStyleSheet(Ui::tags_dialog_light_theme);
+ handle_theme_changed(StyleManager::instance()->current_theme());
+ connect(
+ LanguageManager::instance(), &LanguageManager::language_changed, this,
+ &TagsDialog::handle_language_changed
+ );
+ handle_language_changed(LanguageManager::instance()->current_language());
+}
+
+void TagsDialog::handle_language_changed(std::string new_language) {
+ if (new_language == "RU") {
+ setWindowTitle("Добавить теги");
+ ok_button_->setText(tr("OK"));
+ cancel_button_->setText(tr("Отмена"));
+
+ const QStringList colors = {
+ "Красный", "Синий", "Розовый", "Зеленый", "Желтый"
+ };
+ for (int i = 0; i < MAX_TAGS_COUNT; ++i) {
+ if (color_combo_boxes_[i]) {
+ color_combo_boxes_[i]->setItemText(0, colors[0]);
+ color_combo_boxes_[i]->setItemText(1, colors[1]);
+ color_combo_boxes_[i]->setItemText(2, colors[2]);
+ color_combo_boxes_[i]->setItemText(3, colors[3]);
+ color_combo_boxes_[i]->setItemText(4, colors[4]);
+ }
+ if (name_line_edits_[i]) {
+ name_line_edits_[i]->setPlaceholderText(
+ "Имя тега " + QString::number(i + 1)
+ );
+ }
+ }
+ } else if (new_language == "EN") {
+ setWindowTitle("Add tags");
+ ok_button_->setText(tr("OK"));
+ cancel_button_->setText(tr("Cancel"));
+
+ const QStringList colors = {"Red", "Blue", "Pink", "Green", "Yellow"};
+ for (int i = 0; i < MAX_TAGS_COUNT; ++i) {
+ if (color_combo_boxes_[i]) {
+ color_combo_boxes_[i]->setItemText(0, colors[0]);
+ color_combo_boxes_[i]->setItemText(1, colors[1]);
+ color_combo_boxes_[i]->setItemText(2, colors[2]);
+ color_combo_boxes_[i]->setItemText(3, colors[3]);
+ color_combo_boxes_[i]->setItemText(4, colors[4]);
+ }
+ if (name_line_edits_[i]) {
+ name_line_edits_[i]->setPlaceholderText(
+ "Tag name " + QString::number(i + 1)
+ );
+ }
+ }
+ }
}
void TagsDialog::setup_ui() {
@@ -69,6 +128,14 @@ void TagsDialog::setup_ui() {
connect(
cancel_button_.get(), &QPushButton::clicked, this, &TagsDialog::reject
);
+ connect(
+ StyleManager::instance(), &StyleManager::theme_changed, this,
+ &TagsDialog::handle_theme_changed
+ );
+}
+
+void TagsDialog::handle_theme_changed(int theme) {
+ this->setStyleSheet(THEMES[theme]);
}
QList TagsDialog::get_selected_tags() const {
diff --git a/ui/note-widget/ui/note_edit_dialog.ui b/ui/note-widget/ui/note_edit_dialog.ui
index 60eebd8..a0e0cbd 100644
--- a/ui/note-widget/ui/note_edit_dialog.ui
+++ b/ui/note-widget/ui/note_edit_dialog.ui
@@ -45,7 +45,6 @@
Arial
10
false
- true
@@ -366,4 +365,4 @@
-
\ No newline at end of file
+
diff --git a/ui/profile-window/CMakeLists.txt b/ui/profile-window/CMakeLists.txt
new file mode 100644
index 0000000..2e19e88
--- /dev/null
+++ b/ui/profile-window/CMakeLists.txt
@@ -0,0 +1,42 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(ProfileWindow LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Qt6 COMPONENTS Widgets Core Gui Sql REQUIRED)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+set(SOURCES
+ src/profile_window.cpp
+)
+
+set(HEADERS
+ include/profile_window.h
+ include/profile_window_style_sheet.h
+)
+
+add_library(ProfileWindow STATIC ${SOURCES} ${HEADERS} ${UI_FILES})
+
+target_include_directories(ProfileWindow
+ PUBLIC
+ $
+ $
+)
+
+target_link_libraries(ProfileWindow PRIVATE
+ Qt6::Widgets
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Sql
+ Database
+ StyleManager
+ LanguageManager
+ AuthorizationWindows
+ SettingsWindow
+ AnalyticsWindow
+)
\ No newline at end of file
diff --git a/ui/profile-window/include/profile_window.h b/ui/profile-window/include/profile_window.h
new file mode 100644
index 0000000..28f1fee
--- /dev/null
+++ b/ui/profile-window/include/profile_window.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+#include "style_manager.h"
+#include
+
+QT_BEGIN_NAMESPACE
+namespace Ui {
+
+class ProfileWindow : public QDialog {
+ Q_OBJECT
+
+ QVBoxLayout* main_layout;
+ QPushButton* logout_button;
+ QPushButton* delete_button;
+ QPushButton* stats_button;
+ QPushButton* settings_button;
+ QString current_username;
+
+ void setup_ui(QDialog* profile_window);
+ void switch_window(QWidget *new_window);
+
+public:
+ explicit ProfileWindow(const QString& username, QWidget* parent = nullptr);
+ ~ProfileWindow() = default;
+
+ static const std::vector THEMES;
+ void handle_theme_changed(int theme);
+ void handle_font_size_changed(std::string font_size);
+ void handle_language_changed(std::string new_language);
+ friend class MainWindow;
+
+signals:
+ void logout_requested();
+ void delete_account_requested();
+
+private slots:
+ void on_logout_clicked();
+ void on_delete_account_clicked();
+ void on_stats_clicked();
+ void on_settings_clicked();
+};
+
+} // namespace Ui
+QT_END_NAMESPACE
\ No newline at end of file
diff --git a/ui/profile-window/include/profile_window_style_sheet.h b/ui/profile-window/include/profile_window_style_sheet.h
new file mode 100644
index 0000000..50df3f1
--- /dev/null
+++ b/ui/profile-window/include/profile_window_style_sheet.h
@@ -0,0 +1,393 @@
+#ifndef PROFILE_WINDOW_STYLE_HPP
+#define PROFILE_WINDOW_STYLE_HPP
+
+#include
+
+namespace Ui {
+
+QString profile_window_light_autumn_theme = R"(
+ QDialog {
+ background-color: #f5f5f5;
+ }
+
+ QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ padding: 5px 10px;
+ width: 60px;
+ height: 25px;
+ }
+
+ QPushButton#logout_button {
+ background-color: #fea36b;
+ color: white;
+ }
+
+ QPushButton#logout_button:hover {
+ background-color:rgb(245, 148, 89);
+ }
+
+ QPushButton#logout_button:pressed {
+ background-color:rgb(238, 122, 50);
+ }
+
+ QPushButton#delete_button {
+ background-color: #fea36b;
+ color: white;
+ }
+
+ QPushButton#delete_button:hover {
+ background-color:rgb(245, 148, 89);
+ }
+
+ QPushButton#delete_button:pressed {
+ background-color:rgb(238, 122, 50);
+ }
+
+ QPushButton#stats_button {
+ background-color: #089083;
+ color: #f5f5f5;
+ border: none;
+ padding: 10px;
+ margin: 2px;
+ }
+
+ QPushButton#stats_button:hover {
+ background-color:rgb(8, 82, 74);
+ }
+
+ QPushButton#stats_button:pressed {
+ background-color:rgb(3, 58, 54);
+ }
+
+ QPushButton#settings_button {
+ background-color: rgb(33, 44, 50);
+ color: #f5f5f5;
+ padding: 2px;
+ font-size: 35px;
+ border-radius: 15px;
+ width: 30px;
+ height: 30px;
+ }
+
+ QPushButton#settings_button:hover {
+ background-color: rgb(14, 17, 19);
+ }
+
+ QPushButton#settings_button:pressed {
+ background-color: rgb(4, 4, 5);
+ }
+)";
+
+QString profile_window_dark_autumn_theme = R"(
+ QDialog {
+ background-color:rgb(43, 43, 43);
+ }
+
+ QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ padding: 5px 10px;
+ width: 60px;
+ height: 25px;
+ }
+
+ QPushButton#logout_button {
+ background-color:rgb(211, 139, 95);
+ color: #263238;
+ }
+
+ QPushButton#logout_button:hover {
+ background-color:rgb(181, 114, 59);
+ }
+
+ QPushButton#logout_button:pressed {
+ background-color:rgb(158, 94, 45);
+ }
+
+ QPushButton#delete_button {
+ background-color:rgb(211, 139, 95);
+ color: #263238;
+ }
+
+ QPushButton#delete_button:hover {
+ background-color:rgb(181, 114, 59);
+ }
+
+ QPushButton#delete_button:pressed {
+ background-color:rgb(158, 94, 45);
+ }
+
+ QPushButton#stats_button {
+ background-color: #089083;
+ color: #f5f5f5;
+ border: none;
+ padding: 10px;
+ margin: 2px;
+ }
+
+ QPushButton#stats_button:hover {
+ background-color:rgb(12, 114, 104);
+ }
+
+ QPushButton#stats_button:pressed {
+ background-color:rgb(14, 101, 92);
+ }
+
+ QPushButton#settings_button {
+ background-color:rgb(0, 0, 0);
+ color: #f5f5f5;
+ padding: 2px;
+ font-size: 35px;
+ border-radius: 15px;
+ width: 30px;
+ height: 30px;
+ }
+
+ QPushButton#settings_button:hover {
+ background-color:rgb(54, 54, 54);
+ }
+
+ QPushButton#settings_button:pressed {
+ background-color: rgb(99, 99, 99);
+ }
+)";
+
+QString profile_window_light_purple_theme = R"(
+ QDialog {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 #9882B9, stop:0.5 rgb(176, 157, 205), stop:1 rgb(103, 88, 126));
+ }
+
+ QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ padding: 5px 10px;
+ width: 60px;
+ height: 25px;
+ }
+
+ QPushButton#logout_button {
+ background-color: #722548;
+ color: #9882B9;
+ }
+
+ QPushButton#logout_button:hover {
+ background-color:rgb(82, 27, 51);
+ }
+
+ QPushButton#logout_button:pressed {
+ background-color:rgb(64, 21, 40);
+ }
+
+ QPushButton#delete_button {
+ background-color: #722548;
+ color: #9882B9;
+ }
+
+ QPushButton#delete_button:hover {
+ background-color:rgb(84, 27, 53);
+ }
+
+ QPushButton#delete_button:pressed {
+ background-color:rgb(64, 21, 40);
+ }
+
+ QPushButton#stats_button {
+ background-color: rgb(42, 10, 25);
+ color: rgb(163, 148, 184);
+ border: none;
+ padding: 10px;
+ margin: 2px;
+ }
+
+ QPushButton#stats_button:hover {
+ background-color: rgb(42, 10, 25);
+ }
+
+ QPushButton#stats_button:pressed {
+ background-color:rgb(42, 10, 25);
+ }
+
+ QPushButton#settings_button {
+ background-color: rgb(221, 210, 238);
+ color: rgb(42, 10, 25);
+ padding: 2px;
+ font-size: 35px;
+ border-radius: 15px;
+ width: 30px;
+ height: 30px;
+ }
+
+ QPushButton#settings_button:hover {
+ background-color: rgb(177, 166, 194);
+ }
+
+ QPushButton#settings_button:pressed {
+ background-color: rgb(152, 140, 170);
+ }
+)";
+
+QString profile_window_dark_purple_theme = R"(
+ QDialog {
+ background-color: rgb(9, 6, 10);
+ }
+
+ QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ padding: 5px 10px;
+ width: 60px;
+ height: 25px;
+ }
+
+ QPushButton#logout_button {
+ background-color: #722548;
+ color: #060407;
+ }
+
+ QPushButton#logout_button:hover {
+ background-color: rgb(79, 25, 50);
+ }
+
+ QPushButton#logout_button:pressed {
+ background-color:rgb(59, 16, 35);
+ }
+
+ QPushButton#delete_button {
+ background-color: #722548;
+ color: #060407;
+ }
+
+ QPushButton#delete_button:hover {
+ background-color:rgb(79, 25, 50);
+ }
+
+ QPushButton#delete_button:pressed {
+ background-color:rgb(59, 16, 35);
+ }
+
+ QPushButton#stats_button {
+ background-color: rgb(42, 10, 25);
+ color: #9882B9;
+ border: none;
+ padding: 10px;
+ margin: 2px;
+ }
+
+ QPushButton#stats_button:hover {
+ background-color:rgb(22, 5, 13);
+ }
+
+ QPushButton#stats_button:pressed {
+ background-color:rgb(11, 3, 7);
+ }
+
+ QPushButton#settings_button {
+ background-color: #221932;
+ color: #9882B9;
+ padding: 2px;
+ font-size: 35px;
+ border-radius: 15px;
+ width: 30px;
+ height: 30px;
+ }
+
+ QPushButton#settings_button:hover {
+ background-color:rgb(21, 16, 31);
+ }
+
+ QPushButton#settings_button:pressed {
+ background-color:rgb(4, 3, 5);
+ }
+)";
+
+QString profile_window_blue_theme = R"(
+ QDialog {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 #173C4C, stop:0.5 #326D6C, stop:1 #07142B);
+ }
+
+ QPushButton {
+ font-family: 'Arial';
+ font-size: 13px;
+ font-weight: bold;
+ border-radius: 10px;
+ padding: 5px 10px;
+ width: 60px;
+ height: 25px;
+ border: none;
+ }
+
+ QPushButton#logout_button {
+ background-color: #BDD1BD;
+ color: #173C4C;
+ }
+
+ QPushButton#logout_button:hover {
+ background-color:rgb(158, 176, 158);
+ }
+
+ QPushButton#logout_button:pressed {
+ background-color:rgb(141, 157, 141);
+ }
+
+ QPushButton#delete_button {
+ background-color: #BDD1BD;
+ color: #173C4C;
+ }
+
+ QPushButton#delete_button:hover {
+ background-color:rgb(158, 176, 158);
+ }
+
+ QPushButton#delete_button:pressed {
+ background-color:rgb(141, 157, 141);
+ }
+
+ QPushButton#stats_button {
+ background-color: #326D6C;
+ color: #BDD1BD;
+ border: none;
+ padding: 10px;
+ margin: 2px;
+ }
+
+ QPushButton#stats_button:hover {
+ background-color:rgb(47, 89, 89);
+ }
+
+ QPushButton#stats_button:pressed {
+ background-color:rgb(31, 69, 85);
+ }
+
+ QPushButton#settings_button {
+ background-color: #07142B;
+ color: #BDD1BD;
+ padding: 2px;
+ font-size: 35px;
+ border-radius: 15px;
+ width: 30px;
+ height: 30px;
+ }
+
+ QPushButton#settings_button:hover {
+ background-color:rgb(4, 12, 26);
+ }
+
+ QPushButton#settings_button:pressed {
+ background-color:rgb(2, 3, 5);
+ }
+)";
+
+} // namespace Ui
+
+#endif // PROFILE_WINDOW_STYLE_HPP
\ No newline at end of file
diff --git a/ui/profile-window/src/profile_window.cpp b/ui/profile-window/src/profile_window.cpp
new file mode 100644
index 0000000..20872d6
--- /dev/null
+++ b/ui/profile-window/src/profile_window.cpp
@@ -0,0 +1,158 @@
+#include "profile_window.h"
+#include "profile_window_style_sheet.h"
+#include
+#include "database_manager.hpp"
+#include "lr_dao.hpp"
+#include "settings_window.h"
+#include "analytics_window.h"
+#include "language_manager.h"
+
+namespace Ui {
+
+const std::vector ProfileWindow::THEMES = {
+ profile_window_light_autumn_theme,
+ profile_window_dark_autumn_theme,
+ profile_window_dark_purple_theme,
+ profile_window_light_purple_theme,
+ profile_window_blue_theme
+};
+
+ProfileWindow::ProfileWindow(const QString& username, QWidget* parent)
+ : QDialog(parent), current_username(username) {
+ main_layout = new QVBoxLayout(this);
+
+ logout_button = new QPushButton(tr("Выйти из аккаунта"), this);
+ logout_button->setObjectName("logout_button");
+ main_layout->addWidget(logout_button);
+
+ delete_button = new QPushButton(tr("Удалить аккаунт"), this);
+ delete_button->setObjectName("delete_button");
+ main_layout->addWidget(delete_button);
+
+ QHBoxLayout* bottom_layout = new QHBoxLayout();
+
+ stats_button = new QPushButton(tr("Моя статистика"), this);
+ stats_button->setObjectName("stats_button");
+ bottom_layout->addWidget(stats_button);
+
+ settings_button = new QPushButton("⚙", this);
+ settings_button->setObjectName("settings_button");
+ settings_button->setFixedSize(45, 45);
+ bottom_layout->addWidget(settings_button);
+
+ setWindowTitle(tr("Профиль"));
+
+ main_layout->addLayout(bottom_layout);
+ setFixedSize(250, 160);
+
+ connect(
+ logout_button, &QPushButton::clicked,
+ this, &Ui::ProfileWindow::on_logout_clicked
+ );
+ connect(
+ delete_button, &QPushButton::clicked,
+ this, &Ui::ProfileWindow::on_delete_account_clicked
+ );
+ connect(
+ stats_button, &QPushButton::clicked,
+ this, &Ui::ProfileWindow::on_stats_clicked
+ );
+ connect(settings_button, &QPushButton::clicked,
+ this, &Ui::ProfileWindow::on_settings_clicked
+ );
+ connect(StyleManager::instance(), &StyleManager::theme_changed,
+ this, &Ui::ProfileWindow::handle_theme_changed
+ );
+ handle_theme_changed(StyleManager::instance()->current_theme());
+ connect(StyleManager::instance(), &StyleManager::font_size_changed,
+ this, &Ui::ProfileWindow::handle_font_size_changed
+ );
+ handle_font_size_changed(StyleManager::instance()->current_font_size());
+}
+
+void ProfileWindow::handle_font_size_changed(std::string font_size) {
+
+ QString font_rule;
+ if(font_size == "small") {
+ font_rule = "QPushButton { font-size: 11px; }";
+ }
+ else if(font_size == "medium") {
+ font_rule = "QPushButton { font-size: 13px; }";
+ }
+ else if(font_size == "big") {
+ font_rule = "QPushButton { font-size: 15px; }";
+ }
+
+ this->setStyleSheet(THEMES[StyleManager::instance()->current_theme()] + font_rule);
+ connect(LanguageManager::instance(), &LanguageManager::language_changed,
+ this, &ProfileWindow::handle_language_changed
+ );
+ handle_language_changed(LanguageManager::instance()->current_language());
+}
+
+
+void ProfileWindow::handle_language_changed(std::string new_language) {
+ if (new_language == "RU") {
+ setWindowTitle(tr("Профиль"));
+ logout_button->setText(tr("Выйти из аккаунта"));
+ delete_button->setText(tr("Удалить аккаунт"));
+ stats_button->setText(tr("Моя статистика"));
+ }
+ else if (new_language == "EN") {
+ setWindowTitle(tr("Profile"));
+ logout_button->setText(tr("Log out"));
+ delete_button->setText(tr("Delete account"));
+ stats_button->setText(tr("My statistics"));
+ }
+}
+
+
+
+void ProfileWindow::handle_theme_changed(int theme) {
+ setStyleSheet(THEMES[theme]);
+}
+
+void ProfileWindow::on_logout_clicked() {
+ emit logout_requested();
+ this->deleteLater();
+}
+
+void ProfileWindow::on_delete_account_clicked() {
+ QMessageBox::StandardButton reply = QMessageBox::question(
+ this,
+ tr("Удаление аккаунта"),
+ tr("Вы уверены, что хотите удалить аккаунт? Все данные будут потеряны!"),
+ QMessageBox::Yes | QMessageBox::No
+ );
+
+ if (reply == QMessageBox::Yes && LRDao::try_delete_user(current_username)) {
+ QMessageBox::information(this, tr("Успех"), tr("Аккаунт успешно удалён"));
+ emit delete_account_requested();
+ this->deleteLater();
+ } else if (reply == QMessageBox::Yes) {
+ QMessageBox::critical(this, tr("Ошибка"), tr("Не удалось удалить аккаунт"));
+ }
+}
+
+void ProfileWindow::on_stats_clicked() {
+ AnalyticsWindow *new_analytics_window = new AnalyticsWindow(this->parentWidget());
+ this->switch_window(new_analytics_window);
+}
+
+void ProfileWindow::on_settings_clicked() {
+ SettingsWindow *new_settings_window = new SettingsWindow(this->parentWidget());
+ this->switch_window(new_settings_window);
+}
+
+
+void ProfileWindow::switch_window(QWidget *new_window) {
+ this->setEnabled(false);
+ new_window->setAttribute(Qt::WA_DeleteOnClose);
+ connect(new_window, &AnalyticsWindow::destroyed,
+ this, [this]() { this->setEnabled(true); });
+ new_window->show();
+ new_window->raise();
+ new_window->activateWindow();
+}
+
+} // namespace Ui
\ No newline at end of file
diff --git a/ui/settings-window/CMakeLists.txt b/ui/settings-window/CMakeLists.txt
new file mode 100644
index 0000000..ec37601
--- /dev/null
+++ b/ui/settings-window/CMakeLists.txt
@@ -0,0 +1,40 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(SettingsWindow LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Qt6 COMPONENTS Widgets Core Gui Sql REQUIRED)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+set(SOURCES
+ src/settings_window.cpp
+)
+
+set(HEADERS
+ include/settings_window.h
+ include/settings_window_style_sheet.h
+)
+
+add_library(SettingsWindow STATIC ${SOURCES} ${HEADERS} ${UI_FILES})
+
+target_include_directories(SettingsWindow
+ PUBLIC
+ $
+ $
+)
+
+target_link_libraries(SettingsWindow PRIVATE
+ Qt6::Widgets
+ Qt6::Core
+ Qt6::Gui
+ Qt6::Sql
+ Database
+ StyleManager
+ LanguageManager
+ AuthorizationWindows
+)
\ No newline at end of file
diff --git a/ui/settings-window/include/settings_window.h b/ui/settings-window/include/settings_window.h
new file mode 100644
index 0000000..d64a358
--- /dev/null
+++ b/ui/settings-window/include/settings_window.h
@@ -0,0 +1,43 @@
+#ifndef SETTINGS_WINDOW_H
+#define SETTINGS_WINDOW_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+class SettingsWindow : public QDialog {
+ Q_OBJECT
+
+public:
+ explicit SettingsWindow(QWidget *parent = nullptr);
+ void handle_theme_changed(int theme_);
+ void handle_font_size_changed(std::string font_size_);
+ void handle_language_changed(std::string new_language);
+ static const std::vector THEMES;
+
+private slots:
+ void toggle_language();
+ void toggle_theme();
+ void set_small_font();
+ void set_medium_font();
+ void set_big_font();
+
+private:
+ void update_ui_text();
+
+ QVBoxLayout* main_layout;
+ QPushButton *language_button;
+ QPushButton *theme_button;
+ QLabel *title_label;
+ QLabel *font_size_label;
+ QRadioButton *small_font_radio;
+ QRadioButton *medium_font_radio;
+ QRadioButton *large_font_radio;
+};
+
+#endif // SETTINGS_WINDOW_H
\ No newline at end of file
diff --git a/ui/settings-window/include/settings_window_style_sheet.h b/ui/settings-window/include/settings_window_style_sheet.h
new file mode 100644
index 0000000..be57728
--- /dev/null
+++ b/ui/settings-window/include/settings_window_style_sheet.h
@@ -0,0 +1,385 @@
+#pragma once
+
+#include
+
+namespace Ui {
+ QString settings_window_light_autumn_theme = R"(
+ QWidget {
+ background-color: white;
+ }
+
+ QLabel {
+ font-weight: bold;
+ font-family: 'Arial';
+ color: #089083;
+ background-color: transparent;
+ }
+
+ QLabel#title_label {
+ font-size: 28px;
+ }
+
+ QLabel#font_size_label {
+ font-size: 35px;
+ }
+
+ QPushButton#theme_button {
+ background-color: #fea36b;
+ width: 50px;
+ height: 30px;
+ color: #f5f5f5;
+ padding: 2px;
+ font-size: 15px;
+ border-radius: 7px;
+ }
+
+ QPushButton#theme_button:hover {
+ background-color:rgb(245, 148, 89);
+ }
+ QPushButton#theme_button:pressed {
+ background-color:rgb(238, 122, 50);
+ }
+
+ QPushButton#language_button {
+ background-color: #089083;
+ width: 50px;
+ height: 30px;
+ color: #f5f5f5;
+ padding: 2px;
+ font-size: 20px;
+ border-radius: 7px;
+ }
+ QPushButton#language_button:hover {
+ background-color: rgb(8, 82, 74);
+ color: #f5f5f5;
+ }
+
+ QPushButton::pressed#language_button {
+ background-color:rgb(3, 58, 54);
+ color: #f5f5f5;
+ }
+
+ QRadioButton {
+ font-family: 'Arial';
+ color: #727272;
+ spacing: 5px;
+ background-color: transparent;
+ }
+ QRadioButton::indicator {
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: 1px solid #727272;
+ background-color: transparent;
+ }
+ QRadioButton::indicator:hover {
+ background-color: #727272;
+ }
+ QRadioButton::indicator:checked {
+ background-color: rgb(33, 44, 50);
+ }
+ )";
+
+ QString settings_window_dark_autumn_theme = R"(
+ QWidget {
+ background-color: #202020;
+ }
+
+ QLabel {
+ font-weight: bold;
+ font-family: 'Arial';
+ color: #089083;
+ background-color: transparent;
+ }
+
+ QLabel#title_label {
+ font-size: 28px;
+ }
+
+ QLabel#font_size_label {
+ font-size: 35px;
+ }
+
+ QPushButton#language_button {
+ background-color: #fea36b;
+ width: 50px;
+ height: 30px;
+ color: #263238;
+ padding: 2px;
+ font-size: 20px;
+ border-radius: 7px;
+ }
+
+ QPushButton#language_button:hover {
+ background-color: #d58745;
+ }
+ QPushButton#language_button:pressed {
+ background-color: #b87338;
+ }
+
+ QPushButton#theme_button {
+ background-color: #089083;
+ color: #f5f5f5;
+ width: 50px;
+ height: 30px;
+ padding: 2px;
+ font-size: 15px;
+ border-radius: 7px;
+ }
+ QPushButton#theme_button:hover {
+ background-color:rgb(8, 82, 74);
+ }
+
+ QPushButton::pressed#switch_theme {
+ background-color: #089083;
+ }
+
+ QRadioButton {
+ font-family: 'Arial';
+ color: #727272;
+ spacing: 5px;
+ background-color: transparent;
+ }
+ QRadioButton::indicator {
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: 1px solid #727272;
+ background-color: transparent;
+ }
+ QRadioButton::indicator:hover {
+ background-color: #727272;
+ }
+ QRadioButton::indicator:checked {
+ background-color:rgb(0, 0, 0);
+ }
+ )";
+
+ QString settings_window_light_purple_theme = R"(
+ QWidget {
+ background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1,
+ stop:0 #9882B9, stop:0.5 rgb(176, 157, 205), stop:1 rgb(125, 109, 148));
+ }
+
+ QLabel {
+ font-weight: bold;
+ font-family: 'Arial';
+ color: rgb(42, 10, 25);
+ background-color: transparent;
+ }
+
+ QLabel#title_label {
+ font-size: 28px;
+ }
+
+ QLabel#font_size_label {
+ font-size: 35px;
+ }
+
+ QPushButton#language_button {
+ background-color: #722548;
+ width: 50px;
+ height: 30px;
+ color: rgb(206, 193, 224);
+ padding: 2px;
+ font-size: 20px;
+ border-radius: 7px;
+ }
+
+ QPushButton#language_button:hover {
+ background-color: rgb(98, 27, 59);
+ }
+ QPushButton#language_button:pressed {
+ background-color: rgb(78, 21, 47);
+ }
+
+ QPushButton#theme_button {
+ background-color: rgb(42, 10, 25);
+ color: rgb(163, 148, 184);
+ width: 50px;
+ height: 30px;
+ padding: 2px;
+ font-size: 15px;
+ border-radius: 7px;
+ }
+ QPushButton#theme_button:hover {
+ background-color: rgb(21, 5, 12);
+ }
+
+ QPushButton#theme_button:pressed{
+ background-color: rgb(2, 0, 1);
+ }
+
+ QRadioButton {
+ font-family: 'Arial';
+ color: rgb(42, 10, 25);
+ spacing: 5px;
+ background-color: transparent;
+ }
+ QRadioButton::indicator {
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: 1px solid rgb(42, 10, 25);
+ background-color: transparent;
+ }
+ QRadioButton::indicator:hover {
+ background-color: rgb(42, 10, 25);
+ }
+ QRadioButton::indicator:checked {
+ background-color: rgb(218, 207, 235);
+ }
+ )";
+
+ QString settings_window_dark_purple_theme = R"(
+ QWidget {
+ background-color: rgb(9, 6, 10);
+ }
+
+ QLabel {
+ font-weight: bold;
+ font-family: 'Arial';
+ color: #9882B9;
+ background-color: transparent;
+ }
+
+ QLabel#title_label {
+ font-size: 28px;
+ }
+
+ QLabel#font_size_label {
+ font-size: 35px;
+ }
+
+ QPushButton#language_button {
+ background-color: #722548;
+ color: #060407;
+ width: 50px;
+ height: 30px;
+ padding: 2px;
+ font-size: 20px;
+ border-radius: 7px;
+ }
+
+ QPushButton#language_button:hover {
+ background-color: rgb(79, 25, 50);
+ }
+ QPushButton#language_button:pressed {
+ background-color:rgb(59, 16, 35);
+ }
+
+ QPushButton#theme_button {
+ background-color: rgb(42, 10, 25);
+ color: #9882B9;
+ width: 50px;
+ height: 30px;
+ padding: 2px;
+ font-size: 15px;
+ border-radius: 7px;
+ }
+ QPushButton#theme_button:hover {
+ background-color:rgb(22, 5, 13);
+ }
+
+ QPushButton#theme_button:pressed {
+ background-color:rgb(11, 3, 7);
+ }
+
+ QRadioButton {
+ font-family: 'Arial';
+ color: #9882B9;
+ spacing: 5px;
+ background-color: transparent;
+ }
+ QRadioButton::indicator {
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: 1px solid #9882B9;
+ background-color: transparent;
+ }
+ QRadioButton::indicator:hover {
+ background-color: #221932;
+ }
+ QRadioButton::indicator:checked {
+ background-color: #9882B9;
+ }
+ )";
+
+ QString settings_window_blue_theme = R"(
+ QWidget {
+ background: #173C4C;
+ }
+
+ QLabel {
+ font-weight: bold;
+ font-family: 'Arial';
+ color: #BDD1BD;
+ background-color: transparent;
+ }
+
+ QLabel#title_label {
+ font-size: 28px;
+ }
+
+ QLabel#font_size_label {
+ font-size: 35px;
+ }
+
+ QPushButton#language_button {
+ background-color: #BDD1BD;
+ color: #173C4C;
+ width: 50px;
+ height: 30px;
+ padding: 2px;
+ font-size: 20px;
+ border-radius: 7px;
+ }
+
+ QPushButton#language_button:hover {
+ background-color:rgb(158, 176, 158);
+ }
+ QPushButton#language_button:pressed {
+ background-color:rgb(141, 157, 141);
+ }
+
+ QPushButton#theme_button {
+ background-color: #326D6C;
+ color: #BDD1BD;
+ width: 50px;
+ height: 30px;
+ color: #BDD1BD;
+ padding: 2px;
+ font-size: 15px;
+ border-radius: 7px;
+ }
+ QPushButton#theme_button:hover {
+ background-color:rgb(47, 89, 89);
+ }
+
+ QPushButton#theme_button:pressed {
+ background-color:rgb(31, 69, 85);
+ }
+
+ QRadioButton {
+ font-family: 'Arial';
+ color: #BDD1BD;
+ spacing: 5px;
+ background-color: transparent;
+ }
+ QRadioButton::indicator {
+ width: 16px;
+ height: 16px;
+ border-radius: 3px;
+ border: 1px solid #BDD1BD;
+ background-color: transparent;
+ }
+ QRadioButton::indicator:hover {
+ background-color: #BDD1BD;
+ }
+ QRadioButton::indicator:checked {
+ background-color: #07142B;
+ }
+ )";
+
+} // namespace Ui
\ No newline at end of file
diff --git a/ui/settings-window/src/settings_window.cpp b/ui/settings-window/src/settings_window.cpp
new file mode 100644
index 0000000..d39c939
--- /dev/null
+++ b/ui/settings-window/src/settings_window.cpp
@@ -0,0 +1,162 @@
+#include "settings_window.h"
+#include "settings_window_style_sheet.h"
+#include "style_manager.h"
+#include "language_manager.h"
+#include
+
+const std::vector SettingsWindow::THEMES = {
+ Ui::settings_window_light_autumn_theme,
+ Ui::settings_window_dark_autumn_theme,
+ Ui::settings_window_dark_purple_theme,
+ Ui::settings_window_light_purple_theme,
+ Ui::settings_window_blue_theme
+};
+
+SettingsWindow::SettingsWindow(QWidget *parent) : QDialog(parent) {
+ main_layout = new QVBoxLayout(this);
+
+ title_label = new QLabel(tr("Настройки"), this);
+ title_label->setObjectName("title_label");
+ title_label->setAlignment(Qt::AlignCenter);
+ main_layout->addWidget(title_label);
+
+ QHBoxLayout *buttons_layout = new QHBoxLayout();
+
+ language_button = new QPushButton(tr("RU"), this);
+ language_button->setObjectName("language_button");
+
+ theme_button = new QPushButton(tr("Тема"), this);
+ theme_button->setObjectName("theme_button");
+
+ buttons_layout->addWidget(language_button);
+ buttons_layout->addWidget(theme_button);
+ main_layout->addLayout(buttons_layout);
+
+ font_size_label = new QLabel(tr("Размер шрифта"), this);
+ main_layout->addWidget(font_size_label);
+
+ QButtonGroup *font_group = new QButtonGroup(this);
+ small_font_radio = new QRadioButton(tr("Мелкий"), this);
+ medium_font_radio = new QRadioButton(tr("Средний"), this);
+ large_font_radio = new QRadioButton(tr("Крупный"), this);
+
+ font_group->addButton(small_font_radio);
+ font_group->addButton(medium_font_radio);
+ font_group->addButton(large_font_radio);
+ medium_font_radio->setChecked(true);
+
+ QVBoxLayout *font_layout = new QVBoxLayout();
+ font_layout->addWidget(small_font_radio);
+ font_layout->addWidget(medium_font_radio);
+ font_layout->addWidget(large_font_radio);
+ main_layout->addLayout(font_layout);
+
+ connect(language_button, &QPushButton::clicked, this, &SettingsWindow::toggle_language);
+ connect(theme_button, &QPushButton::clicked, this, &SettingsWindow::toggle_theme);
+ connect(small_font_radio, &QRadioButton::clicked, this, &SettingsWindow::set_small_font);
+ connect(medium_font_radio, &QRadioButton::clicked, this, &SettingsWindow::set_medium_font);
+ connect(large_font_radio, &QRadioButton::clicked, this, &SettingsWindow::set_big_font);
+ connect(StyleManager::instance(), &StyleManager::theme_changed,
+ this, &SettingsWindow::handle_theme_changed);
+ connect(StyleManager::instance(), &StyleManager::font_size_changed,
+ this, &SettingsWindow::handle_font_size_changed
+ );
+ title_label->setText(tr("Настройки"));
+ font_size_label->setText(tr("Размер шрифта"));
+ theme_button->setText(tr("Тема"));
+ small_font_radio->setText(tr("Мелкий"));
+ medium_font_radio->setText(tr("Средний"));
+ large_font_radio->setText(tr("Крупный"));
+
+ language_button->setText(tr("RU"));
+ setWindowTitle(tr("Настройки"));
+
+ setLayout(main_layout);
+ setFixedSize(250, 250);
+ handle_theme_changed(StyleManager::instance()->current_theme());
+
+ handle_font_size_changed(StyleManager::instance()->current_font_size());
+ connect(LanguageManager::instance(), &LanguageManager::language_changed,
+ this, &SettingsWindow::handle_language_changed
+ );
+ handle_language_changed(LanguageManager::instance()->current_language());
+}
+
+void SettingsWindow::handle_language_changed(std::string new_language) {
+ if (new_language == "RU") {
+ setWindowTitle(tr("Настройки"));
+ title_label->setText(tr("Настройки"));
+ font_size_label->setText(tr("Размер шрифта"));
+ theme_button->setText(tr("Тема"));
+ small_font_radio->setText(tr("Мелкий"));
+ medium_font_radio->setText(tr("Средний"));
+ large_font_radio->setText(tr("Крупный"));
+ language_button->setText("RU");
+ }
+ else if (new_language == "EN") {
+ setWindowTitle(tr("Settings"));
+ title_label->setText(tr("Settings"));
+ font_size_label->setText(tr("Font size"));
+ theme_button->setText(tr("Theme"));
+ small_font_radio->setText(tr("Small"));
+ medium_font_radio->setText(tr("Medium"));
+ large_font_radio->setText(tr("Large"));
+ language_button->setText("EN");
+ }
+}
+
+
+void SettingsWindow::handle_font_size_changed(std::string font_size) {
+ QString font_rule;
+ if(font_size == "small") {
+ font_rule =
+ "QPushButton#language_button, QPushButton#theme_button { font-size: 12px; }"
+ "QWidget { font-size: 12px; }"
+ "QLabel#title_label { font-size: 23px; }"
+ "QLabel#font_size_label { font-size: 30px; }";
+ }
+ else if(font_size == "medium") {
+ font_rule =
+ "QPushButton#language_button, QPushButton#theme_button { font-size: 15px; }"
+ "QWidget { font-size: 15px; }"
+ "QLabel#title_label { font-size: 28px; }"
+ "QLabel#font_size_label { font-size: 35px; }";
+ }
+ else if(font_size == "big") {
+ font_rule =
+ "QPushButton#language_button, QPushButton#theme_button { font-size: 18px; }"
+ "QWidget { font-size: 18px; }"
+ "QLabel#title_label { font-size: 32px; }"
+ "QLabel#font_size_label { font-size: 40px; }";
+ }
+ this->setStyleSheet(THEMES[StyleManager::instance()->current_theme()] + font_rule);
+}
+
+void SettingsWindow::handle_theme_changed(int theme_) {
+ this->setStyleSheet(THEMES[theme_]);
+}
+
+void SettingsWindow::toggle_language() {
+ if (language_button->text() == tr("RU")) {
+ language_button->setText(tr("EN"));
+ LanguageManager::instance()->apply_language("EN");
+ } else {
+ language_button->setText(tr("RU"));
+ LanguageManager::instance()->apply_language("RU");
+ }
+}
+
+void SettingsWindow::toggle_theme() {
+ int next_theme = (StyleManager::instance()->current_theme() + 1) % 5;
+ StyleManager::instance()->apply_theme(next_theme);
+}
+
+void SettingsWindow::set_small_font() {
+ StyleManager::instance()->apply_font_size("small");
+ }
+void SettingsWindow::set_medium_font() {
+ StyleManager::instance()->apply_font_size("medium");
+ }
+void SettingsWindow::set_big_font() {
+ StyleManager::instance()->apply_font_size("big");
+ }
\ No newline at end of file
diff --git a/ui/style-manager/CMakeLists.txt b/ui/style-manager/CMakeLists.txt
new file mode 100644
index 0000000..1706ec9
--- /dev/null
+++ b/ui/style-manager/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(StyleManager LANGUAGES CXX)
+
+set(CMAKE_CXX_STANDARD 20)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(Qt6 COMPONENTS Core Gui Widgets Core Gui Sql REQUIRED)
+
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
+
+
+set(SOURCES
+ src/style_manager.cpp
+)
+
+set(HEADERS
+ include/style_manager.h
+)
+
+add_library(StyleManager STATIC ${SOURCES} ${HEADERS})
+
+target_include_directories(StyleManager
+ PUBLIC
+ $
+ $
+)
+
+target_link_libraries(StyleManager PRIVATE Qt6::Widgets Qt6::Core Qt6::Gui Qt6::Sql Database Scripts)
+
diff --git a/ui/style-manager/include/style_manager.h b/ui/style-manager/include/style_manager.h
new file mode 100644
index 0000000..a34ce77
--- /dev/null
+++ b/ui/style-manager/include/style_manager.h
@@ -0,0 +1,32 @@
+#ifndef STYLE_MANAGER_H
+#define STYLE_MANAGER_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+class StyleManager : public QObject {
+ Q_OBJECT
+
+public:
+ static StyleManager* instance();
+
+ void apply_theme(int theme);
+ void apply_font_size(std::string font_size_);
+ int current_theme() const;
+ std::string current_font_size() const;
+signals:
+ void theme_changed(int new_theme);
+ void font_size_changed(std::string new_font_size_);
+
+private:
+ explicit StyleManager(QObject *parent = nullptr);
+ static StyleManager* m_instance;
+ int current_theme_;
+ std::string current_font_size_;
+};
+
+#endif // style_manager_H
\ No newline at end of file
diff --git a/ui/style-manager/src/style_manager.cpp b/ui/style-manager/src/style_manager.cpp
new file mode 100644
index 0000000..8cf6c93
--- /dev/null
+++ b/ui/style-manager/src/style_manager.cpp
@@ -0,0 +1,37 @@
+#include "style_manager.h"
+#include
+#include
+#include
+
+StyleManager* StyleManager::m_instance = nullptr;
+
+StyleManager::StyleManager(QObject *parent)
+ : QObject(parent) {
+ current_theme_ = 0;
+ emit theme_changed(this->current_theme_);
+}
+
+StyleManager* StyleManager::instance() {
+ if (!m_instance) {
+ m_instance = new StyleManager();
+ }
+ return m_instance;
+}
+
+void StyleManager::apply_theme(int theme) {
+ this->current_theme_ = theme;
+ emit theme_changed(this->current_theme_);
+}
+
+int StyleManager::current_theme() const {
+ return current_theme_;
+}
+
+void StyleManager::apply_font_size(std::string font_size_) {
+ current_font_size_ = font_size_;
+ emit font_size_changed(current_font_size_);
+}
+
+std::string StyleManager::current_font_size() const {
+ return current_font_size_;
+}
\ No newline at end of file