1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #ifndef _CALENDAR_HXX
25 #define _CALENDAR_HXX
26
27 #include "svtools/svtdllapi.h"
28 #include <unotools/calendarwrapper.hxx>
29 #ifndef _COM_SUN_STAR_I18N_WEEKDAYS_HPP
30 #include <com/sun/star/i18n/Weekdays.hpp>
31 #endif
32
33 #ifndef _CTRL_HXX
34 #include <vcl/ctrl.hxx>
35 #endif
36 #include <vcl/timer.hxx>
37 #ifndef _FIELD_HXX
38 #include <vcl/field.hxx>
39 #endif
40
41 class Table;
42 class MouseEvent;
43 class TrackingEvent;
44 class KeyEvent;
45 class HelpEvent;
46 class DataChangedEvent;
47 class FloatingWindow;
48 class PushButton;
49 struct ImplDateInfo;
50 class ImplDateTable;
51 class ImplCFieldFloatWin;
52
53 /*************************************************************************
54
55 Beschreibung
56 ============
57
58 class Calendar
59
60 Diese Klasse erlaubt die Auswahl eines Datum. Der Datumsbereich der
61 angezeigt wird, ist der, der durch die Klasse Date vorgegeben ist.
62 Es werden soviele Monate angezeigt, wie die Ausgabeflaeche des
63 Controls vorgibt. Der Anwender kann zwischen den Monaten ueber ein
64 ContextMenu (Bei Click auf den Monatstitel) oder durch 2 ScrollButtons
65 zwischen den Monaten wechseln.
66
67 --------------------------------------------------------------------------
68
69 WinBits
70
71 WB_BORDER Um das Fenster wird ein Border gezeichnet.
72 WB_TABSTOP Tastatursteuerung ist moeglich. Der Focus wird
73 sich geholt, wenn mit der Maus in das
74 Control geklickt wird.
75 WB_QUICKHELPSHOWSDATEINFO DateInfo auch bei QuickInfo als BalloonHelp zeigen
76 WB_BOLDTEXT Formatiert wird nach fetten Texten und
77 DIB_BOLD wird bei AddDateInfo() ausgewertet
78 WB_FRAMEINFO Formatiert wird so, das Frame-Info angezeigt
79 werden kann und die FrameColor bei AddDateInfo()
80 ausgewertet wird
81 WB_RANGESELECT Es koennen mehrere Tage selektiert werden, die
82 jedoch alle zusammenhaengend sein muessen
83 WB_MULTISELECT Es koennen mehrere Tage selektiert werden
84 WB_WEEKNUMBER Es werden die Wochentage mit angezeigt
85
86 --------------------------------------------------------------------------
87
88 Mit SetCurDate() / GetCurDate() wird das ausgewaehlte Datum gesetzt und
89 abgefragt. Wenn der Anwnder ein Datum selektiert hat, wird Select()
90 gerufen. Bei einem Doppelklick auf ein Datum wird DoubleClick() gerufen.
91
92 --------------------------------------------------------------------------
93
94 Mit CalcWindowSizePixel() kann die Groesse des Fensters in Pixel fuer
95 die Darstellung einer bestimmte Anzahl von Monaten berechnet werden.
96
97 --------------------------------------------------------------------------
98
99 Mit SetSaturdayColor() kann eine spezielle Farbe fuer Sonnabende gesetzt
100 werden und mit SetSundayColor() eine fuer Sonntage. Mit AddDateInfo()
101 koennen Tage speziell gekennzeichnet werden. Dabei kann man einem
102 einzelnen Datum eine andere Farbe geben (zum Beispiel fuer Feiertage)
103 oder diese Umranden (zum Beispiel fuer Termine). Wenn beim Datum
104 kein Jahr angegeben wird, wird der Tag in jedem Jahr benutzt. Mit
105 AddDateInfo() kann auch jedem Datum ein Text mitgegeben werden, der
106 dann angezeigt wird, wenn Balloon-Hilfe an ist. Um nicht alle Jahre
107 mit entsprechenden Daten zu versorgen, wird der RequestDateInfo()-
108 Handler gerufen, wenn ein neues Jahr angezeigt wird. Es kann dann
109 im Handler mit GetRequestYear() das Jahr abgefragt werden.
110
111 --------------------------------------------------------------------------
112
113 Um ein ContextMenu zu einem Datum anzuzeigen, muss man den Command-Handler
114 ueberlagern. Mit GetDate() kann zur Mouse-Position das Datum ermittelt
115 werden. Bei Tastaturausloesung sollte das aktuelle Datum genommen werden.
116 Wenn ein ContextMenu angezeigt wird, darf der Handler der Basisklasse nicht
117 gerufen werden.
118
119 --------------------------------------------------------------------------
120
121 Bei Mehrfachselektion WB_RANGESELECT oder WB_MULTISELECT kann mit
122 SelectDate()/SelectDateRange() Datumsbereiche selektiert/deselektiert
123 werden. SelectDateRange() gilt inkl. EndDatum. Mit SetNoSelection() kann
124 alles deselektiert werden. SetCurDate() selektiert bei Mehrfachselektion
125 jedoch nicht das Datum mit, sondern gibt nur das Focus-Rechteck vor.
126
127 Den selektierten Bereich kann man mit GetSelectDateCount()/GetSelectDate()
128 abgefragt werden oder der Status von einem Datum kann mit IsDateSelected()
129 abgefragt werden.
130
131 Waehrend der Anwender am selektieren ist, wird der SelectionChanging()-
132 Handler gerufen. In diesem kann der selektierte Bereich angepasst werden,
133 wenn man beispielsweise den Bereich eingrenzen oder erweitern will. Der
134 Bereich wird mit SelectDate()/SelectDateRange() umgesetzt und mit
135 GetSelectDateCount()/GetSelectDate() abgefragt. Wenn man wissen moechte,
136 in welche Richtung selektiert wird, kann dies ueber IsSelectLeft()
137 abgefragt werden. sal_True bedeutet eine Selektion nach links oder oben,
138 sal_False eine Selektion nach rechts oder unten.
139
140 --------------------------------------------------------------------------
141
142 Wenn sich der Date-Range-Bereich anpasst und man dort die Selektion
143 uebernehmen will, sollte dies nur gemacht werden, wenn
144 IsScrollDateRangeChanged() sal_True zurueckliefert. Denn diese Methode liefert
145 sal_True zurueck, wenn der Bereich durch Betaetigung von den Scroll-Buttons
146 ausgeloest wurde. Bei sal_False wurde dies durch Resize(), Methoden-Aufrufen
147 oder durch Beendigung einer Selektion ausgeloest.
148
149 *************************************************************************/
150
151 // ------------------
152 // - Calendar-Types -
153 // ------------------
154
155 #define WB_QUICKHELPSHOWSDATEINFO ((WinBits)0x00004000)
156 #define WB_BOLDTEXT ((WinBits)0x00008000)
157 #define WB_FRAMEINFO ((WinBits)0x00010000)
158 #define WB_WEEKNUMBER ((WinBits)0x00020000)
159 // Muss mit den WinBits beim TabBar uebereinstimmen oder mal
160 // nach \vcl\inc\wintypes.hxx verlagert werden
161 #ifndef WB_RANGESELECT
162 #define WB_RANGESELECT ((WinBits)0x00200000)
163 #endif
164 #ifndef WB_MULTISELECT
165 #define WB_MULTISELECT ((WinBits)0x00400000)
166 #endif
167
168 #define DIB_BOLD ((sal_uInt16)0x0001)
169
170 // ------------
171 // - Calendar -
172 // ------------
173
174 class SVT_DLLPUBLIC Calendar : public Control
175 {
176 private:
177 ImplDateTable* mpDateTable;
178 Table* mpSelectTable;
179 Table* mpOldSelectTable;
180 Table* mpRestoreSelectTable;
181 XubString* mpDayText[31];
182 XubString maDayText;
183 XubString maWeekText;
184 CalendarWrapper maCalendarWrapper;
185 Rectangle maPrevRect;
186 Rectangle maNextRect;
187 String maDayOfWeekText;
188 sal_Int32 mnDayOfWeekAry[7];
189 Date maOldFormatFirstDate;
190 Date maOldFormatLastDate;
191 Date maFirstDate;
192 Date maOldFirstDate;
193 Date maCurDate;
194 Date maOldCurDate;
195 Date maAnchorDate;
196 Date maDropDate;
197 Color maSelColor;
198 Color maOtherColor;
199 Color* mpStandardColor;
200 Color* mpSaturdayColor;
201 Color* mpSundayColor;
202 sal_uLong mnDayCount;
203 long mnDaysOffX;
204 long mnWeekDayOffY;
205 long mnDaysOffY;
206 long mnMonthHeight;
207 long mnMonthWidth;
208 long mnMonthPerLine;
209 long mnLines;
210 long mnDayWidth;
211 long mnDayHeight;
212 long mnWeekWidth;
213 long mnDummy2;
214 long mnDummy3;
215 long mnDummy4;
216 WinBits mnWinStyle;
217 sal_uInt16 mnFirstYear;
218 sal_uInt16 mnLastYear;
219 sal_uInt16 mnRequestYear;
220 sal_Bool mbCalc:1,
221 mbFormat:1,
222 mbDrag:1,
223 mbSelection:1,
224 mbMultiSelection:1,
225 mbWeekSel:1,
226 mbUnSel:1,
227 mbMenuDown:1,
228 mbSpinDown:1,
229 mbPrevIn:1,
230 mbNextIn:1,
231 mbDirect:1,
232 mbInSelChange:1,
233 mbTravelSelect:1,
234 mbScrollDateRange:1,
235 mbSelLeft:1,
236 mbAllSel:1,
237 mbDropPos:1;
238 Link maSelectionChangingHdl;
239 Link maDateRangeChangedHdl;
240 Link maRequestDateInfoHdl;
241 Link maDoubleClickHdl;
242 Link maSelectHdl;
243 Timer maDragScrollTimer;
244 sal_uInt16 mnDragScrollHitTest;
245
246 #ifdef _SV_CALENDAR_CXX
247 using Control::ImplInitSettings;
248 using Window::ImplInit;
249 SVT_DLLPRIVATE void ImplInit( WinBits nWinStyle );
250 SVT_DLLPRIVATE void ImplInitSettings();
251 SVT_DLLPRIVATE void ImplGetWeekFont( Font& rFont ) const;
252 SVT_DLLPRIVATE void ImplFormat();
253 using Window::ImplHitTest;
254 SVT_DLLPRIVATE sal_uInt16 ImplHitTest( const Point& rPos, Date& rDate ) const;
255 SVT_DLLPRIVATE void ImplDrawSpin( sal_Bool bDrawPrev = sal_True, sal_Bool bDrawNext = sal_True );
256 SVT_DLLPRIVATE void ImplDrawDate( long nX, long nY,
257 sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear,
258 DayOfWeek eDayOfWeek,
259 sal_Bool bBack = sal_True, sal_Bool bOther = sal_False,
260 sal_uLong nToday = 0 );
261 SVT_DLLPRIVATE void ImplDraw( sal_Bool bPaint = sal_False );
262 SVT_DLLPRIVATE void ImplUpdateDate( const Date& rDate );
263 SVT_DLLPRIVATE void ImplUpdateSelection( Table* pOld );
264 SVT_DLLPRIVATE void ImplMouseSelect( const Date& rDate, sal_uInt16 nHitTest,
265 sal_Bool bMove, sal_Bool bExpand, sal_Bool bExtended );
266 SVT_DLLPRIVATE void ImplUpdate( sal_Bool bCalcNew = sal_False );
267 using Window::ImplScroll;
268 SVT_DLLPRIVATE void ImplScroll( sal_Bool bPrev );
269 SVT_DLLPRIVATE void ImplInvertDropPos();
270 SVT_DLLPRIVATE void ImplShowMenu( const Point& rPos, const Date& rDate );
271 SVT_DLLPRIVATE void ImplTracking( const Point& rPos, sal_Bool bRepeat );
272 SVT_DLLPRIVATE void ImplEndTracking( sal_Bool bCancel );
273 SVT_DLLPRIVATE DayOfWeek ImplGetWeekStart() const;
274 #endif
275
276 protected:
277 sal_Bool ShowDropPos( const Point& rPos, Date& rDate );
278 void HideDropPos();
279
280 DECL_STATIC_LINK( Calendar, ScrollHdl, Timer *);
281
282 public:
283 Calendar( Window* pParent, WinBits nWinStyle = 0 );
284 Calendar( Window* pParent, const ResId& rResId );
285 ~Calendar();
286
287 virtual void MouseButtonDown( const MouseEvent& rMEvt );
288 virtual void MouseButtonUp( const MouseEvent& rMEvt );
289 virtual void MouseMove( const MouseEvent& rMEvt );
290 virtual void Tracking( const TrackingEvent& rMEvt );
291 virtual void KeyInput( const KeyEvent& rKEvt );
292 virtual void Paint( const Rectangle& rRect );
293 virtual void Resize();
294 virtual void GetFocus();
295 virtual void LoseFocus();
296 virtual void RequestHelp( const HelpEvent& rHEvt );
297 virtual void Command( const CommandEvent& rCEvt );
298 virtual void StateChanged( StateChangedType nStateChange );
299 virtual void DataChanged( const DataChangedEvent& rDCEvt );
300
301 virtual void SelectionChanging();
302 virtual void DateRangeChanged();
303 virtual void RequestDateInfo();
304 virtual void DoubleClick();
305 virtual void Select();
306
GetCalendarWrapper() const307 const CalendarWrapper& GetCalendarWrapper() const { return maCalendarWrapper; }
308
309 /// Set one of ::com::sun::star::i18n::Weekdays.
310 void SetWeekStart( sal_Int16 nDay );
311
312 /// Set how many days of a week must reside in the first week of a year.
313 void SetMinimumNumberOfDaysInWeek( sal_Int16 nDays );
314
315 void SelectDate( const Date& rDate, sal_Bool bSelect = sal_True );
316 void SelectDateRange( const Date& rStartDate, const Date& rEndDate,
317 sal_Bool bSelect = sal_True );
318 void SetNoSelection();
319 sal_Bool IsDateSelected( const Date& rDate ) const;
320 sal_uLong GetSelectDateCount() const;
321 Date GetSelectDate( sal_uLong nIndex = 0 ) const;
EnableCallEverySelect(sal_Bool bEvery=sal_True)322 void EnableCallEverySelect( sal_Bool bEvery = sal_True ) { mbAllSel = bEvery; }
IsCallEverySelectEnabled() const323 sal_Bool IsCallEverySelectEnabled() const { return mbAllSel; }
324
GetRequestYear() const325 sal_uInt16 GetRequestYear() const { return mnRequestYear; }
326 void SetCurDate( const Date& rNewDate );
GetCurDate() const327 Date GetCurDate() const { return maCurDate; }
328 void SetFirstDate( const Date& rNewFirstDate );
GetFirstDate() const329 Date GetFirstDate() const { return maFirstDate; }
GetLastDate() const330 Date GetLastDate() const { return GetFirstDate() + mnDayCount; }
GetDayCount() const331 sal_uLong GetDayCount() const { return mnDayCount; }
332 Date GetFirstMonth() const;
333 Date GetLastMonth() const;
334 sal_uInt16 GetMonthCount() const;
335 sal_Bool GetDate( const Point& rPos, Date& rDate ) const;
336 Rectangle GetDateRect( const Date& rDate ) const;
337 sal_Bool GetDropDate( Date& rDate ) const;
338
GetCurMonthPerLine() const339 long GetCurMonthPerLine() const { return mnMonthPerLine; }
GetCurLines() const340 long GetCurLines() const { return mnLines; }
341
342 void SetStandardColor( const Color& rColor );
343 const Color& GetStandardColor() const;
344 void SetSaturdayColor( const Color& rColor );
345 const Color& GetSaturdayColor() const;
346 void SetSundayColor( const Color& rColor );
347 const Color& GetSundayColor() const;
348
349 void AddDateInfo( const Date& rDate, const XubString& rText,
350 const Color* pTextColor = NULL,
351 const Color* pFrameColor = NULL,
352 sal_uInt16 nFlags = 0 );
353 void RemoveDateInfo( const Date& rDate );
354 void ClearDateInfo();
355 XubString GetDateInfoText( const Date& rDate );
356
357 void StartSelection();
358 void EndSelection();
359
IsTravelSelect() const360 sal_Bool IsTravelSelect() const { return mbTravelSelect; }
IsScrollDateRangeChanged() const361 sal_Bool IsScrollDateRangeChanged() const { return mbScrollDateRange; }
IsSelectLeft() const362 sal_Bool IsSelectLeft() const { return mbSelLeft; }
363
364 Size CalcWindowSizePixel( long nCalcMonthPerLine = 1,
365 long nCalcLines = 1 ) const;
366
SetSelectionChangingHdl(const Link & rLink)367 void SetSelectionChangingHdl( const Link& rLink ) { maSelectionChangingHdl = rLink; }
GetSelectionChangingHdl() const368 const Link& GetSelectionChangingHdl() const { return maSelectionChangingHdl; }
SetDateRangeChangedHdl(const Link & rLink)369 void SetDateRangeChangedHdl( const Link& rLink ) { maDateRangeChangedHdl = rLink; }
GetDateRangeChangedHdl() const370 const Link& GetDateRangeChangedHdl() const { return maDateRangeChangedHdl; }
SetRequestDateInfoHdl(const Link & rLink)371 void SetRequestDateInfoHdl( const Link& rLink ) { maRequestDateInfoHdl = rLink; }
GetRequestDateInfoHdl() const372 const Link& GetRequestDateInfoHdl() const { return maRequestDateInfoHdl; }
SetDoubleClickHdl(const Link & rLink)373 void SetDoubleClickHdl( const Link& rLink ) { maDoubleClickHdl = rLink; }
GetDoubleClickHdl() const374 const Link& GetDoubleClickHdl() const { return maDoubleClickHdl; }
SetSelectHdl(const Link & rLink)375 void SetSelectHdl( const Link& rLink ) { maSelectHdl = rLink; }
GetSelectHdl() const376 const Link& GetSelectHdl() const { return maSelectHdl; }
377 };
378
GetStandardColor() const379 inline const Color& Calendar::GetStandardColor() const
380 {
381 if ( mpStandardColor )
382 return *mpStandardColor;
383 else
384 return GetFont().GetColor();
385 }
386
GetSaturdayColor() const387 inline const Color& Calendar::GetSaturdayColor() const
388 {
389 if ( mpSaturdayColor )
390 return *mpSaturdayColor;
391 else
392 return GetFont().GetColor();
393 }
394
GetSundayColor() const395 inline const Color& Calendar::GetSundayColor() const
396 {
397 if ( mpSundayColor )
398 return *mpSundayColor;
399 else
400 return GetFont().GetColor();
401 }
402
403 /*************************************************************************
404
405 Beschreibung
406 ============
407
408 class CalendarField
409
410 Bei dieser Klasse handelt es sich um ein DateField, wo ueber einen
411 DropDown-Button ueber das Calendar-Control ein Datum ausgewaehlt werden
412 kann.
413
414 --------------------------------------------------------------------------
415
416 WinBits
417
418 Siehe DateField
419
420 Die Vorgaben fuer das CalendarControl koennen ueber SetCalendarStyle()
421 gesetzt werden.
422
423 --------------------------------------------------------------------------
424
425 Mit EnableToday()/EnableNone() kann ein Today-Button und ein None-Button
426 enabled werden.
427
428 --------------------------------------------------------------------------
429
430 Wenn mit SetCalendarStyle() WB_RANGESELECT gesetzt wird, koennen im
431 Calendar auch mehrere Tage selektiert werden. Da immer nur das Start-Datum
432 in das Feld uebernommen wird, sollte dann im Select-Handler mit
433 GetCalendar() der Calendar abgefragt werden und an dem mit
434 GetSelectDateCount()/GetSelectDate() der selektierte Bereich abgefragt
435 werden, um beispielsweise diese dann in ein weiteres Feld zu uebernehmen.
436
437 --------------------------------------------------------------------------
438
439 Wenn ein abgeleiteter Calendar verwendet werden soll, kann am
440 CalendarField die Methode CreateCalendar() ueberlagert werden und
441 dort ein eigener Calendar erzeugt werden.
442
443 *************************************************************************/
444
445 // -----------------
446 // - CalendarField -
447 // -----------------
448
449 class SVT_DLLPUBLIC CalendarField : public DateField
450 {
451 private:
452 ImplCFieldFloatWin* mpFloatWin;
453 Calendar* mpCalendar;
454 WinBits mnCalendarStyle;
455 PushButton* mpTodayBtn;
456 PushButton* mpNoneBtn;
457 Date maDefaultDate;
458 sal_Bool mbToday;
459 sal_Bool mbNone;
460 Link maSelectHdl;
461
462 #ifdef _SV_CALENDAR_CXX
463 DECL_DLLPRIVATE_LINK( ImplSelectHdl, Calendar* );
464 DECL_DLLPRIVATE_LINK( ImplClickHdl, PushButton* );
465 DECL_DLLPRIVATE_LINK( ImplPopupModeEndHdl, FloatingWindow* );
466 #endif
467
468 public:
469 CalendarField( Window* pParent, WinBits nWinStyle );
470 CalendarField( Window* pParent, const ResId& rResId );
471 ~CalendarField();
472
473 virtual void Select();
474
475 virtual sal_Bool ShowDropDown( sal_Bool bShow );
476 virtual Calendar* CreateCalendar( Window* pParent );
477 Calendar* GetCalendar();
478
SetDefaultDate(const Date & rDate)479 void SetDefaultDate( const Date& rDate ) { maDefaultDate = rDate; }
GetDefaultDate() const480 Date GetDefaultDate() const { return maDefaultDate; }
481
EnableToday(sal_Bool bToday=sal_True)482 void EnableToday( sal_Bool bToday = sal_True ) { mbToday = bToday; }
IsTodayEnabled() const483 sal_Bool IsTodayEnabled() const { return mbToday; }
EnableNone(sal_Bool bNone=sal_True)484 void EnableNone( sal_Bool bNone = sal_True ) { mbNone = bNone; }
IsNoneEnabled() const485 sal_Bool IsNoneEnabled() const { return mbNone; }
486
SetCalendarStyle(WinBits nStyle)487 void SetCalendarStyle( WinBits nStyle ) { mnCalendarStyle = nStyle; }
GetCalendarStyle() const488 WinBits GetCalendarStyle() const { return mnCalendarStyle; }
489
SetSelectHdl(const Link & rLink)490 void SetSelectHdl( const Link& rLink ) { maSelectHdl = rLink; }
GetSelectHdl() const491 const Link& GetSelectHdl() const { return maSelectHdl; }
492
493 protected:
494 virtual void StateChanged( StateChangedType nStateChange );
495 };
496
497 #endif // _CALENDAR_HXX
498