1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
23 #include "svtools/svtdllapi.h"
24 #include <unotools/calendarwrapper.hxx>
25 #include <com/sun/star/i18n/Weekdays.hpp>
27 #include <vcl/ctrl.hxx>
28 #include <vcl/timer.hxx>
29 #include <vcl/field.hxx>
36 class DataChangedEvent
;
39 class ImplCFieldFloatWin
;
41 /*************************************************************************
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.
53 --------------------------------------------------------------------------
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
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
67 WB_MULTISELECT The user can select multiple days
68 WB_WEEKNUMBER We also display the weekdays
70 --------------------------------------------------------------------------
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.
76 --------------------------------------------------------------------------
78 CalcWindowSizePixel() calculates the window size in pixel that is needed
79 to display a certain number of months.
81 --------------------------------------------------------------------------
83 SetSaturdayColor() and SetSundayColor() set a special color for Saturdays
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.
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().
95 --------------------------------------------------------------------------
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.
101 If a ContextMenu is displayed, the baseclass' handler must not be called.
103 --------------------------------------------------------------------------
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
111 GetSelectDateCount()/GetSelectDate() query the selected range.
112 IsDateSelected() queries for the status of a date.
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().
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
123 --------------------------------------------------------------------------
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.
131 *************************************************************************/
133 // ------------------
134 // - Calendar types -
135 // ------------------
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)
146 #ifndef WB_MULTISELECT
147 #define WB_MULTISELECT ((WinBits)0x00400000)
150 #define DIB_BOLD ((sal_uInt16)0x0001)
156 typedef std::set
<sal_uInt32
> IntDateSet
;
159 class SVT_DLLPUBLIC Calendar
: public Control
162 IntDateSet
* mpSelectTable
;
163 IntDateSet
* mpOldSelectTable
;
164 IntDateSet
* mpRestoreSelectTable
;
165 OUString maDayTexts
[31];
168 CalendarWrapper maCalendarWrapper
;
169 Rectangle maPrevRect
;
170 Rectangle maNextRect
;
171 String maDayOfWeekText
;
172 sal_Int32 mnDayOfWeekAry
[7];
173 Date maOldFormatFirstDate
;
174 Date maOldFormatLastDate
;
183 Color
* mpStandardColor
;
184 Color
* mpSaturdayColor
;
185 Color
* mpSundayColor
;
186 sal_uLong mnDayCount
;
198 sal_uInt16 mnFirstYear
;
199 sal_uInt16 mnLastYear
;
200 sal_uInt16 mnRequestYear
;
219 Link maSelectionChangingHdl
;
220 Link maDateRangeChangedHdl
;
221 Link maRequestDateInfoHdl
;
222 Link maDoubleClickHdl
;
224 Timer maDragScrollTimer
;
225 sal_uInt16 mnDragScrollHitTest
;
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( 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( sal_Bool bDrawPrev
= sal_True
, sal_Bool bDrawNext
= sal_True
);
236 SVT_DLLPRIVATE
void ImplDrawDate( long nX
, long nY
,
237 sal_uInt16 nDay
, sal_uInt16 nMonth
, sal_uInt16 nYear
,
238 DayOfWeek eDayOfWeek
,
239 sal_Bool bBack
= sal_True
, sal_Bool bOther
= sal_False
,
240 sal_uLong nToday
= 0 );
241 SVT_DLLPRIVATE
void ImplDraw( sal_Bool bPaint
= sal_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 sal_Bool bMove
, sal_Bool bExpand
, sal_Bool bExtended
);
246 SVT_DLLPRIVATE
void ImplUpdate( sal_Bool bCalcNew
= sal_False
);
247 using Window::ImplScroll
;
248 SVT_DLLPRIVATE
void ImplScroll( sal_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
, sal_Bool bRepeat
);
252 SVT_DLLPRIVATE
void ImplEndTracking( sal_Bool bCancel
);
253 SVT_DLLPRIVATE DayOfWeek
ImplGetWeekStart() const;
257 DECL_STATIC_LINK( Calendar
, ScrollHdl
, Timer
*);
260 Calendar( Window
* pParent
, WinBits nWinStyle
= 0 );
263 virtual void MouseButtonDown( const MouseEvent
& rMEvt
);
264 virtual void MouseButtonUp( const MouseEvent
& rMEvt
);
265 virtual void MouseMove( const MouseEvent
& rMEvt
);
266 virtual void Tracking( const TrackingEvent
& rMEvt
);
267 virtual void KeyInput( const KeyEvent
& rKEvt
);
268 virtual void Paint( const Rectangle
& rRect
);
269 virtual void Resize();
270 virtual void GetFocus();
271 virtual void LoseFocus();
272 virtual void RequestHelp( const HelpEvent
& rHEvt
);
273 virtual void Command( const CommandEvent
& rCEvt
);
274 virtual void StateChanged( StateChangedType nStateChange
);
275 virtual void DataChanged( const DataChangedEvent
& rDCEvt
);
277 virtual void SelectionChanging();
278 virtual void DateRangeChanged();
279 virtual void RequestDateInfo();
280 virtual void DoubleClick();
281 virtual void Select();
283 const CalendarWrapper
& GetCalendarWrapper() const { return maCalendarWrapper
; }
285 void SelectDate( const Date
& rDate
, sal_Bool bSelect
= sal_True
);
286 void SetNoSelection();
287 sal_Bool
IsDateSelected( const Date
& rDate
) const;
288 Date
GetFirstSelectedDate() const;
289 void EnableCallEverySelect( sal_Bool bEvery
= sal_True
) { mbAllSel
= bEvery
; }
290 sal_Bool
IsCallEverySelectEnabled() const { return mbAllSel
; }
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 Date
GetFirstDate() const { return maFirstDate
; }
297 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 sal_Bool
GetDate( const Point
& rPos
, Date
& rDate
) const;
303 Rectangle
GetDateRect( const Date
& rDate
) const;
305 long GetCurMonthPerLine() const { return mnMonthPerLine
; }
306 long GetCurLines() const { return mnLines
; }
308 const Color
& GetStandardColor() const;
309 const Color
& GetSaturdayColor() const;
310 const Color
& GetSundayColor() const;
312 void StartSelection();
315 sal_Bool
IsTravelSelect() const { return mbTravelSelect
; }
316 sal_Bool
IsScrollDateRangeChanged() const { return mbScrollDateRange
; }
317 sal_Bool
IsSelectLeft() const { return mbSelLeft
; }
319 Size
CalcWindowSizePixel( long nCalcMonthPerLine
= 1,
320 long nCalcLines
= 1 ) const;
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 void SetSelectHdl( const Link
& rLink
) { maSelectHdl
= rLink
; }
331 const Link
& GetSelectHdl() const { return maSelectHdl
; }
334 inline const Color
& Calendar::GetStandardColor() const
336 if ( mpStandardColor
)
337 return *mpStandardColor
;
339 return GetFont().GetColor();
342 inline const Color
& Calendar::GetSaturdayColor() const
344 if ( mpSaturdayColor
)
345 return *mpSaturdayColor
;
347 return GetFont().GetColor();
350 inline const Color
& Calendar::GetSundayColor() const
353 return *mpSundayColor
;
355 return GetFont().GetColor();
358 /*************************************************************************
365 This class is a DateField with which one can select a date via a DropDownButton
366 and the CalendarControl.
368 --------------------------------------------------------------------------
374 The preferences for the CalendarControl can be set via SetCalendarStyle().
376 --------------------------------------------------------------------------
378 With EnableToday()/EnableNone() we can enable a TodayButton and a NoneButton.
380 --------------------------------------------------------------------------
382 If we set WB_RANGESELECT with SetCalendarStyle(), we can select multiple days
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.
389 --------------------------------------------------------------------------
391 If a derived Calendar should be used, we can override the CreateCalendar()
392 method in CalendarField and create an own calendar there ourselves.
394 *************************************************************************/
400 class SVT_DLLPUBLIC CalendarField
: public DateField
403 ImplCFieldFloatWin
* mpFloatWin
;
404 Calendar
* mpCalendar
;
405 WinBits mnCalendarStyle
;
406 PushButton
* mpTodayBtn
;
407 PushButton
* mpNoneBtn
;
413 DECL_DLLPRIVATE_LINK( ImplSelectHdl
, Calendar
* );
414 DECL_DLLPRIVATE_LINK( ImplClickHdl
, PushButton
* );
415 DECL_DLLPRIVATE_LINK( ImplPopupModeEndHdl
, void* );
418 CalendarField( Window
* pParent
, WinBits nWinStyle
);
421 virtual void Select();
423 virtual sal_Bool
ShowDropDown( sal_Bool bShow
);
424 virtual Calendar
* CreateCalendar( Window
* pParent
);
425 Calendar
* GetCalendar();
427 void SetDefaultDate( const Date
& rDate
) { maDefaultDate
= rDate
; }
428 Date
GetDefaultDate() const { return maDefaultDate
; }
430 void EnableToday( sal_Bool bToday
= sal_True
) { mbToday
= bToday
; }
431 sal_Bool
IsTodayEnabled() const { return mbToday
; }
432 void EnableNone( sal_Bool bNone
= sal_True
) { mbNone
= bNone
; }
433 sal_Bool
IsNoneEnabled() const { return mbNone
; }
435 void SetCalendarStyle( WinBits nStyle
) { mnCalendarStyle
= nStyle
; }
436 WinBits
GetCalendarStyle() const { return mnCalendarStyle
; }
438 void SetSelectHdl( const Link
& rLink
) { maSelectHdl
= rLink
; }
439 const Link
& GetSelectHdl() const { return maSelectHdl
; }
442 virtual void StateChanged( StateChangedType nStateChange
);
445 #endif // _CALENDAR_HXX
447 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */