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