Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #ifndef _CALENDAR_HXX
21 : #define _CALENDAR_HXX
22 :
23 : #include "svtools/svtdllapi.h"
24 : #include <unotools/calendarwrapper.hxx>
25 : #include <com/sun/star/i18n/Weekdays.hpp>
26 :
27 : #include <vcl/ctrl.hxx>
28 : #include <vcl/timer.hxx>
29 : #include <vcl/field.hxx>
30 : #include <set>
31 :
32 : class MouseEvent;
33 : class TrackingEvent;
34 : class KeyEvent;
35 : class HelpEvent;
36 : class DataChangedEvent;
37 : class FloatingWindow;
38 : class PushButton;
39 : class ImplCFieldFloatWin;
40 :
41 : /*************************************************************************
42 :
43 : Description
44 : ============
45 :
46 : class Calendar
47 :
48 : This class allows for the selection of a date. The displayed date range is
49 : the one specified by the Date class. We display as many months as we have
50 : space in the control. The user can switch between months using a ContextMenu
51 : (clicking on the month's name) or via two ScrollButtons in-between the months.
52 :
53 : --------------------------------------------------------------------------
54 :
55 : WinBits
56 :
57 : WB_BORDER We draw a border around the window.
58 : WB_TABSTOP Keyboard control is possible. We get the focus, when
59 : the user clicks in the Control.
60 : WB_QUICKHELPSHOWSDATEINFO Show DateInfo as BallonHelp even if QuickInfo is enabled
61 : WB_BOLDTEXT We format by bold texts and DIB_BOLD is evaluated by
62 : AddDateInfo()
63 : WB_FRAMEINFO We format in a way, so that FrameInfo can be displayed
64 : and the FrameColor is evaluated by AddDateInfo()
65 : WB_RANGESELECT The user can select multiple days, which need to be
66 : consecutive
67 : WB_MULTISELECT The user can select multiple days
68 : WB_WEEKNUMBER We also display the weekdays
69 :
70 : --------------------------------------------------------------------------
71 :
72 : We set and get the selected date by SetCurDate()/GetCurDate().
73 : If the user selects a date Select() is called. If the user double clicks
74 : DoubleClick() is called.
75 :
76 : --------------------------------------------------------------------------
77 :
78 : CalcWindowSizePixel() calculates the window size in pixel that is needed
79 : to display a certain number of months.
80 :
81 : --------------------------------------------------------------------------
82 :
83 : SetSaturdayColor() and SetSundayColor() set a special color for Saturdays
84 : and Sundays.
85 : AddDateInfo() marks special days. With that we can set e.g. public holidays
86 : to another color or encircle them (for e.g. appointments).
87 : If we do not supply a year in the date, the day is used in EVERY year.
88 :
89 : AddDateInfo() can also add text for every date, which is displayed if the
90 : BalloonHelp is enabled.
91 : In order to not have to supply all years with the relevant data, we call
92 : the RequestDateInfo() handler if a new year is displayed. We can then query
93 : the year in the handler with GetRequestYear().
94 :
95 : --------------------------------------------------------------------------
96 :
97 : In order to display a ContextMenu for a date, we need to override the
98 : Command handler. GetDate() can infer the date from the mouse's position.
99 : If we use the keyboard, the current date should be use.
100 :
101 : If a ContextMenu is displayed, the baseclass' handler must not be called.
102 :
103 : --------------------------------------------------------------------------
104 :
105 : For multiple selection (WB_RANGESELECT or WB_MULTISELECT) SelectDate(),
106 : SelectDateRange() can select date ranges. SelectDateRange() selects
107 : including the end date.
108 : SetNoSelection() deselects everything.
109 : SetCurDate() does not select the current date, but only defines the focus
110 : rectangle.
111 : GetSelectDateCount()/GetSelectDate() query the selected range.
112 : IsDateSelected() queries for the status of a date.
113 :
114 : The SelectionChanging() handler is being called while a user selects a
115 : date. In it, we can change the selected range. E.g. if we want to limit
116 : or extend the selected range. The selected range is realised via SelectDate()
117 : and SelectDateRange() and queried with GetSelectDateCount()/GetSelectDate().
118 :
119 : IsSelectLeft() returns the direction of the selection:
120 : sal_True is a selection to the left or up
121 : sal_False is a selection to the right or down
122 :
123 : --------------------------------------------------------------------------
124 :
125 : If the DateRange area changes and we want to take over the selection, we
126 : should only do this is if IsScrollDateRangeChanged() retruns sal_True.
127 : This method returns sal_True if the area change was triggered by using the
128 : ScrollButtons and sal_False if it was triggered by Resize(), other method
129 : calls or by ending a selection.
130 :
131 : *************************************************************************/
132 :
133 : // ------------------
134 : // - Calendar types -
135 : // ------------------
136 :
137 : #define WB_QUICKHELPSHOWSDATEINFO ((WinBits)0x00004000)
138 : #define WB_BOLDTEXT ((WinBits)0x00008000)
139 : #define WB_FRAMEINFO ((WinBits)0x00010000)
140 : #define WB_WEEKNUMBER ((WinBits)0x00020000)
141 : // Needs to in agreement with the WinBits in the TabBar or
142 : // we move it to \vcl\inc\wintypes.hxx
143 : #ifndef WB_RANGESELECT
144 : #define WB_RANGESELECT ((WinBits)0x00200000)
145 : #endif
146 : #ifndef WB_MULTISELECT
147 : #define WB_MULTISELECT ((WinBits)0x00400000)
148 : #endif
149 :
150 : #define DIB_BOLD ((sal_uInt16)0x0001)
151 :
152 : // ------------
153 : // - Calendar -
154 : // ------------
155 :
156 : typedef std::set<sal_uInt32> IntDateSet;
157 :
158 :
159 : class SVT_DLLPUBLIC Calendar : public Control
160 : {
161 : private:
162 : IntDateSet* mpSelectTable;
163 : IntDateSet* mpOldSelectTable;
164 : IntDateSet* mpRestoreSelectTable;
165 : XubString* mpDayText[31];
166 : XubString maDayText;
167 : XubString maWeekText;
168 : CalendarWrapper maCalendarWrapper;
169 : Rectangle maPrevRect;
170 : Rectangle maNextRect;
171 : String maDayOfWeekText;
172 : sal_Int32 mnDayOfWeekAry[7];
173 : Date maOldFormatFirstDate;
174 : Date maOldFormatLastDate;
175 : Date maFirstDate;
176 : Date maOldFirstDate;
177 : Date maCurDate;
178 : Date maOldCurDate;
179 : Date maAnchorDate;
180 : Date maDropDate;
181 : Color maSelColor;
182 : Color maOtherColor;
183 : Color* mpStandardColor;
184 : Color* mpSaturdayColor;
185 : Color* mpSundayColor;
186 : sal_uLong mnDayCount;
187 : long mnDaysOffX;
188 : long mnWeekDayOffY;
189 : long mnDaysOffY;
190 : long mnMonthHeight;
191 : long mnMonthWidth;
192 : long mnMonthPerLine;
193 : long mnLines;
194 : long mnDayWidth;
195 : long mnDayHeight;
196 : long mnWeekWidth;
197 : WinBits mnWinStyle;
198 : sal_uInt16 mnFirstYear;
199 : sal_uInt16 mnLastYear;
200 : sal_uInt16 mnRequestYear;
201 : sal_Bool mbCalc:1,
202 : mbFormat:1,
203 : mbDrag:1,
204 : mbSelection:1,
205 : mbMultiSelection:1,
206 : mbWeekSel:1,
207 : mbUnSel:1,
208 : mbMenuDown:1,
209 : mbSpinDown:1,
210 : mbPrevIn:1,
211 : mbNextIn:1,
212 : mbDirect:1,
213 : mbInSelChange:1,
214 : mbTravelSelect:1,
215 : mbScrollDateRange:1,
216 : mbSelLeft:1,
217 : mbAllSel:1,
218 : mbDropPos:1;
219 : Link maSelectionChangingHdl;
220 : Link maDateRangeChangedHdl;
221 : Link maRequestDateInfoHdl;
222 : Link maDoubleClickHdl;
223 : Link maSelectHdl;
224 : Timer maDragScrollTimer;
225 : sal_uInt16 mnDragScrollHitTest;
226 :
227 : #ifdef _SV_CALENDAR_CXX
228 : using Control::ImplInitSettings;
229 : using Window::ImplInit;
230 : SVT_DLLPRIVATE void ImplInit( WinBits nWinStyle );
231 : SVT_DLLPRIVATE void ImplInitSettings();
232 : SVT_DLLPRIVATE void ImplGetWeekFont( Font& rFont ) const;
233 : SVT_DLLPRIVATE void ImplFormat();
234 : using Window::ImplHitTest;
235 : SVT_DLLPRIVATE sal_uInt16 ImplHitTest( const Point& rPos, Date& rDate ) const;
236 : SVT_DLLPRIVATE void ImplDrawSpin( sal_Bool bDrawPrev = sal_True, sal_Bool bDrawNext = sal_True );
237 : SVT_DLLPRIVATE void ImplDrawDate( long nX, long nY,
238 : sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear,
239 : DayOfWeek eDayOfWeek,
240 : sal_Bool bBack = sal_True, sal_Bool bOther = sal_False,
241 : sal_uLong nToday = 0 );
242 : SVT_DLLPRIVATE void ImplDraw( sal_Bool bPaint = sal_False );
243 : SVT_DLLPRIVATE void ImplUpdateDate( const Date& rDate );
244 : SVT_DLLPRIVATE void ImplUpdateSelection( IntDateSet* pOld );
245 : SVT_DLLPRIVATE void ImplMouseSelect( const Date& rDate, sal_uInt16 nHitTest,
246 : sal_Bool bMove, sal_Bool bExpand, sal_Bool bExtended );
247 : SVT_DLLPRIVATE void ImplUpdate( sal_Bool bCalcNew = sal_False );
248 : using Window::ImplScroll;
249 : SVT_DLLPRIVATE void ImplScroll( sal_Bool bPrev );
250 : SVT_DLLPRIVATE void ImplInvertDropPos();
251 : SVT_DLLPRIVATE void ImplShowMenu( const Point& rPos, const Date& rDate );
252 : SVT_DLLPRIVATE void ImplTracking( const Point& rPos, sal_Bool bRepeat );
253 : SVT_DLLPRIVATE void ImplEndTracking( sal_Bool bCancel );
254 : SVT_DLLPRIVATE DayOfWeek ImplGetWeekStart() const;
255 : #endif
256 :
257 : protected:
258 :
259 : DECL_STATIC_LINK( Calendar, ScrollHdl, Timer *);
260 :
261 : public:
262 : Calendar( Window* pParent, WinBits nWinStyle = 0 );
263 : ~Calendar();
264 :
265 : virtual void MouseButtonDown( const MouseEvent& rMEvt );
266 : virtual void MouseButtonUp( const MouseEvent& rMEvt );
267 : virtual void MouseMove( const MouseEvent& rMEvt );
268 : virtual void Tracking( const TrackingEvent& rMEvt );
269 : virtual void KeyInput( const KeyEvent& rKEvt );
270 : virtual void Paint( const Rectangle& rRect );
271 : virtual void Resize();
272 : virtual void GetFocus();
273 : virtual void LoseFocus();
274 : virtual void RequestHelp( const HelpEvent& rHEvt );
275 : virtual void Command( const CommandEvent& rCEvt );
276 : virtual void StateChanged( StateChangedType nStateChange );
277 : virtual void DataChanged( const DataChangedEvent& rDCEvt );
278 :
279 : virtual void SelectionChanging();
280 : virtual void DateRangeChanged();
281 : virtual void RequestDateInfo();
282 : virtual void DoubleClick();
283 : virtual void Select();
284 :
285 : const CalendarWrapper& GetCalendarWrapper() const { return maCalendarWrapper; }
286 :
287 : void SelectDate( const Date& rDate, sal_Bool bSelect = sal_True );
288 : void SetNoSelection();
289 : sal_Bool IsDateSelected( const Date& rDate ) const;
290 : Date GetFirstSelectedDate() const;
291 0 : void EnableCallEverySelect( sal_Bool bEvery = sal_True ) { mbAllSel = bEvery; }
292 : sal_Bool IsCallEverySelectEnabled() const { return mbAllSel; }
293 :
294 : sal_uInt16 GetRequestYear() const { return mnRequestYear; }
295 : void SetCurDate( const Date& rNewDate );
296 : Date GetCurDate() const { return maCurDate; }
297 : void SetFirstDate( const Date& rNewFirstDate );
298 0 : Date GetFirstDate() const { return maFirstDate; }
299 0 : Date GetLastDate() const { return GetFirstDate() + mnDayCount; }
300 : sal_uLong GetDayCount() const { return mnDayCount; }
301 : Date GetFirstMonth() const;
302 : Date GetLastMonth() const;
303 : sal_uInt16 GetMonthCount() const;
304 : sal_Bool GetDate( const Point& rPos, Date& rDate ) const;
305 : Rectangle GetDateRect( const Date& rDate ) const;
306 :
307 : long GetCurMonthPerLine() const { return mnMonthPerLine; }
308 : long GetCurLines() const { return mnLines; }
309 :
310 : const Color& GetStandardColor() const;
311 : const Color& GetSaturdayColor() const;
312 : const Color& GetSundayColor() const;
313 :
314 : void StartSelection();
315 : void EndSelection();
316 :
317 0 : sal_Bool IsTravelSelect() const { return mbTravelSelect; }
318 : sal_Bool IsScrollDateRangeChanged() const { return mbScrollDateRange; }
319 : sal_Bool IsSelectLeft() const { return mbSelLeft; }
320 :
321 : Size CalcWindowSizePixel( long nCalcMonthPerLine = 1,
322 : long nCalcLines = 1 ) const;
323 :
324 : void SetSelectionChangingHdl( const Link& rLink ) { maSelectionChangingHdl = rLink; }
325 : const Link& GetSelectionChangingHdl() const { return maSelectionChangingHdl; }
326 : void SetDateRangeChangedHdl( const Link& rLink ) { maDateRangeChangedHdl = rLink; }
327 : const Link& GetDateRangeChangedHdl() const { return maDateRangeChangedHdl; }
328 : void SetRequestDateInfoHdl( const Link& rLink ) { maRequestDateInfoHdl = rLink; }
329 : const Link& GetRequestDateInfoHdl() const { return maRequestDateInfoHdl; }
330 : void SetDoubleClickHdl( const Link& rLink ) { maDoubleClickHdl = rLink; }
331 : const Link& GetDoubleClickHdl() const { return maDoubleClickHdl; }
332 0 : void SetSelectHdl( const Link& rLink ) { maSelectHdl = rLink; }
333 : const Link& GetSelectHdl() const { return maSelectHdl; }
334 : };
335 :
336 : inline const Color& Calendar::GetStandardColor() const
337 : {
338 : if ( mpStandardColor )
339 : return *mpStandardColor;
340 : else
341 : return GetFont().GetColor();
342 : }
343 :
344 : inline const Color& Calendar::GetSaturdayColor() const
345 : {
346 : if ( mpSaturdayColor )
347 : return *mpSaturdayColor;
348 : else
349 : return GetFont().GetColor();
350 : }
351 :
352 : inline const Color& Calendar::GetSundayColor() const
353 : {
354 : if ( mpSundayColor )
355 : return *mpSundayColor;
356 : else
357 : return GetFont().GetColor();
358 : }
359 :
360 : /*************************************************************************
361 :
362 : Description
363 : ============
364 :
365 : class CalendarField
366 :
367 : This class is a DateField with which one can select a date via a DropDownButton
368 : and the CalendarControl.
369 :
370 : --------------------------------------------------------------------------
371 :
372 : WinBits
373 :
374 : See DateField
375 :
376 : The preferences for the CalendarControl can be set via SetCalendarStyle().
377 :
378 : --------------------------------------------------------------------------
379 :
380 : With EnableToday()/EnableNone() we can enable a TodayButton and a NoneButton.
381 :
382 : --------------------------------------------------------------------------
383 :
384 : If we set WB_RANGESELECT with SetCalendarStyle(), we can select multiple days
385 : in the Calendar.
386 :
387 : Because we only take over the start date into the field, we should query
388 : with GetCalendar() in the SelectHandler and with GetSelectDateCount()/GetSelectDate()
389 : the selected range. We then can e.g. take over that value to another field.
390 :
391 : --------------------------------------------------------------------------
392 :
393 : If a derived Calendar should be used, we can override the CreateCalendar()
394 : method in CalendarField and create an own calendar there ourselves.
395 :
396 : *************************************************************************/
397 :
398 : // -----------------
399 : // - CalendarField -
400 : // -----------------
401 :
402 : class SVT_DLLPUBLIC CalendarField : public DateField
403 : {
404 : private:
405 : ImplCFieldFloatWin* mpFloatWin;
406 : Calendar* mpCalendar;
407 : WinBits mnCalendarStyle;
408 : PushButton* mpTodayBtn;
409 : PushButton* mpNoneBtn;
410 : Date maDefaultDate;
411 : sal_Bool mbToday;
412 : sal_Bool mbNone;
413 : Link maSelectHdl;
414 :
415 : #ifdef _SV_CALENDAR_CXX
416 : DECL_DLLPRIVATE_LINK( ImplSelectHdl, Calendar* );
417 : DECL_DLLPRIVATE_LINK( ImplClickHdl, PushButton* );
418 : DECL_DLLPRIVATE_LINK( ImplPopupModeEndHdl, void* );
419 : #endif
420 :
421 : public:
422 : CalendarField( Window* pParent, WinBits nWinStyle );
423 : ~CalendarField();
424 :
425 : virtual void Select();
426 :
427 : virtual sal_Bool ShowDropDown( sal_Bool bShow );
428 : virtual Calendar* CreateCalendar( Window* pParent );
429 : Calendar* GetCalendar();
430 :
431 : void SetDefaultDate( const Date& rDate ) { maDefaultDate = rDate; }
432 : Date GetDefaultDate() const { return maDefaultDate; }
433 :
434 0 : void EnableToday( sal_Bool bToday = sal_True ) { mbToday = bToday; }
435 : sal_Bool IsTodayEnabled() const { return mbToday; }
436 0 : void EnableNone( sal_Bool bNone = sal_True ) { mbNone = bNone; }
437 : sal_Bool IsNoneEnabled() const { return mbNone; }
438 :
439 : void SetCalendarStyle( WinBits nStyle ) { mnCalendarStyle = nStyle; }
440 : WinBits GetCalendarStyle() const { return mnCalendarStyle; }
441 :
442 : void SetSelectHdl( const Link& rLink ) { maSelectHdl = rLink; }
443 : const Link& GetSelectHdl() const { return maSelectHdl; }
444 :
445 : protected:
446 : virtual void StateChanged( StateChangedType nStateChange );
447 : };
448 :
449 : #endif // _CALENDAR_HXX
450 :
451 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|