From 9f90c3f0536a90bfb667957173465c113bc5a70a Mon Sep 17 00:00:00 2001 From: Harshit Sharma Date: Thu, 8 Sep 2022 11:50:01 +0530 Subject: [PATCH 1/4] Saving/Loading for events and GUI Changes for Calendar --- main/src/EventWindow.cpp | 88 +++++++++++++++++++++++++++++++++- main/src/EventWindow.h | 6 +++ main/src/db/QueryDBManager.cpp | 16 ++++++- main/src/model/Event.cpp | 33 ++++++++++++- main/src/model/Event.h | 11 ++++- main/src/utils/ICal.cpp | 2 +- 6 files changed, 148 insertions(+), 8 deletions(-) diff --git a/main/src/EventWindow.cpp b/main/src/EventWindow.cpp index 3ae23ca..fa2aea4 100644 --- a/main/src/EventWindow.cpp +++ b/main/src/EventWindow.cpp @@ -6,6 +6,7 @@ #include "EventWindow.h" #include +#include #include #include @@ -83,6 +84,10 @@ EventWindow::MessageReceived(BMessage* message) OnCheckBoxToggle(); break; + case kReminderPressed: + OnReminderCheckBoxToggle(); + break; + case kCancelPressed: PostMessage(B_QUIT_REQUESTED); break; @@ -253,6 +258,7 @@ EventWindow::OnSaveClick() time_t start; time_t end; + time_t reminderTime; BTime startTime; BTime endTime; @@ -301,10 +307,26 @@ EventWindow::OnSaveClick() Category* c = fCategoryList->ItemAt(index); category = new Category(*c); + if (fReminderCheckBox->Value() == B_CONTROL_ON) { + time_t deltaTime = std::stoi(fTextReminderTime->Text()); + BMenuItem* mI = fReminderMenu->FindMarked(); + int32 ind = fReminderMenu->IndexOf(mI); + + if (ind == 0) // hours + deltaTime *= 3600; + else if (ind == 1) // minutes + deltaTime *= 60; + + reminderTime = start - deltaTime; + } else { + reminderTime = -1; + } + Event newEvent(fTextName->Text(), fTextPlace->Text(), fTextDescription->Text(), fAllDayCheckBox->Value() == B_CONTROL_ON, - start, end, category, time(NULL), status); + start, end, category, fReminderCheckBox->Value() == B_CONTROL_ON, + reminderTime, time(NULL), status); if ((fNew == true) && (fDBManager->AddEvent(&newEvent))) CloseWindow(); @@ -384,6 +406,20 @@ EventWindow::OnCheckBoxToggle() } } +void +EventWindow::OnReminderCheckBoxToggle() +{ + if (fReminderCheckBox->Value() == B_CONTROL_ON) { + fTextReminderTime->SetText("0"); + fTextReminderTime->SetEnabled(true); + fReminderMenuField->SetEnabled(true); + } else { + fTextReminderTime->SetText(""); + fTextReminderTime->SetEnabled(false); + fReminderMenuField->SetEnabled(false); + } +} + void EventWindow::_InitInterface() @@ -397,6 +433,9 @@ EventWindow::_InitInterface() fTextEndDate = new BTextControl("EndDate", NULL, NULL, NULL); fTextStartTime = new BTextControl("StartTime", NULL, NULL, NULL); fTextEndTime = new BTextControl("EndTime", NULL, NULL, NULL); + fTextReminderTime = new BTextControl("ReminderTime", + B_TRANSLATE("Notify before Event:"), NULL, NULL); + fTextReminderTime->SetEnabled(false); const char* tooltip = B_TRANSLATE("Enter the time in HH:mm (24 hour) format."); @@ -411,6 +450,8 @@ EventWindow::_InitInterface() fAllDayCheckBox->SetValue(B_CONTROL_OFF); fCancelledCheckBox = new BCheckBox(B_TRANSLATE("Cancelled"), NULL); fHiddenCheckBox = new BCheckBox(B_TRANSLATE("Hidden"), NULL); + fReminderCheckBox = new BCheckBox(NULL, + new BMessage(kReminderPressed)); fEveryMonth = new BRadioButton( "EveryMonth", B_TRANSLATE("Monthly"), new BMessage(kOptEveryMonth)); @@ -451,6 +492,7 @@ EventWindow::_InitInterface() fEndCalButton->SetExplicitMinSize(BSize(height * 2, height)); fDBManager = new QueryDBManager(); + fCategoryList = fDBManager->GetAllCategories(((App*) be_app)->GetPreferences()->fDefaultCategory); fCategoryMenu = new BMenu("CategoryMenu"); @@ -464,12 +506,24 @@ EventWindow::_InitInterface() fCategoryMenu->SetLabelFromMarked(true); fCategoryMenu->ItemAt(0)->SetMarked(true); + fReminderMenu = new BMenu("ReminderMenu"); + fReminderMenu->AddItem(new BMenuItem("hours", NULL)); + fReminderMenu->AddItem(new BMenuItem("minutes", NULL)); + fReminderMenu->AddItem(new BMenuItem("seconds", NULL)); + fReminderMenu->SetRadioMode(true); + fReminderMenu->SetLabelFromMarked(true); + fReminderMenu->ItemAt(1)->SetMarked(true); + fStartDateEdit = new BMenu(B_TRANSLATE("Start date")); fEndDateEdit = new BMenu(B_TRANSLATE("End date")); fCategoryMenuField = new BMenuField("CategoryMenuField", NULL, fCategoryMenu); + fReminderMenuField + = new BMenuField("ReminderMenuField", NULL, fReminderMenu); + fReminderMenuField->SetEnabled(false); + BBox* fStatusBox = new BBox("StatusBox"); BLayoutBuilder::Group<>(fStatusBox, B_VERTICAL, B_USE_HALF_ITEM_SPACING) .SetInsets(B_USE_ITEM_INSETS) @@ -536,6 +590,11 @@ EventWindow::_InitInterface() .End() .Add(fDescriptionLabel) .Add(fTextDescription) + .AddGroup(B_HORIZONTAL) + .Add(fReminderCheckBox) + .Add(fTextReminderTime) + .Add(fReminderMenuField) + .End() .AddGrid() .Add(fCategoryLabel, 0, 0) .Add(fCategoryMenuField, 1, 0) @@ -611,6 +670,31 @@ EventWindow::_PopulateWithEvent(Event* event) fTextEndTime->SetText(GetLocaleTimeString(event->GetEndDateTime())); } + if (event->IsReminded()) { + fReminderCheckBox->SetValue(B_CONTROL_ON); + fTextReminderTime->SetEnabled(true); + fReminderMenuField->SetEnabled(true); + time_t deltaTime = event->GetStartDateTime() - event->GetReminderTime(); + int32 ind = 2; + + if (deltaTime%3600 == 0) { // hours + ind = 0; + deltaTime /= 3600; + } + else if (deltaTime%60 == 0) { // minutes + ind = 1; + deltaTime /= 60; + } + + fTextReminderTime->SetText(std::to_string(deltaTime).c_str()); + + fReminderMenu->ItemAt(ind)->SetMarked(true); + } else { + fReminderCheckBox->SetValue(B_CONTROL_OFF); + fTextReminderTime->SetEnabled(false); + fReminderMenuField->SetEnabled(false); + } + uint16 status = 0; if (event != NULL) status = event->GetStatus(); @@ -633,7 +717,7 @@ EventWindow::_UpdateCategoryMenu() selectedCategory = new Category(*c); delete fCategoryList; - fCategoryList = fDBManager->GetAllCategories(((App*) be_app)->GetPreferences()->fDefaultCategory); + fCategoryList = fDBManager->GetAllCategories(); Category* category; bool marked = false; diff --git a/main/src/EventWindow.h b/main/src/EventWindow.h index 1df19ab..0c3b2e8 100644 --- a/main/src/EventWindow.h +++ b/main/src/EventWindow.h @@ -50,6 +50,7 @@ class EventWindow : public BWindow void SetEndDate(BDate& date); void OnCheckBoxToggle(); + void OnReminderCheckBoxToggle(); void OnSaveClick(); void OnDeleteClick(); void CloseWindow(); @@ -71,6 +72,7 @@ class EventWindow : public BWindow static const uint32 kAllDayPressed = 1003; static const uint32 kOptEveryMonth = 1004; static const uint32 kOptEveryYear = 1005; + static const uint32 kReminderPressed = 1006; BTextControl* fTextName; BTextControl* fTextPlace; @@ -78,6 +80,7 @@ class EventWindow : public BWindow BTextControl* fTextEndDate; BTextControl* fTextStartTime; BTextControl* fTextEndTime; + BTextControl* fTextReminderTime; BTextView* fTextDescription; BView* fMainView; @@ -85,8 +88,10 @@ class EventWindow : public BWindow BMenu* fCategoryMenu; BMenu* fStartDateEdit; BMenu* fEndDateEdit; + BMenu* fReminderMenu; BMenuField* fCategoryMenuField; + BMenuField* fReminderMenuField; BStringView* fNameLabel; BStringView* fPlaceLabel; @@ -108,6 +113,7 @@ class EventWindow : public BWindow BCheckBox* fAllDayCheckBox; BCheckBox* fCancelledCheckBox; BCheckBox* fHiddenCheckBox; + BCheckBox* fReminderCheckBox; BBox* fStartDateBox; BBox* fEndDateBox; diff --git a/main/src/db/QueryDBManager.cpp b/main/src/db/QueryDBManager.cpp index 3cf0f75..e511444 100644 --- a/main/src/db/QueryDBManager.cpp +++ b/main/src/db/QueryDBManager.cpp @@ -623,6 +623,12 @@ QueryDBManager::_FileToEvent(entry_ref* ref) && end <= dayEnd + 59) allDay = true; + time_t reminder = time(NULL); + bool reminded = true; + if (node.ReadAttr("Event:Reminder", B_TIME_TYPE, 0, &reminder, sizeof(time_t)) + == B_ENTRY_NOT_FOUND) + reminded = false; + uint16 status = 0; if (statusStr.FindFirst("Notified") >= 0) status |= EVENT_NOTIFIED; @@ -634,8 +640,8 @@ QueryDBManager::_FileToEvent(entry_ref* ref) status |= EVENT_DELETED; return new Event(name.String(), place.String(), desc.String(), allDay, - start, end, EnsureCategory(catName.String()), updated, status, - idStr.String()); + start, end, EnsureCategory(catName.String()), reminded, reminder, + updated, status, idStr.String()); } @@ -737,6 +743,10 @@ QueryDBManager::_EventToFile(Event* event, BFile* file) time_t end = event->GetEndDateTime(); file->WriteAttr("Event:End", B_TIME_TYPE, 0, &end, sizeof(time_t)); + + time_t reminder = event->GetReminderTime(); + if (reminder != -1) + file->WriteAttr("Event:Reminder", B_TIME_TYPE, 0, &reminder, sizeof(time_t)); const char* icon_type = "EVENT_ICON"; if (statusInt & EVENT_HIDDEN) @@ -984,6 +994,7 @@ QueryDBManager::_EventMimetype() _AddAttribute(info, "Event:Description", "Description", B_STRING_TYPE, true, 200); _AddAttribute(info, "Event:Place", "Place", B_STRING_TYPE, true, 200); _AddAttribute(info, "Event:Updated", "Updated", B_TIME_TYPE, true, 150); + _AddAttribute(info, "Event:Reminder", "Reminder", B_TIME_TYPE, true, 150); _AddAttribute(info, "Event:Status", "Status", B_STRING_TYPE, true, 50); _AddAttribute(info, "Calendar:ID", "ID", B_STRING_TYPE, true, 100); @@ -1014,6 +1025,7 @@ QueryDBManager::_AddIndices() fs_create_index(device, "Event:Start", B_INT32_TYPE, 0); fs_create_index(device, "Event:End", B_INT32_TYPE, 0); fs_create_index(device, "Event:Updated", B_INT32_TYPE, 0); + fs_create_index(device, "Event:Reminder", B_INT32_TYPE, 0); fs_create_index(device, "Event:Status", B_STRING_TYPE, 0); fs_create_index(device, "Calendar:ID", B_STRING_TYPE, 0); fs_create_index(device, "Category:Name", B_STRING_TYPE, 0); diff --git a/main/src/model/Event.cpp b/main/src/model/Event.cpp index e8b0b5e..85c0e40 100644 --- a/main/src/model/Event.cpp +++ b/main/src/model/Event.cpp @@ -11,8 +11,8 @@ Event::Event(const char* name, const char* place, const char* description, bool allday, time_t start, time_t end, Category* category, - time_t updated /*=time(NULL)*/, uint16 status /*= 0 */, - const char* id /*= NULL*/) + bool reminded, time_t reminderTime, time_t updated /*=time(NULL)*/, + uint16 status /*= 0 */, const char* id /*= NULL*/) { fName = name; fPlace = place; @@ -25,6 +25,9 @@ Event::Event(const char* name, const char* place, const char* description, fCategory = new Category(*category); + fReminded = reminded; + fReminderTime = reminderTime; + if (id == NULL) fId = BUuid().SetToRandom().ToString(); else @@ -44,6 +47,8 @@ Event::Event(Event& event) fEnd = event.GetEndDateTime(); fUpdated = event.GetUpdated(); fStatus = event.GetStatus(); + fReminded = event.IsReminded(); + fReminderTime = event.GetReminderTime(); } @@ -179,3 +184,27 @@ Event::Equals(Event& e) const { return (fId == e.GetId()); } + +bool +Event::IsReminded() const +{ + return fReminded; +} + +void +Event::SetReminded(bool reminded) +{ + fReminded = reminded; +} + +time_t +Event::GetReminderTime() const +{ + return fReminderTime; +} + +void +Event::SetReminderTime(time_t reminderTime) +{ + fReminderTime = reminderTime; +} diff --git a/main/src/model/Event.h b/main/src/model/Event.h index 547e631..af94691 100644 --- a/main/src/model/Event.h +++ b/main/src/model/Event.h @@ -25,7 +25,8 @@ class Event public: Event(const char* name, const char* place, const char* description, bool allday, time_t start, time_t end, Category* category, - time_t updated = time(NULL), uint16 status = 0, const char* id = NULL); + bool reminded, time_t reminderTime, time_t updated = time(NULL), + uint16 status = 0, const char* id = NULL); Event(Event& event); time_t GetStartDateTime() const; @@ -54,6 +55,12 @@ class Event time_t GetUpdated() const; void SetUpdated(time_t updated); + time_t GetReminderTime() const; + void SetReminderTime(time_t reminderTime); + + bool IsReminded() const; + void SetReminded(bool reminded); + bool Equals(Event& e) const; private: @@ -65,8 +72,10 @@ class Event time_t fStart; time_t fEnd; time_t fUpdated; + time_t fReminderTime; bool fAllDay; + bool fReminded; int16 fStatus; Category* fCategory; diff --git a/main/src/utils/ICal.cpp b/main/src/utils/ICal.cpp index c9738f7..e9801fd 100644 --- a/main/src/utils/ICal.cpp +++ b/main/src/utils/ICal.cpp @@ -207,7 +207,7 @@ VEventToEvent(BStringList* vevent, QueryDBManager* DBManager) delete properties; return new Event(name.String(), place.String(), desc.String(), allDay, - start.Time_t(), end.Time_t(), category, updated.Time_t(), status, + start.Time_t(), end.Time_t(), category, true, start.Time_t(), updated.Time_t(), status, uid.String()); } From 1a347c4e4493a4c9289aae5815fa9689dd801f0e Mon Sep 17 00:00:00 2001 From: Harshit Sharma Date: Thu, 8 Sep 2022 22:38:59 +0530 Subject: [PATCH 2/4] Code style fixes and set the GetAllCategories() argument --- main/src/EventWindow.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/main/src/EventWindow.cpp b/main/src/EventWindow.cpp index fa2aea4..abcaa7e 100644 --- a/main/src/EventWindow.cpp +++ b/main/src/EventWindow.cpp @@ -309,12 +309,12 @@ EventWindow::OnSaveClick() if (fReminderCheckBox->Value() == B_CONTROL_ON) { time_t deltaTime = std::stoi(fTextReminderTime->Text()); - BMenuItem* mI = fReminderMenu->FindMarked(); - int32 ind = fReminderMenu->IndexOf(mI); + BMenuItem* menuItem = fReminderMenu->FindMarked(); + int32 index = fReminderMenu->IndexOf(menuItem); - if (ind == 0) // hours + if (index == 0) // hours deltaTime *= 3600; - else if (ind == 1) // minutes + else if (index == 1) // minutes deltaTime *= 60; reminderTime = start - deltaTime; @@ -675,20 +675,20 @@ EventWindow::_PopulateWithEvent(Event* event) fTextReminderTime->SetEnabled(true); fReminderMenuField->SetEnabled(true); time_t deltaTime = event->GetStartDateTime() - event->GetReminderTime(); - int32 ind = 2; + int32 index = 2; - if (deltaTime%3600 == 0) { // hours - ind = 0; + if (deltaTime % 3600 == 0) { // hours + index = 0; deltaTime /= 3600; } - else if (deltaTime%60 == 0) { // minutes - ind = 1; + else if (deltaTime % 60 == 0) { // minutes + index = 1; deltaTime /= 60; } fTextReminderTime->SetText(std::to_string(deltaTime).c_str()); - fReminderMenu->ItemAt(ind)->SetMarked(true); + fReminderMenu->ItemAt(index)->SetMarked(true); } else { fReminderCheckBox->SetValue(B_CONTROL_OFF); fTextReminderTime->SetEnabled(false); @@ -717,7 +717,7 @@ EventWindow::_UpdateCategoryMenu() selectedCategory = new Category(*c); delete fCategoryList; - fCategoryList = fDBManager->GetAllCategories(); + fCategoryList = fDBManager->GetAllCategories(((App*) be_app)->GetPreferences()->fDefaultCategory); Category* category; bool marked = false; From 23c21abd67f4610439bd2e9be23128484b018fa4 Mon Sep 17 00:00:00 2001 From: Harshit Sharma Date: Thu, 8 Sep 2022 23:19:23 +0530 Subject: [PATCH 3/4] Enforced only numbers in fTextReminderTime --- main/src/EventWindow.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/main/src/EventWindow.cpp b/main/src/EventWindow.cpp index abcaa7e..39b9ddd 100644 --- a/main/src/EventWindow.cpp +++ b/main/src/EventWindow.cpp @@ -437,6 +437,12 @@ EventWindow::_InitInterface() B_TRANSLATE("Notify before Event:"), NULL, NULL); fTextReminderTime->SetEnabled(false); + // only allow numbers in Reminder Time + for (uint32 i = 0; i < '0' ; i++) + fTextReminderTime->TextView()->DisallowChar(i); + for (uint32 i = '9' + 1; i < 255 ; i++) + fTextReminderTime->TextView()->DisallowChar(i); + const char* tooltip = B_TRANSLATE("Enter the time in HH:mm (24 hour) format."); fTextStartTime->SetToolTip(tooltip); From 111f5c596cc2b73a6079454660389f1737bd8eec Mon Sep 17 00:00:00 2001 From: Harshit Sharma Date: Fri, 9 Sep 2022 15:39:05 +0530 Subject: [PATCH 4/4] Bug Fix: Reminder not getting removed while updating event --- main/src/db/QueryDBManager.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/main/src/db/QueryDBManager.cpp b/main/src/db/QueryDBManager.cpp index e511444..62c78e9 100644 --- a/main/src/db/QueryDBManager.cpp +++ b/main/src/db/QueryDBManager.cpp @@ -743,10 +743,15 @@ QueryDBManager::_EventToFile(Event* event, BFile* file) time_t end = event->GetEndDateTime(); file->WriteAttr("Event:End", B_TIME_TYPE, 0, &end, sizeof(time_t)); - + time_t reminder = event->GetReminderTime(); + if (reminder != -1) file->WriteAttr("Event:Reminder", B_TIME_TYPE, 0, &reminder, sizeof(time_t)); + if (reminder == -1 && + file->ReadAttr("Event:Reminder", B_TIME_TYPE, 0, &reminder, sizeof(time_t)) + != B_ENTRY_NOT_FOUND) + file->RemoveAttr("Event:Reminder"); const char* icon_type = "EVENT_ICON"; if (statusInt & EVENT_HIDDEN)