Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

200 lines
6.8 KiB

  1. /*
  2. * Windows Calendar
  3. * Copyright (c) 1985 by Microsoft Corporation, all rights reserved.
  4. * Written by Mark L. Chamberlin, consultant to Microsoft.
  5. *
  6. */
  7. /*
  8. *****
  9. ***** calspecl.c
  10. *****
  11. */
  12. #include "cal.h"
  13. /* Notes about special times - 9/13/85 - MLC:
  14. I want to explain some things about special times because the design
  15. is not as clean as it should be and can lead to some confusion.
  16. As I originally planned it, a special time was defined to be an
  17. appointment time that had been inserted with the Options Special Time
  18. Insert command. An appointment time inserted this way had the fSpecial
  19. bit set in its associated QR. This is still the case, but from the
  20. user's point of view the definition of a special time is different.
  21. The problem was that user confusion could result from the original
  22. definition. For example, suppose that with the interval set to 15
  23. minutes, the user types text into a 9:15 appointment. At some
  24. point he switches the interval to 60 minutes. The 9:15 appointment
  25. is still present because it has data associated with it, and given
  26. the 60 minute interval, it sure looks like a special time to the
  27. user (particularly if he is looking at it days later and doesn't
  28. remember that it was inserted when he had the interval set to 15
  29. minutes). He tries to deleted it with the Options Special Time
  30. Delete command, but since its fSpecial bit is not set, he is
  31. told that it is not a special time, which totally confuses him,
  32. and he sues Tandy Trower. The only way to get rid of the 9:15
  33. appointment is to make it "empty" (no text, no alarm).
  34. So to avoid user confusion I ended up saying that for purposes
  35. of the Options Special Time Delete command, a special time is
  36. any time that does not fall on a regular interval given the
  37. current interval setting.
  38. The fSpecial bit now serves only one semi-rediculous purpose:
  39. With the interval set to 60, the user inserts the special time
  40. of 10:30. He types no text into that time, and there is no
  41. alarm set. He switches to 30 minute interval, and then back
  42. to 60 minute interval. Were it not for the fSpecial bit, the
  43. appointment would have disappeared because in 30 minute mode
  44. it would not look like a special time. But the fSpecial bit
  45. keeps the appointment from going away.
  46. I now consider the whole business of the fSpecial
  47. bit to be unnecessary baggage, and I am tempted to get rid of it.
  48. I am short on time, and it's not really worth making such a change
  49. at this late stage, so I won't, but if I had it to do
  50. over, I would not have the fSpecial bit.
  51. My apologies in advance to anyone who has to work on special times -
  52. I hope this explanation helps.
  53. */
  54. /**** InsertSpecial - insert a special time. */
  55. VOID APIENTRY InsertSpecial ()
  56. {
  57. QR qrNew;
  58. /* Record the current edits and prevent them from later using an
  59. invalid tld (which we are about to invalidate by fooling around
  60. with the tqr).
  61. */
  62. CalSetFocus ((HWND)NULL);
  63. /* Insert a new QR for the special time with the special time bit set.
  64. The special time bit prevents keeps the QR in the tqr even though
  65. it has no appointment text and the alarm is not set.
  66. Note that FSearchTqr was called by the Special Time dialog so
  67. votqrNext is already set up.
  68. */
  69. qrNew.cb = CBQRHEAD + 1;
  70. qrNew.fAlarm = FALSE;
  71. qrNew.fSpecial = TRUE;
  72. qrNew.tm = vtmSpecial;
  73. qrNew.qd [0] = '\0';
  74. if (FInsertQr (votqrNext, &qrNew))
  75. {
  76. /* Adjust up the scroll bar range. */
  77. AdjustDayScrollRange (1);
  78. /* Fix up the display. */
  79. SpecialTimeFin ();
  80. }
  81. }
  82. /**** DeleteSpecial - delete a special time. */
  83. VOID APIENTRY DeleteSpecial ()
  84. {
  85. register BOOL fAlarm;
  86. register DR *pdr;
  87. INT itdd;
  88. FT ftTemp;
  89. /* Note that FSearchTqr was
  90. called by the special time dialog code, and the result was
  91. TRUE. Therefore, votqrCur has been set up.
  92. */
  93. /* Record the current edits and prevent them from later using an
  94. invalid tld (which we are about to invalidate by fooling around
  95. with the tqr).
  96. */
  97. CalSetFocus ((HWND)NULL);
  98. /* Before deleting the QR, see if it had an alarm. */
  99. fAlarm = ((PQR )(PbTqrFromPdr (pdr = PdrLockCur ()) + votqrCur))
  100. -> fAlarm;
  101. ftTemp.dt = pdr -> dt;
  102. DrUnlockCur ();
  103. /* Delete the QR for the special time. */
  104. DeleteQr (votqrCur);
  105. if (fAlarm)
  106. {
  107. /* There is an alarm for the special time we're deleting.
  108. Decrement the count of alarms for this date.
  109. */
  110. FSearchTdd (ftTemp.dt, &itdd);
  111. (TddLock () + itdd) -> cAlarms--;
  112. TddUnlock ();
  113. ftTemp.tm = vtmSpecial;
  114. if (CompareFt (&ftTemp, &vftAlarmNext) == 0)
  115. {
  116. /* Cancelling the next armed alarm. Need to arm the one
  117. after it. Since the one we are cancelling has not yet
  118. gone off, it can't be time for the one after it to
  119. go off either, so there is no need to call AlarmCheck -
  120. just let it go off naturally.
  121. Note this be done AFTER the QR has been deleted and
  122. the count has been decremented so
  123. GetNextAlarm doesn't find the same alarm again.
  124. */
  125. GetNextAlarm (&vftCur, &vftCur, TRUE, (HWND)NULL);
  126. }
  127. }
  128. /* Adjust down the range of the scroll bar. */
  129. AdjustDayScrollRange (-1);
  130. /* Fix up the display. */
  131. SpecialTimeFin ();
  132. }
  133. /**** SpecialTimeFin */
  134. VOID APIENTRY SpecialTimeFin ()
  135. {
  136. register INT ln;
  137. /* Mark the DR and the file as dirty. */
  138. PdrLockCur () -> fDirty = vfDirty = TRUE;
  139. DrUnlockCur ();
  140. /* Fill the tld, using the special time as the starting time.
  141. In the insert case, FillTld will use the new special time.
  142. In the delete case, FillTld will use the first appointment
  143. time greater than the special time that was just deleted.
  144. */
  145. FillTld (vtmSpecial);
  146. /* Find the ln of the new special time (insert) or of the appointment
  147. time following the old special time (delete). It's not
  148. necessarily on the top line since there may not have been
  149. enough appointment times following it to fill up the screen.
  150. */
  151. for (ln = 0; ln < vlnLast && vtld [ln].tm < vtmSpecial; ln++)
  152. ;
  153. /* Give it the focus. (Need to set vhwndFocus before calling
  154. SetQdEc because we want the focus to go to the appointment
  155. even if it's currently in the notes area.
  156. */
  157. vhwndFocus = vhwnd3;
  158. SetQdEc (ln);
  159. /* Set the thumb, and repaint the appointments. */
  160. SetDayScrollPos (-1);
  161. InvalidateRect (vhwnd2B, (LPRECT)NULL, TRUE);
  162. }