1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-18 20:45:08 +00:00
serenity/Userland/Applications/Calendar/AddEventDialog.cpp
Michal Grich 331a19efe8 Calendar: Save time of the event and display it in Calendar
This PR introduces the ability to save calendar event times
and adds functionality for displaying saved times in the calendar.
Additionally, it addresses the issue where changes to the time
value in the dropdown were not being saved.
2023-09-05 15:08:42 +01:00

218 lines
7.6 KiB
C++

/*
* Copyright (c) 2019-2020, Ryan Grieb <ryan.m.grieb@gmail.com>
* Copyright (c) 2022-2023, the SerenityOS developers.
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include "AddEventDialog.h"
#include <LibCore/DateTime.h>
#include <LibGUI/BoxLayout.h>
#include <LibGUI/Button.h>
#include <LibGUI/ComboBox.h>
#include <LibGUI/Label.h>
#include <LibGUI/Painter.h>
#include <LibGUI/SpinBox.h>
#include <LibGUI/TextBox.h>
#include <LibGUI/Widget.h>
#include <LibGUI/Window.h>
#include <LibGfx/Color.h>
#include <LibGfx/Font/FontDatabase.h>
namespace Calendar {
AddEventDialog::AddEventDialog(Core::DateTime date_time, EventManager& event_manager, Window* parent_window)
: Dialog(parent_window)
, m_date_time(date_time)
, m_event_manager(event_manager)
{
resize(158, 130);
set_title("Add Event");
set_resizable(false);
set_icon(parent_window->icon());
m_date_time = Core::DateTime::create(m_date_time.year(), m_date_time.month(), m_date_time.day(), 12, 0);
auto widget = set_main_widget<GUI::Widget>().release_value_but_fixme_should_propagate_errors();
widget->set_fill_with_background_color(true);
widget->set_layout<GUI::VerticalBoxLayout>();
auto& top_container = widget->add<GUI::Widget>();
top_container.set_layout<GUI::VerticalBoxLayout>(4);
top_container.set_fixed_height(45);
auto& add_label = top_container.add<GUI::Label>("Add title & date:"_string);
add_label.set_text_alignment(Gfx::TextAlignment::CenterLeft);
add_label.set_fixed_height(14);
add_label.set_font(Gfx::FontDatabase::default_font().bold_variant());
auto& event_title_textbox = top_container.add<GUI::TextBox>();
event_title_textbox.set_name("event_title_textbox");
event_title_textbox.set_fixed_height(20);
auto& middle_container = widget->add<GUI::Widget>();
middle_container.set_layout<GUI::HorizontalBoxLayout>(4);
middle_container.set_fixed_height(25);
auto& time_container = widget->add<GUI::Widget>();
time_container.set_layout<GUI::HorizontalBoxLayout>(4);
time_container.set_fixed_height(25);
auto& starting_month_combo = middle_container.add<GUI::ComboBox>();
starting_month_combo.set_only_allow_values_from_model(true);
starting_month_combo.set_fixed_size(50, 20);
starting_month_combo.set_model(MonthListModel::create());
starting_month_combo.set_selected_index(m_date_time.month() - 1);
auto& starting_day_combo = middle_container.add<GUI::SpinBox>();
starting_day_combo.set_fixed_size(40, 20);
starting_day_combo.set_range(1, m_date_time.days_in_month());
starting_day_combo.set_value(m_date_time.day());
auto& starting_year_combo = middle_container.add<GUI::SpinBox>();
starting_year_combo.set_fixed_size(55, 20);
starting_year_combo.set_range(0, 9999);
starting_year_combo.set_value(m_date_time.year());
auto& starting_hour_combo = time_container.add<GUI::SpinBox>();
starting_hour_combo.set_fixed_size(50, 20);
starting_hour_combo.set_range(1, 12);
starting_hour_combo.set_value(m_date_time.hour());
auto& starting_minute_combo = time_container.add<GUI::SpinBox>();
starting_minute_combo.set_fixed_size(40, 20);
starting_minute_combo.set_range(0, 59);
starting_minute_combo.set_value(m_date_time.minute());
auto& starting_meridiem_combo = time_container.add<GUI::ComboBox>();
starting_meridiem_combo.set_only_allow_values_from_model(true);
starting_meridiem_combo.set_fixed_size(55, 20);
starting_meridiem_combo.set_model(MeridiemListModel::create());
starting_meridiem_combo.set_selected_index(0);
widget->add_spacer();
auto& button_container = widget->add<GUI::Widget>();
button_container.set_fixed_height(20);
button_container.set_layout<GUI::HorizontalBoxLayout>();
button_container.add_spacer();
auto& ok_button = button_container.add<GUI::Button>("OK"_string);
ok_button.set_fixed_size(80, 20);
ok_button.on_click = [&](auto) {
add_event_to_calendar().release_value_but_fixme_should_propagate_errors();
done(ExecResult::OK);
};
auto update_starting_day_range = [&starting_day_combo, &starting_year_combo, &starting_month_combo]() {
auto year = starting_year_combo.value();
auto month = starting_month_combo.selected_index();
starting_day_combo.set_range(1, days_in_month(year, month + 1));
};
starting_year_combo.on_change = [update_starting_day_range](auto) { update_starting_day_range(); };
starting_month_combo.on_change = [update_starting_day_range](auto, auto) { update_starting_day_range(); };
auto update_combo_values = [&]() {
auto year = starting_year_combo.value();
auto month = starting_month_combo.selected_index() + 1;
auto day = starting_day_combo.value();
auto hour = starting_hour_combo.value();
auto minute = starting_minute_combo.value();
m_date_time = Core::DateTime::create(year, month, day, hour, minute);
};
starting_year_combo.on_change = [update_combo_values](auto) { update_combo_values(); };
starting_month_combo.on_change = [update_combo_values](auto, auto) { update_combo_values(); };
starting_day_combo.on_change = [update_combo_values](auto) { update_combo_values(); };
starting_hour_combo.on_change = [update_combo_values](auto) { update_combo_values(); };
starting_minute_combo.on_change = [update_combo_values](auto) { update_combo_values(); };
event_title_textbox.set_focus(true);
}
ErrorOr<void> AddEventDialog::add_event_to_calendar()
{
JsonObject event;
auto start_date = TRY(String::formatted("{}-{:0>2d}-{:0>2d}", m_date_time.year(), m_date_time.month(), m_date_time.day()));
auto start_time = TRY(String::formatted("{}:{:0>2d}", m_date_time.hour(), m_date_time.minute()));
auto summary = find_descendant_of_type_named<GUI::TextBox>("event_title_textbox")->get_text();
event.set("start_date", JsonValue(start_date));
event.set("start_time", JsonValue(start_time));
event.set("summary", JsonValue(summary));
TRY(m_event_manager.add_event(event));
m_event_manager.set_dirty(true);
return {};
}
int AddEventDialog::MonthListModel::row_count(const GUI::ModelIndex&) const
{
return 12;
}
int AddEventDialog::MeridiemListModel::row_count(const GUI::ModelIndex&) const
{
return 2;
}
ErrorOr<String> AddEventDialog::MonthListModel::column_name(int column) const
{
switch (column) {
case Column::Month:
return "Month"_string;
default:
VERIFY_NOT_REACHED();
}
}
ErrorOr<String> AddEventDialog::MeridiemListModel::column_name(int column) const
{
switch (column) {
case Column::Meridiem:
return "Meridiem"_string;
default:
VERIFY_NOT_REACHED();
}
}
GUI::Variant AddEventDialog::MonthListModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
{
constexpr Array short_month_names = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
auto& month = short_month_names[index.row()];
if (role == GUI::ModelRole::Display) {
switch (index.column()) {
case Column::Month:
return month;
default:
VERIFY_NOT_REACHED();
}
}
return {};
}
GUI::Variant AddEventDialog::MeridiemListModel::data(const GUI::ModelIndex& index, GUI::ModelRole role) const
{
constexpr Array meridiem_names = {
"AM", "PM"
};
auto& meridiem = meridiem_names[index.row()];
if (role == GUI::ModelRole::Display) {
switch (index.column()) {
case Column::Meridiem:
return meridiem;
default:
VERIFY_NOT_REACHED();
}
}
return {};
}
}