home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 April / Chip_1997-04_cd.bin / prezent / cb / data.z / CALENDAR.CPP < prev    next >
C/C++ Source or Header  |  1997-01-16  |  7KB  |  309 lines

  1. //---------------------------------------------------------------------------
  2. // Borland C++Builder
  3. // Copyright (c) 1987, 1997 Borland International Inc.  All Rights Reserved.
  4. //---------------------------------------------------------------------------
  5. #if !defined (REGISTER_ALL_CONTROLS)
  6.   #include  "calendar.h"
  7. #else
  8.   #include "calendar\calendar.h"
  9. #endif
  10.  
  11. //#pragma resource "*.res"  //IDE links .res automatically for components
  12.  
  13. namespace Calendar{
  14. void __fastcall Register()
  15. {
  16.   TComponentClass classes[1] = {__classid(TCalendar)};
  17.   RegisterComponents("Samples", classes, 0);
  18. }
  19. } //namespace
  20.  
  21. __fastcall TCalendar::TCalendar(TComponent *AOwner) :
  22.   TCustomGrid(AOwner)
  23. {
  24.   FUseCurrentDate = true;
  25.   FixedCols       = 0;
  26.   FixedRows       = 1;
  27.   ColCount        = 7;
  28.   RowCount        = 7;
  29.   ScrollBars      = ssNone;
  30.   FDate           = Date();
  31.   (Options >> goRangeSelect) << goDrawFocusSelected;
  32.   UpdateCalendar();
  33. }
  34.  
  35. void __fastcall TCalendar::Change()
  36. {
  37.   if(FOnChange)
  38.     FOnChange(this);
  39. }
  40.  
  41. void __fastcall TCalendar::Click()
  42. {
  43.   AnsiString  TheCellText;
  44.  
  45.   TheCellText = CellText[Col][Row];
  46.   if(!TheCellText.IsEmpty())
  47.     Day = StrToInt(TheCellText);
  48. }
  49.  
  50.  
  51. /* Don't have any leap year code available.  Seemed like a straigthforward
  52.    translation, but should be checked.
  53. */
  54. bool __fastcall TCalendar::IsLeapYear(int AYear)
  55. {
  56.   return  ((AYear %   4) == 0) &&
  57.          (((AYear % 100) != 0) ||
  58.           ((AYear % 400) == 0));
  59. };
  60.  
  61.  
  62. int __fastcall TCalendar::DaysPerMonth(int AYear, int AMonth)
  63. {
  64.   int result;
  65.   const int DaysInMonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  66.  
  67.   result = DaysInMonth[AMonth-1];
  68.   if ((AMonth == 2) && IsLeapYear(AYear))
  69.     ++result; // leap-year Feb is special
  70.  
  71.   return result;
  72. };
  73.  
  74. int __fastcall TCalendar::DaysThisMonth()
  75. {
  76.   return DaysPerMonth(Year, Month);
  77. };
  78.  
  79.  
  80. void __fastcall TCalendar::DrawCell(long ACol, long ARow, const TRect &ARect,
  81.   TGridDrawState /*AState*/)
  82. {
  83.   const AnsiString  TheText = CellText[ACol][ARow];
  84.   Canvas->TextRect(
  85.     ARect,
  86.     ARect.Left + (ARect.Right - ARect.Left - Canvas->TextWidth(TheText)) / 2,
  87.     ARect.Top + (ARect.Bottom - ARect.Top - Canvas->TextHeight(TheText)) / 2,
  88.     TheText);
  89. };
  90.  
  91.  
  92. AnsiString __fastcall TCalendar::GetCellText(int ACol, int ARow)
  93. {
  94.   int DayNum;
  95.   AnsiString  result;
  96.  
  97.   if (!ARow)
  98.     // day names at tops of columns
  99.     //
  100.     result = ShortDayNames[(StartOfWeek + ACol) % 7];
  101.   else
  102.   {
  103.     DayNum = FMonthOffset + ACol + (ARow - 1) * 7;
  104.     if ((DayNum < 1) || (DayNum > DaysThisMonth()))
  105.       result = "";
  106.     else
  107.       result = IntToStr(DayNum);
  108.   }
  109.  
  110.   return result;
  111. };
  112.  
  113. bool __fastcall TCalendar::SelectCell(long ACol, long ARow)
  114. {
  115.   bool  result;
  116.  
  117.   if ((!FUpdating && FReadOnly) || !CellText[ACol][ARow].c_str())
  118.     result = false;
  119.   else
  120.    result = TCustomGrid::SelectCell(ACol, ARow);
  121.  
  122.   return result;
  123. };
  124.  
  125. void __fastcall TCalendar::SetCalendarDate(TDateTime Value)
  126. {
  127.   FDate = Value;
  128.   UpdateCalendar();
  129.   Change();
  130. };
  131.  
  132. bool __fastcall TCalendar::StoreCalendarDate()
  133. {
  134.   return !FUseCurrentDate;
  135. };
  136.  
  137. int __fastcall  TCalendar::GetDateElement(int Index)
  138. {
  139.   Word  AYear, AMonth, ADay;
  140.   int result;
  141.  
  142.   DecodeDate(FDate, AYear, AMonth, ADay);
  143.   switch(Index)
  144.   {
  145.     case 1:
  146.       result = AYear;break;
  147.  
  148.     case 2:
  149.       result = AMonth;break;
  150.  
  151.     case 3:
  152.       result = ADay;break;
  153.  
  154.     default:
  155.       result = -1;
  156.   };
  157.  
  158.   return result;
  159. };
  160.  
  161. void __fastcall TCalendar::SetDateElement(int Index, int Value)
  162. {
  163.   Word  AYear, AMonth, ADay;
  164.   bool  Update  = false;
  165.  
  166.   if (Value > 0)
  167.   {
  168.     DecodeDate(FDate, AYear, AMonth, ADay);
  169.     switch(Index)
  170.     {
  171.       case 1:
  172.         if (AYear != Value)
  173.         {
  174.           AYear   = Value;
  175.           Update  = true;
  176.         }
  177.         break;
  178.  
  179.       case 2:
  180.         if ((Value <= 12) && (Value != AMonth))
  181.         {
  182.           AMonth  = Value;
  183.           Update  = true;
  184.         }
  185.         break;
  186.  
  187.       case 3:
  188.         if ((Value <= DaysThisMonth()) && (Value != ADay))
  189.         {
  190.           ADay    = Value;
  191.           Update  = true;
  192.         }
  193.         break;
  194.     }
  195.     if (Update)
  196.     {
  197.       FDate = EncodeDate(AYear, AMonth, ADay);
  198.       FUseCurrentDate = false;
  199.       UpdateCalendar();
  200.       Change();
  201.     }
  202.   };
  203. };
  204.  
  205. void __fastcall TCalendar::SetStartOfWeek(TDayOfWeek Value)
  206. {
  207.   if (Value != FStartOfWeek)
  208.   {
  209.     FStartOfWeek = Value;
  210.     UpdateCalendar();
  211.   }
  212. };
  213.  
  214. void __fastcall TCalendar::SetUseCurrentDate(bool Value)
  215. {
  216.   if (Value != FUseCurrentDate)
  217.   {
  218.     FUseCurrentDate = Value;
  219.     if (Value)
  220.     {
  221.       FDate = Date(); // use the current date, then
  222.       UpdateCalendar();
  223.     };
  224.   };
  225. };
  226.  
  227. // Given a value of 1 or -1, moves to Next or Prev month accordingly.
  228. //
  229. void __fastcall TCalendar::ChangeMonth(int Delta)
  230. {
  231.   Word  AYear, AMonth, ADay;
  232.   TDateTime NewDate;
  233.   int CurDay;
  234.  
  235.   DecodeDate(FDate, AYear, AMonth, ADay);
  236.   CurDay = ADay;
  237.   if (Delta > 0)
  238.     ADay = DaysPerMonth(AYear, AMonth);
  239.   else
  240.     ADay = 1;
  241.  
  242.   NewDate = EncodeDate(AYear, AMonth, ADay);
  243.   NewDate = NewDate + Delta;
  244.   DecodeDate(NewDate, AYear, AMonth, ADay);
  245.   if (DaysPerMonth(AYear, AMonth) > CurDay)
  246.     ADay = CurDay;
  247.   else
  248.     ADay = DaysPerMonth(AYear, AMonth);
  249.  
  250.   CalendarDate = EncodeDate(AYear, AMonth, ADay);
  251. };
  252.  
  253. void __fastcall TCalendar::PrevMonth()
  254. {
  255.   ChangeMonth(-1);
  256. }
  257.  
  258. void __fastcall TCalendar::NextMonth()
  259. {
  260.   ChangeMonth(1);
  261. }
  262.  
  263. void __fastcall TCalendar::NextYear()
  264. {
  265.   if (IsLeapYear(Year) && (Month == 2) && (Day == 29))
  266.     Day = 28;
  267.   ++Year;
  268. }
  269.  
  270. void __fastcall TCalendar::PrevYear()
  271. {
  272.   if (IsLeapYear(Year) && (Month == 2) && (Day == 29))
  273.     Day = 28;
  274.   --Year;
  275. }
  276.  
  277. void __fastcall TCalendar::UpdateCalendar()
  278. {
  279.   Word  AYear, AMonth, ADay;
  280.   TDateTime FirstDate;
  281.  
  282.   FUpdating = True;
  283.   DecodeDate(FDate, AYear, AMonth, ADay);
  284.   FirstDate = EncodeDate(AYear, AMonth, 1);
  285.  
  286.   // Day of week for 1st of month.
  287.   //
  288.   FMonthOffset = 2 - ((DayOfWeek(FirstDate) - StartOfWeek + 7) % 7);
  289.   if (FMonthOffset == 2)
  290.     FMonthOffset = -5;
  291.  
  292.   MoveColRow((ADay - FMonthOffset) % 7,
  293.              (ADay - FMonthOffset) / 7 + 1,
  294.              False, False);
  295.     Invalidate();
  296.  
  297.   FUpdating = False;
  298. };
  299.  
  300. void __fastcall TCalendar::WMSize(TWMSize &Message)
  301. {
  302.   int GridLines;
  303.  
  304.   GridLines = 6 * GridLineWidth;
  305.   DefaultColWidth   = (Message.Width - GridLines) / 7;
  306.   DefaultRowHeight  = (Message.Height - GridLines) / 7;
  307. }
  308.  
  309.