5 import "CalendarControl"
7 #define ISLEAP(y) (!((y)%4) && (((y) % 100) || (!((y)% 400))))
9 /*static */Array<const String> enLongDaysNames
11 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
13 /*static */Array<const String> enLongMonthsNames
15 "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
18 /*static */Array<const String> enShortDaysNames
20 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
22 /*static */Array<const String> enShortMonthsNames
24 "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
27 /*static */Array<const String> longDaysNames
29 $"Sunday", $"Monday", $"Tuesday", $"Wednesday", $"Thursday", $"Friday", $"Saturday"
31 /*static */Array<const String> longMonthsNames
33 $"January", $"February", $"March", $"April", $"LongMonthNames"."May", $"June", $"July", $"August", $"September", $"October", $"November", $"December"
36 /*static */Array<const String> shortDaysNames
38 $"Sun", $"Mon", $"Tue", $"Wed", $"Thu", $"Fri", $"Sat"
40 /*static */Array<const String> shortMonthsNames
42 $"Jan", $"Feb", $"Mar", $"Apr", $"ShortMonthNames"."May", $"Jun", $"Jul", $"Aug", $"Sep", $"Oct", $"Nov", $"Dec"
46 extern int __ecereVMethodID_class_OnGetString;
51 january, february, march, april, may, june, july, august, september, october, november, december;
53 const char * OnGetString(char * string, void * fieldData, bool * needClass)
56 if(m >= january && m <= december)
58 if(!needClass || !*needClass)
59 return longMonthsNames[m];
61 return class::OnGetString(string, fieldData, needClass);
66 bool OnGetDataFromString(const char * string)
71 for(m = 0; m<=december; m++)
73 if(!strcmpi(shortMonthsNames[m], string) || !strcmpi(longMonthsNames[m], string) ||
74 !strcmpi(enShortMonthsNames[m], string) || !strcmpi(enLongMonthsNames[m], string))
86 extern int __ecereVMethodID_class_OnGetString;
97 if(year > b.year) return 1;
98 if(year < b.year) return -1;
99 if(month > b.month) return 1;
100 if(month < b.month) return -1;
101 if(day > b.day) return 1;
102 if(day < b.day) return -1;
106 const char * OnGetString(char * stringOutput, void * fieldData, bool * needClass)
111 sprintf(stringOutput, "%s, %s %2d, %d",
112 longDaysNames[dayOfTheWeek], longMonthsNames[month], day, year);
119 const char * OnGetStringEn(char * stringOutput, void * fieldData, bool * needClass)
124 sprintf(stringOutput, "%s, %s %2d, %d",
125 enLongDaysNames[dayOfTheWeek], enLongMonthsNames[month], day, year);
132 bool OnGetDataFromString(const char * string)
135 bool gotAlphaMonth = false;
144 if(!strcmpi(string, "today") || !strcmpi(string, $"today") ||
145 !strcmpi(string, "now") || !strcmpi(string, $"now") ||
146 !strcmpi(string, "tomorrow") || !strcmpi(string, $"tomorrow") ||
147 !strcmpi(string, "yesterday") || !strcmpi(string, $"yesterday"))
150 if(!strcmpi(string, "tomorrow") || !strcmpi(string, $"tomorrow"))
152 weWant = (SecSince1970)time + 24 * 60 * 60;
153 time = (DateTime)weWant;
155 else if(!strcmpi(string, "yesterday") || !strcmpi(string, $"yesterday"))
157 weWant = (SecSince1970)time - 24 * 60 * 60;
158 time = (DateTime)weWant;
160 this.year = time.year;
161 this.month = time.month;
175 while(GetAlNum(&string, value, sizeof(value)))
177 int numeric = atoi(value);
179 bool isAlpha = false;
182 for(c = 0; (ch = UTF8GetChar(value + c, &nb)) && !isAlpha; c += nb)
184 // if(isalpha(value[c])) isAlpha = true;
185 if(CharMatchCategories(ch, letters)) isAlpha = true;
191 for(m = 0; m<Month::enumSize; m++)
192 if(!strcmpi(shortMonthsNames[m], value) || !strcmpi(longMonthsNames[m], value) ||
193 !strcmpi(enShortMonthsNames[m], value) || !strcmpi(enLongMonthsNames[m], value))
196 gotAlphaMonth = true;
202 len[count] = strlen(value);
203 numerics[count++] = numeric;
207 if(count + gotAlphaMonth >= 3)
212 if(numerics[1] >= 1 && numerics[1] <= 12 &&
213 numerics[2] >= 1 && numerics[2] <= 31)
215 year = numerics[0]; yearLen = len[0];
216 month = (Month)(numerics[1] - 1);
219 else if(numerics[1] >= 1 && numerics[1] <= 31 &&
220 numerics[2] >= 1 && numerics[2] <= 12)
222 year = numerics[0]; yearLen = len[0];
224 month = (Month)(numerics[2] - 1);
227 else if(numerics[0] >= 1 && numerics[0] <= 31 &&
228 numerics[1] >= 1 && numerics[1] <= 12)
231 month = (Month)(numerics[1] - 1);
232 year = numerics[2]; yearLen = len[2];
234 else if(numerics[0] >= 1 && numerics[0] <= 12 &&
235 numerics[1] >= 1 && numerics[1] <= 31)
237 month = (Month)(numerics[0] - 1);
239 year = numerics[2]; yearLen = len[2];
242 else if(numerics[0] >= 1 && numerics[0] <= 12 &&
243 numerics[1] >= 1 && numerics[1] <= 31)
245 month = (Month)(numerics[0] - 1);
247 year = numerics[2]; yearLen = len[2];
249 else if(numerics[0] >= 1 && numerics[0] <= 31 &&
250 numerics[1] >= 1 && numerics[1] <= 12)
253 month = (Month)(numerics[1] - 1);
254 year = numerics[2]; yearLen = len[2];
261 if(numerics[0] < 1 || numerics[0] > 31 || (len[0] == 2 && numerics[0] < 10))
263 year = numerics[0]; yearLen = len[0];
266 else if(numerics[0] >= 1 && numerics[0] <= 31)
269 year = numerics[1]; yearLen = len[1];
271 else if(numerics[1] >= 1 && numerics[1] <= 31)
273 year = numerics[0]; yearLen = len[0];
280 if(year < 100 && yearLen == 2)
282 year += (time.year / 100) * 100;
283 if(Abs(year - time.year) >= 50)
287 else if(count >= 2 && !gotAlphaMonth)
291 if(numerics[0] >= 1 && numerics[0] <= 12 &&
292 numerics[1] >= 1 && numerics[1] <= 31)
294 month = (Month)(numerics[0] - 1);
297 else if(numerics[0] >= 1 && numerics[0] <= 31 &&
298 numerics[1] >= 1 && numerics[1] <= 12)
301 month = (Month)(numerics[1] - 1);
306 else if(count >= 1 && gotAlphaMonth)
314 if(day > monthLengths[ISLEAP(year)][month])
324 property DayOfTheWeek dayOfTheWeek
328 DayOfTheWeek dayOfTheWeek;
329 int a4 = (year / 4) - !(year & 3);
330 int b4 = (EPOCH_YEAR / 4) - !(EPOCH_YEAR & 3);
331 int a100 = a4 / 25 - (a4 % 25 < 0);
332 int b100 = b4 / 25 - (b4 % 25 < 0);
335 int leapDays = (a4 - b4) - (a100 - b100) + (a400 - b400);
336 int days = 365 * (year - EPOCH_YEAR) + leapDays;
337 days += daysInAYearBeforeMonth[ISLEAP(year)][month] + day - 1;
338 dayOfTheWeek = (EPOCH_WEEKDAY + days) % 7;
345 bool OnSaveEdit(DropBox dropBox, void * object)
347 return dropBox.Save();
350 Window OnEdit(DataBox dataBox, Window obsolete, int x, int y, int w, int h, void * fieldData)
352 const char * string = "";
357 anchor = { 0, 0, 0, 0 };
362 if(day || year || month)
364 char tempString[MAX_F_STRING] = "";
365 bool needClass = false;
366 const char * result = OnGetString(tempString, null, &needClass);
367 if(result) string = result;
369 comboBox.calendar.dateValue = this;
370 comboBox.calendar.shownMonth = month;
371 comboBox.calendar.shownYear = year;
377 comboBox.calendar.dateValue.year = now.year;
378 comboBox.calendar.dateValue.month = (Month)now.month;
379 comboBox.calendar.dateValue.day = now.day;
380 comboBox.calendar.shownMonth = (Month)now.month;
381 comboBox.calendar.shownYear = now.year;
384 comboBox.contents = string;
387 comboBox.contents = string;
392 class DateDropBox : DropBox
395 void EditNotifyUpdate(EditBox editBox)
403 editBox.NotifyUpdate = EditNotifyUpdate;
406 bool OnKeyDown(Key key, unichar ch)
408 SmartKey sKey = (SmartKey)key;
409 if(pullDown && sKey == enter)
411 // Because we can still edit the date text while the calendar is dropped, enter on the date box should validate it
412 NotifyTextEntry(master, this, contents, true);
413 ((DataBox)master).SetData(&calendar.dateValue, false);
414 ((DataBox)master).Refresh();
417 return DropBox::OnKeyDown(key, ch);
419 CalendarControl calendar
421 master = this, autoCreate = false;
424 bool OnActivate(bool active, Window previous, bool * goOnWithActivation, bool direct)
428 DateDropBox dropBox = (DateDropBox)master;
430 ((DataBox)dropBox.master).Refresh();
431 *goOnWithActivation = false;
436 void NotifyChanged(CalendarControl calendarControl, bool close)
441 Date date = calendar.dateValue;
442 dateModified = false;
443 if(date.OnGetDataFromString(contents))
445 if(date.year || date.month || date.day)
447 calendar.dateValue = date;
448 calendar.shownMonth = date.month;
449 calendar.shownYear = date.year;
455 NotifyTextEntry(master, this, null, false);
456 dateModified = false;
457 //((DataBox)master).SetData(&calendar.dateValue, false);
461 // TESTING THIS HERE:
462 ((DataBox)master).Refresh();
472 NotifyTextEntry(master, this, contents, true);
477 void OnCloseDropDown(Window dateEditor)
483 bool DataBox::NotifyTextEntry(DateDropBox dropBox, const char * string, bool save)
485 CalendarControl calendar = (CalendarControl)dropBox.calendar;
486 Date date = calendar.dateValue;
487 Date * dataBoxDate = (Date *)data;
491 if(date.OnGetDataFromString(string))
493 // TESTING THIS COMMENTED OUT HERE: (Not good -- was modifying on drop down!)
494 // With it not commented out, a current date in a SavingDataBox always shows blank
495 if(date.year != calendar.dateValue.year || date.year != dataBoxDate->year ||
496 date.month != calendar.dateValue.month || date.month != dataBoxDate->month ||
497 date.day != calendar.dateValue.day || date.day != dataBoxDate->day)
498 SetData(&date, false);
499 if(date.year || date.month || date.day)
501 calendar.dateValue = date;
502 calendar.shownMonth = date.month;
503 calendar.shownYear = date.year;
513 char tempString[1024] = "";
514 bool needClass = false;
515 // char * string = date.OnGetString(tempString, null, &needClass);
516 const char * string = ((const char *(*)(void *, void *, char *, void *, bool *))(void *)type._vTbl[__ecereVMethodID_class_OnGetString])(type, &date, tempString, null, &needClass);
517 dropBox.contents = string;
523 public class RepButton : Button
530 property Seconds delay { set { timer2.delay = value; } }
531 property Seconds delay0 { set { timer.delay = value; } }
533 bool OnKeyHit(Key key, unichar ch)
537 return NotifyClicked(master, this, 0, 0, key.modifiers);
543 bool OnKeyDown(Key key, unichar ch)
547 /*return */NotifyPushed(master, this, 0,0, key.modifiers);
548 return false; //true;
553 bool OnKeyUp(Key key, unichar ch)
557 return NotifyReleased(master, this, 0,0, key.modifiers);
563 bool NotifyPushed(RepButton button, int x, int y, Modifiers mods)
565 button.pressing = true;
566 button.NotifyClicked(this, button, x, y, mods);
567 button.timer.Start();
571 bool NotifyMouseLeave(RepButton button, Modifiers mods)
574 button.timer2.Stop();
578 bool NotifyReleased(RepButton button, int x, int y, Modifiers mods)
580 button.pressing = false;
581 button.NotifyMouseLeave(this, button, mods);
585 bool NotifyMouseOver(RepButton button, int x, int y, Modifiers mods)
588 button.timer2.Start();
600 timer2.DelayExpired(this);
609 NotifyClicked(master, this, 0, 0, 0);