diff --git a/headers/os/support/DateTime.h b/headers/os/support/DateTime.h index 3d06bb47d3..8ee9122652 100644 --- a/headers/os/support/DateTime.h +++ b/headers/os/support/DateTime.h @@ -119,6 +119,10 @@ public: int32 Month() const; int32 Difference(const BDate& date) const; + void SetDay(int32 day); + void SetMonth(int32 month); + void SetYear(int32 year); + int32 DayOfWeek() const; int32 DayOfYear() const; diff --git a/headers/private/shared/CalendarView.h b/headers/private/shared/CalendarView.h index 292c22f8f2..b7f0dcee66 100644 --- a/headers/private/shared/CalendarView.h +++ b/headers/private/shared/CalendarView.h @@ -79,8 +79,12 @@ public: virtual BSize PreferredSize(); int32 Day() const; - int32 Year() const; int32 Month() const; + int32 Year() const; + + bool SetDay(int32 day); + bool SetMonth(int32 month); + bool SetYear(int32 year); BDate Date() const; bool SetDate(const BDate& date); diff --git a/src/kits/shared/CalendarView.cpp b/src/kits/shared/CalendarView.cpp index f2cae8f0f2..087b5bf6fe 100644 --- a/src/kits/shared/CalendarView.cpp +++ b/src/kits/shared/CalendarView.cpp @@ -530,6 +530,57 @@ BCalendarView::Month() const } +bool +BCalendarView::SetDay(int32 day) +{ + BDate date = Date(); + date.SetDay(day); + if (!date.IsValid()) + return false; + SetDate(date); + return true; +} + + +bool +BCalendarView::SetMonth(int32 month) +{ + if (month < 1 || month > 12) + return false; + BDate date = Date(); + int32 oldDay = date.Day(); + + date.SetMonth(month); + date.SetDay(1); // make sure the date is valid + + // We must make sure that the day in month fits inside the new month. + if (oldDay > date.DaysInMonth()) + date.SetDay(date.DaysInMonth()); + else + date.SetDay(oldDay); + SetDate(date); + return true; +} + + +bool +BCalendarView::SetYear(int32 year) +{ + BDate date = Date(); + + // This can fail when going from 29 feb. on a leap year to a non-leap year. + if (date.Month() == 2 && date.Day() == 29 && !date.IsLeapYear(year)) + date.SetDay(28); + + // TODO we should also handle the "hole" at the switch between Julian and + // Gregorian calendars, which will result in an invalid date. + + date.SetYear(year); + SetDate(date); + return true; +} + + BDate BCalendarView::Date() const { diff --git a/src/kits/support/DateTime.cpp b/src/kits/support/DateTime.cpp index e07e437444..1852d35ad6 100644 --- a/src/kits/support/DateTime.cpp +++ b/src/kits/support/DateTime.cpp @@ -769,6 +769,27 @@ BDate::Difference(const BDate& date) const } +void +BDate::SetDay(int32 day) +{ + fDay = day; +} + + +void +BDate::SetMonth(int32 month) +{ + fMonth = month; +} + + +void +BDate::SetYear(int32 year) +{ + fYear = year; +} + + /*! Returns the week number of the date, if the date is invalid it will return B_ERROR. Please note that this function does only work within the Gregorian diff --git a/src/tests/kits/shared/CalendarViewTest.cpp b/src/tests/kits/shared/CalendarViewTest.cpp new file mode 100644 index 0000000000..06d23b6ffa --- /dev/null +++ b/src/tests/kits/shared/CalendarViewTest.cpp @@ -0,0 +1,77 @@ +/* + * Copyright 2014, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ + + +#include "CalendarViewTest.h" + +#include + +#include +#include + + +using namespace BPrivate; + + +CalendarViewTest::CalendarViewTest() +{ +} + + +CalendarViewTest::~CalendarViewTest() +{ +} + + +void +CalendarViewTest::TestSetters() +{ + BCalendarView view("test"); + + NextSubTest(); + view.SetDate(2004, 2, 29); + CPPUNIT_ASSERT_EQUAL(2004, view.Year()); + CPPUNIT_ASSERT_EQUAL(2, view.Month()); + CPPUNIT_ASSERT_EQUAL(29, view.Day()); + + NextSubTest(); + // Moving from leap year to leap year on 29 feb. must not change day + view.SetYear(2008); + CPPUNIT_ASSERT_EQUAL(2008, view.Year()); + CPPUNIT_ASSERT_EQUAL(2, view.Month()); + CPPUNIT_ASSERT_EQUAL(29, view.Day()); + + NextSubTest(); + // Moving from leap year to non-leap year on 29 feb. must go back to 28 + view.SetYear(2014); + CPPUNIT_ASSERT_EQUAL(2014, view.Year()); + CPPUNIT_ASSERT_EQUAL(2, view.Month()); + CPPUNIT_ASSERT_EQUAL(28, view.Day()); + + NextSubTest(); + view.SetDate(2014, 8, 31); + CPPUNIT_ASSERT_EQUAL(2014, view.Year()); + CPPUNIT_ASSERT_EQUAL(8, view.Month()); + CPPUNIT_ASSERT_EQUAL(31, view.Day()); + + NextSubTest(); + // Moving to month with less days should adjust day + view.SetMonth(2); + CPPUNIT_ASSERT_EQUAL(2014, view.Year()); + CPPUNIT_ASSERT_EQUAL(2, view.Month()); + CPPUNIT_ASSERT_EQUAL(28, view.Day()); +} + + +/*static*/ void +CalendarViewTest::AddTests(BTestSuite& parent) +{ + CppUnit::TestSuite& suite = *new CppUnit::TestSuite("CalendarViewTest"); + + suite.addTest(new CppUnit::TestCaller( + "CalendarViewTest::TestSetters", &CalendarViewTest::TestSetters)); + + parent.addTest("CalendarViewTest", &suite); +} diff --git a/src/tests/kits/shared/CalendarViewTest.h b/src/tests/kits/shared/CalendarViewTest.h new file mode 100644 index 0000000000..90de6c8f97 --- /dev/null +++ b/src/tests/kits/shared/CalendarViewTest.h @@ -0,0 +1,24 @@ +/* + * Copyright 2014, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef CALENDAR_VIEW_TEST_H +#define CALENDAR_VIEW_TEST_H + + +#include +#include + + +class CalendarViewTest : public BTestCase { +public: + CalendarViewTest(); + virtual ~CalendarViewTest(); + + void TestSetters(); + + static void AddTests(BTestSuite& suite); +}; + + +#endif // CALENDAR_VIEW_TEST_H diff --git a/src/tests/kits/shared/SharedTestAddon.cpp b/src/tests/kits/shared/SharedTestAddon.cpp index 4a698aeea7..ac3c9375af 100644 --- a/src/tests/kits/shared/SharedTestAddon.cpp +++ b/src/tests/kits/shared/SharedTestAddon.cpp @@ -7,6 +7,7 @@ #include #include +#include "CalendarViewTest.h" #include "NaturalCompareTest.h" @@ -15,6 +16,7 @@ getTestSuite() { BTestSuite* suite = new BTestSuite("Shared"); + CalendarViewTest::AddTests(*suite); NaturalCompareTest::AddTests(*suite); return suite;