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 .
20 #ifndef INCLUDED_SVTOOLS_CALENDAR_HXX
21 #define INCLUDED_SVTOOLS_CALENDAR_HXX
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
;
42 /*************************************************************************
49 This class allows for the selection of a date. The displayed date range is
50 the one specified by the Date class. We display as many months as we have
51 space in the control. The user can switch between months using a ContextMenu
52 (clicking on the month's name) or via two ScrollButtons in-between the months.
54 --------------------------------------------------------------------------
58 WB_BORDER We draw a border around the window.
59 WB_TABSTOP Keyboard control is possible. We get the focus, when
60 the user clicks in the Control.
61 WB_QUICKHELPSHOWSDATEINFO Show DateInfo as BallonHelp even if QuickInfo is enabled
62 WB_BOLDTEXT We format by bold texts and DIB_BOLD is evaluated by
64 WB_FRAMEINFO We format in a way, so that FrameInfo can be displayed
65 and the FrameColor is evaluated by AddDateInfo()
66 WB_RANGESELECT The user can select multiple days, which need to be
68 WB_MULTISELECT The user can select multiple days
69 WB_WEEKNUMBER We also display the weekdays
71 --------------------------------------------------------------------------
73 We set and get the selected date by SetCurDate()/GetCurDate().
74 If the user selects a date Select() is called. If the user double clicks
75 DoubleClick() is called.
77 --------------------------------------------------------------------------
79 CalcWindowSizePixel() calculates the window size in pixel that is needed
80 to display a certain number of months.
82 --------------------------------------------------------------------------
84 SetSaturdayColor() and SetSundayColor() set a special color for Saturdays
86 AddDateInfo() marks special days. With that we can set e.g. public holidays
87 to another color or encircle them (for e.g. appointments).
88 If we do not supply a year in the date, the day is used in EVERY year.
90 AddDateInfo() can also add text for every date, which is displayed if the
91 BalloonHelp is enabled.
92 In order to not have to supply all years with the relevant data, we call
93 the RequestDateInfo() handler if a new year is displayed. We can then query
94 the year in the handler with GetRequestYear().
96 --------------------------------------------------------------------------
98 In order to display a ContextMenu for a date, we need to override the
99 Command handler. GetDate() can infer the date from the mouse's position.
100 If we use the keyboard, the current date should be use.
102 If a ContextMenu is displayed, the baseclass' handler must not be called.
104 --------------------------------------------------------------------------
106 For multiple selection (WB_RANGESELECT or WB_MULTISELECT) SelectDate(),
107 SelectDateRange() can select date ranges. SelectDateRange() selects
108 including the end date.
109 SetNoSelection() deselects everything.
110 SetCurDate() does not select the current date, but only defines the focus
112 GetSelectDateCount()/GetSelectDate() query the selected range.
113 IsDateSelected() queries for the status of a date.
115 The SelectionChanging() handler is being called while a user selects a
116 date. In it, we can change the selected range. E.g. if we want to limit
117 or extend the selected range. The selected range is realised via SelectDate()
118 and SelectDateRange() and queried with GetSelectDateCount()/GetSelectDate().
120 IsSelectLeft() returns the direction of the selection:
121 sal_True is a selection to the left or up
122 sal_False is a selection to the right or down
124 --------------------------------------------------------------------------
126 If the DateRange area changes and we want to take over the selection, we
127 should only do this is if IsScrollDateRangeChanged() retruns sal_True.
128 This method returns sal_True if the area change was triggered by using the
129 ScrollButtons and sal_False if it was triggered by Resize(), other method
130 calls or by ending a selection.
132 *************************************************************************/
134 #define WB_QUICKHELPSHOWSDATEINFO ((WinBits)0x00004000)
135 #define WB_BOLDTEXT ((WinBits)0x00008000)
136 #define WB_FRAMEINFO ((WinBits)0x00010000)
137 #define WB_WEEKNUMBER ((WinBits)0x00020000)
138 // Needs to be in agreement with the WinBits in the TabBar or
139 // we move it to \vcl\inc\wintypes.hxx
140 #ifndef WB_RANGESELECT
141 #define WB_RANGESELECT ((WinBits)0x00200000)
143 #ifndef WB_MULTISELECT
144 #define WB_MULTISELECT ((WinBits)0x00400000)
147 #define DIB_BOLD ((sal_uInt16)0x0001)
149 typedef std::set
<sal_Int32
> IntDateSet
;
152 class SVT_DLLPUBLIC Calendar
: public Control
155 IntDateSet
* mpSelectTable
;
156 IntDateSet
* mpOldSelectTable
;
157 IntDateSet
* mpRestoreSelectTable
;
158 OUString maDayTexts
[31];
161 CalendarWrapper maCalendarWrapper
;
162 tools::Rectangle maPrevRect
;
163 tools::Rectangle maNextRect
;
164 OUString maDayOfWeekText
;
165 long mnDayOfWeekAry
[7];
166 Date maOldFormatFirstDate
;
167 Date maOldFormatLastDate
;
176 Color
* mpStandardColor
;
177 Color
* mpSaturdayColor
;
178 Color
* mpSundayColor
;
179 sal_uLong mnDayCount
;
191 sal_Int16 mnFirstYear
;
192 sal_Int16 mnLastYear
;
210 Link
<Calendar
*,void> maSelectHdl
;
211 Timer maDragScrollTimer
;
212 sal_uInt16 mnDragScrollHitTest
;
214 using Control::ImplInitSettings
;
215 using Window::ImplInit
;
216 SVT_DLLPRIVATE
void ImplInit( WinBits nWinStyle
);
217 SVT_DLLPRIVATE
void ImplInitSettings();
219 virtual void ApplySettings(vcl::RenderContext
& rRenderContext
) override
;
221 SVT_DLLPRIVATE
static void ImplGetWeekFont( vcl::Font
& rFont
);
222 SVT_DLLPRIVATE
void ImplFormat();
223 using Window::ImplHitTest
;
224 SVT_DLLPRIVATE sal_uInt16
ImplHitTest( const Point
& rPos
, Date
& rDate
) const;
225 SVT_DLLPRIVATE
void ImplDrawSpin(vcl::RenderContext
& rRenderContext
);
226 SVT_DLLPRIVATE
void ImplDrawDate(vcl::RenderContext
& rRenderContext
, long nX
, long nY
,
227 sal_uInt16 nDay
, sal_uInt16 nMonth
, sal_Int16 nYear
,
228 DayOfWeek eDayOfWeek
,
229 bool bOther
, sal_Int32 nToday
);
230 SVT_DLLPRIVATE
void ImplDraw(vcl::RenderContext
& rRenderContext
);
231 SVT_DLLPRIVATE
void ImplUpdateDate( const Date
& rDate
);
232 SVT_DLLPRIVATE
void ImplUpdateSelection( IntDateSet
* pOld
);
233 SVT_DLLPRIVATE
void ImplMouseSelect( const Date
& rDate
, sal_uInt16 nHitTest
,
234 bool bMove
, bool bExpand
, bool bExtended
);
235 SVT_DLLPRIVATE
void ImplUpdate( bool bCalcNew
= false );
236 using Window::ImplScroll
;
237 SVT_DLLPRIVATE
void ImplScroll( bool bPrev
);
238 SVT_DLLPRIVATE
void ImplInvertDropPos();
239 SVT_DLLPRIVATE
void ImplShowMenu( const Point
& rPos
, const Date
& rDate
);
240 SVT_DLLPRIVATE
void ImplTracking( const Point
& rPos
, bool bRepeat
);
241 SVT_DLLPRIVATE
void ImplEndTracking( bool bCancel
);
242 SVT_DLLPRIVATE DayOfWeek
ImplGetWeekStart() const;
246 DECL_LINK( ScrollHdl
, Timer
*, void );
249 Calendar( vcl::Window
* pParent
, WinBits nWinStyle
);
250 virtual ~Calendar() override
;
251 virtual void dispose() override
;
253 virtual void MouseButtonDown( const MouseEvent
& rMEvt
) override
;
254 virtual void MouseButtonUp( const MouseEvent
& rMEvt
) override
;
255 virtual void MouseMove( const MouseEvent
& rMEvt
) override
;
256 virtual void Tracking( const TrackingEvent
& rMEvt
) override
;
257 virtual void KeyInput( const KeyEvent
& rKEvt
) override
;
258 virtual void Paint( vcl::RenderContext
& rRenderContext
, const tools::Rectangle
& rRect
) override
;
259 virtual void Resize() override
;
260 virtual void GetFocus() override
;
261 virtual void LoseFocus() override
;
262 virtual void RequestHelp( const HelpEvent
& rHEvt
) override
;
263 virtual void Command( const CommandEvent
& rCEvt
) override
;
264 virtual void StateChanged( StateChangedType nStateChange
) override
;
265 virtual void DataChanged( const DataChangedEvent
& rDCEvt
) override
;
269 void SelectDate( const Date
& rDate
, bool bSelect
= true );
270 void SetNoSelection();
271 bool IsDateSelected( const Date
& rDate
) const;
272 Date
GetFirstSelectedDate() const;
273 void EnableCallEverySelect() { mbAllSel
= true; }
275 void SetCurDate( const Date
& rNewDate
);
276 void SetFirstDate( const Date
& rNewFirstDate
);
277 const Date
& GetFirstDate() const { return maFirstDate
; }
278 Date
GetLastDate() const { return GetFirstDate() + mnDayCount
; }
279 Date
GetFirstMonth() const;
280 Date
GetLastMonth() const;
281 sal_uInt16
GetMonthCount() const;
282 bool GetDate( const Point
& rPos
, Date
& rDate
) const;
283 tools::Rectangle
GetDateRect( const Date
& rDate
) const;
285 void StartSelection();
288 bool IsTravelSelect() const { return mbTravelSelect
; }
290 Size
CalcWindowSizePixel() const;
292 void SetSelectHdl( const Link
<Calendar
*,void>& rLink
) { maSelectHdl
= rLink
; }
296 /*************************************************************************
303 This class is a DateField with which one can select a date via a DropDownButton
304 and the CalendarControl.
306 --------------------------------------------------------------------------
312 The preferences for the CalendarControl can be set via SetCalendarStyle().
314 --------------------------------------------------------------------------
316 With EnableToday()/EnableNone() we can enable a TodayButton and a NoneButton.
318 --------------------------------------------------------------------------
320 If we set WB_RANGESELECT with SetCalendarStyle(), we can select multiple days
323 Because we only take over the start date into the field, we should query
324 with GetCalendar() in the SelectHandler and with GetSelectDateCount()/GetSelectDate()
325 the selected range. We then can e.g. take over that value to another field.
327 --------------------------------------------------------------------------
329 If a derived Calendar should be used, we can override the CreateCalendar()
330 method in CalendarField and create an own calendar there ourselves.
332 *************************************************************************/
335 class SVT_DLLPUBLIC CalendarField
: public DateField
338 VclPtr
<ImplCFieldFloatWin
> mpFloatWin
;
339 VclPtr
<Calendar
> mpCalendar
;
340 WinBits mnCalendarStyle
;
341 VclPtr
<PushButton
> mpTodayBtn
;
342 VclPtr
<PushButton
> mpNoneBtn
;
347 DECL_DLLPRIVATE_LINK( ImplSelectHdl
, Calendar
*, void );
348 DECL_DLLPRIVATE_LINK( ImplClickHdl
, Button
*, void );
349 DECL_DLLPRIVATE_LINK( ImplPopupModeEndHdl
, FloatingWindow
*, void );
352 CalendarField( vcl::Window
* pParent
, WinBits nWinStyle
);
353 virtual ~CalendarField() override
;
354 virtual void dispose() override
;
356 virtual bool ShowDropDown( bool bShow
) override
;
357 Calendar
* GetCalendar();
359 void EnableToday() { mbToday
= true; }
360 void EnableNone() { mbNone
= true; }
363 virtual void StateChanged( StateChangedType nStateChange
) override
;
366 #endif // INCLUDED_SVTOOLS_CALENDAR_HXX
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */