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 INCLUDED_SVTOOLS_CALENDAR_HXX
21 : #define INCLUDED_SVTOOLS_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 : OUString maDayTexts[31];
166 : OUString maDayText;
167 : OUString maWeekText;
168 : CalendarWrapper maCalendarWrapper;
169 : Rectangle maPrevRect;
170 : Rectangle maNextRect;
171 : OUString maDayOfWeekText;
172 : long 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 : 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 : using Control::ImplInitSettings;
228 : using Window::ImplInit;
229 : SVT_DLLPRIVATE void ImplInit( WinBits nWinStyle );
230 : SVT_DLLPRIVATE void ImplInitSettings();
231 : SVT_DLLPRIVATE void ImplGetWeekFont( vcl::Font& rFont ) const;
232 : SVT_DLLPRIVATE void ImplFormat();
233 : using Window::ImplHitTest;
234 : SVT_DLLPRIVATE sal_uInt16 ImplHitTest( const Point& rPos, Date& rDate ) const;
235 : SVT_DLLPRIVATE void ImplDrawSpin( bool bDrawPrev = true, bool bDrawNext = true );
236 : SVT_DLLPRIVATE void ImplDrawDate( long nX, long nY,
237 : sal_uInt16 nDay, sal_uInt16 nMonth, sal_uInt16 nYear,
238 : DayOfWeek eDayOfWeek,
239 : bool bBack = true, bool bOther = false,
240 : sal_uLong nToday = 0 );
241 : SVT_DLLPRIVATE void ImplDraw( bool bPaint = false );
242 : SVT_DLLPRIVATE void ImplUpdateDate( const Date& rDate );
243 : SVT_DLLPRIVATE void ImplUpdateSelection( IntDateSet* pOld );
244 : SVT_DLLPRIVATE void ImplMouseSelect( const Date& rDate, sal_uInt16 nHitTest,
245 : bool bMove, bool bExpand, bool bExtended );
246 : SVT_DLLPRIVATE void ImplUpdate( bool bCalcNew = false );
247 : using Window::ImplScroll;
248 : SVT_DLLPRIVATE void ImplScroll( bool bPrev );
249 : SVT_DLLPRIVATE void ImplInvertDropPos();
250 : SVT_DLLPRIVATE void ImplShowMenu( const Point& rPos, const Date& rDate );
251 : SVT_DLLPRIVATE void ImplTracking( const Point& rPos, bool bRepeat );
252 : SVT_DLLPRIVATE void ImplEndTracking( bool bCancel );
253 : SVT_DLLPRIVATE DayOfWeek ImplGetWeekStart() const;
254 :
255 : protected:
256 :
257 : DECL_STATIC_LINK( Calendar, ScrollHdl, Timer *);
258 :
259 : public:
260 : Calendar( vcl::Window* pParent, WinBits nWinStyle = 0 );
261 : virtual ~Calendar();
262 :
263 : virtual void MouseButtonDown( const MouseEvent& rMEvt ) SAL_OVERRIDE;
264 : virtual void MouseButtonUp( const MouseEvent& rMEvt ) SAL_OVERRIDE;
265 : virtual void MouseMove( const MouseEvent& rMEvt ) SAL_OVERRIDE;
266 : virtual void Tracking( const TrackingEvent& rMEvt ) SAL_OVERRIDE;
267 : virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
268 : virtual void Paint( const Rectangle& rRect ) SAL_OVERRIDE;
269 : virtual void Resize() SAL_OVERRIDE;
270 : virtual void GetFocus() SAL_OVERRIDE;
271 : virtual void LoseFocus() SAL_OVERRIDE;
272 : virtual void RequestHelp( const HelpEvent& rHEvt ) SAL_OVERRIDE;
273 : virtual void Command( const CommandEvent& rCEvt ) SAL_OVERRIDE;
274 : virtual void StateChanged( StateChangedType nStateChange ) SAL_OVERRIDE;
275 : virtual void DataChanged( const DataChangedEvent& rDCEvt ) SAL_OVERRIDE;
276 :
277 : virtual void SelectionChanging();
278 : virtual void DateRangeChanged();
279 : virtual void RequestDateInfo();
280 : virtual void DoubleClick();
281 : virtual void Select();
282 :
283 : const CalendarWrapper& GetCalendarWrapper() const { return maCalendarWrapper; }
284 :
285 : void SelectDate( const Date& rDate, bool bSelect = true );
286 : void SetNoSelection();
287 : bool IsDateSelected( const Date& rDate ) const;
288 : Date GetFirstSelectedDate() const;
289 0 : void EnableCallEverySelect( bool bEvery = true ) { mbAllSel = bEvery; }
290 : bool IsCallEverySelectEnabled() const { return mbAllSel; }
291 :
292 : sal_uInt16 GetRequestYear() const { return mnRequestYear; }
293 : void SetCurDate( const Date& rNewDate );
294 : Date GetCurDate() const { return maCurDate; }
295 : void SetFirstDate( const Date& rNewFirstDate );
296 0 : Date GetFirstDate() const { return maFirstDate; }
297 0 : Date GetLastDate() const { return GetFirstDate() + mnDayCount; }
298 : sal_uLong GetDayCount() const { return mnDayCount; }
299 : Date GetFirstMonth() const;
300 : Date GetLastMonth() const;
301 : sal_uInt16 GetMonthCount() const;
302 : bool GetDate( const Point& rPos, Date& rDate ) const;
303 : Rectangle GetDateRect( const Date& rDate ) const;
304 :
305 : long GetCurMonthPerLine() const { return mnMonthPerLine; }
306 : long GetCurLines() const { return mnLines; }
307 :
308 : const Color& GetStandardColor() const;
309 : const Color& GetSaturdayColor() const;
310 : const Color& GetSundayColor() const;
311 :
312 : void StartSelection();
313 : void EndSelection();
314 :
315 0 : bool IsTravelSelect() const { return mbTravelSelect; }
316 : bool IsScrollDateRangeChanged() const { return mbScrollDateRange; }
317 : bool IsSelectLeft() const { return mbSelLeft; }
318 :
319 : Size CalcWindowSizePixel( long nCalcMonthPerLine = 1,
320 : long nCalcLines = 1 ) const;
321 :
322 : void SetSelectionChangingHdl( const Link& rLink ) { maSelectionChangingHdl = rLink; }
323 : const Link& GetSelectionChangingHdl() const { return maSelectionChangingHdl; }
324 : void SetDateRangeChangedHdl( const Link& rLink ) { maDateRangeChangedHdl = rLink; }
325 : const Link& GetDateRangeChangedHdl() const { return maDateRangeChangedHdl; }
326 : void SetRequestDateInfoHdl( const Link& rLink ) { maRequestDateInfoHdl = rLink; }
327 : const Link& GetRequestDateInfoHdl() const { return maRequestDateInfoHdl; }
328 : void SetDoubleClickHdl( const Link& rLink ) { maDoubleClickHdl = rLink; }
329 : const Link& GetDoubleClickHdl() const { return maDoubleClickHdl; }
330 0 : void SetSelectHdl( const Link& rLink ) { maSelectHdl = rLink; }
331 : const Link& GetSelectHdl() const { return maSelectHdl; }
332 : };
333 :
334 : inline const Color& Calendar::GetStandardColor() const
335 : {
336 : if ( mpStandardColor )
337 : return *mpStandardColor;
338 : else
339 : return GetFont().GetColor();
340 : }
341 :
342 : inline const Color& Calendar::GetSaturdayColor() const
343 : {
344 : if ( mpSaturdayColor )
345 : return *mpSaturdayColor;
346 : else
347 : return GetFont().GetColor();
348 : }
349 :
350 : inline const Color& Calendar::GetSundayColor() const
351 : {
352 : if ( mpSundayColor )
353 : return *mpSundayColor;
354 : else
355 : return GetFont().GetColor();
356 : }
357 :
358 : /*************************************************************************
359 :
360 : Description
361 : ============
362 :
363 : class CalendarField
364 :
365 : This class is a DateField with which one can select a date via a DropDownButton
366 : and the CalendarControl.
367 :
368 : --------------------------------------------------------------------------
369 :
370 : WinBits
371 :
372 : See DateField
373 :
374 : The preferences for the CalendarControl can be set via SetCalendarStyle().
375 :
376 : --------------------------------------------------------------------------
377 :
378 : With EnableToday()/EnableNone() we can enable a TodayButton and a NoneButton.
379 :
380 : --------------------------------------------------------------------------
381 :
382 : If we set WB_RANGESELECT with SetCalendarStyle(), we can select multiple days
383 : in the Calendar.
384 :
385 : Because we only take over the start date into the field, we should query
386 : with GetCalendar() in the SelectHandler and with GetSelectDateCount()/GetSelectDate()
387 : the selected range. We then can e.g. take over that value to another field.
388 :
389 : --------------------------------------------------------------------------
390 :
391 : If a derived Calendar should be used, we can override the CreateCalendar()
392 : method in CalendarField and create an own calendar there ourselves.
393 :
394 : *************************************************************************/
395 :
396 :
397 : // - CalendarField -
398 :
399 :
400 : class SVT_DLLPUBLIC CalendarField : public DateField
401 : {
402 : private:
403 : ImplCFieldFloatWin* mpFloatWin;
404 : Calendar* mpCalendar;
405 : WinBits mnCalendarStyle;
406 : PushButton* mpTodayBtn;
407 : PushButton* mpNoneBtn;
408 : Date maDefaultDate;
409 : bool mbToday;
410 : bool mbNone;
411 : Link maSelectHdl;
412 :
413 : DECL_DLLPRIVATE_LINK( ImplSelectHdl, Calendar* );
414 : DECL_DLLPRIVATE_LINK( ImplClickHdl, PushButton* );
415 : DECL_DLLPRIVATE_LINK( ImplPopupModeEndHdl, void* );
416 :
417 : public:
418 : CalendarField( vcl::Window* pParent, WinBits nWinStyle );
419 : virtual ~CalendarField();
420 :
421 : virtual void Select();
422 :
423 : virtual bool ShowDropDown( bool bShow ) SAL_OVERRIDE;
424 : virtual Calendar* CreateCalendar( vcl::Window* pParent );
425 : Calendar* GetCalendar();
426 :
427 : void SetDefaultDate( const Date& rDate ) { maDefaultDate = rDate; }
428 : Date GetDefaultDate() const { return maDefaultDate; }
429 :
430 60 : void EnableToday( bool bToday = true ) { mbToday = bToday; }
431 : bool IsTodayEnabled() const { return mbToday; }
432 60 : void EnableNone( bool bNone = true ) { mbNone = bNone; }
433 : bool IsNoneEnabled() const { return mbNone; }
434 :
435 : void SetCalendarStyle( WinBits nStyle ) { mnCalendarStyle = nStyle; }
436 : WinBits GetCalendarStyle() const { return mnCalendarStyle; }
437 :
438 : void SetSelectHdl( const Link& rLink ) { maSelectHdl = rLink; }
439 : const Link& GetSelectHdl() const { return maSelectHdl; }
440 :
441 : protected:
442 : virtual void StateChanged( StateChangedType nStateChange ) SAL_OVERRIDE;
443 : };
444 :
445 : #endif // INCLUDED_SVTOOLS_CALENDAR_HXX
446 :
447 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|