xref: /AOO41X/main/svtools/inc/svtools/calendar.hxx (revision 01aa44aa134af97080e2cf8e8bf3a0a4cd1cffe0)
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