Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / include / svtools / calendar.hxx
blob4c190b73c1574153d6df8f1fedab46f4bd860531
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
30 #include <set>
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 class Button;
42 /*************************************************************************
44 Description
45 ============
47 class Calendar
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 --------------------------------------------------------------------------
56 WinBits
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
63 AddDateInfo()
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
67 consecutive
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
85 and Sundays.
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
111 rectangle.
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)
142 #endif
143 #ifndef WB_MULTISELECT
144 #define WB_MULTISELECT ((WinBits)0x00400000)
145 #endif
147 #define DIB_BOLD ((sal_uInt16)0x0001)
149 typedef std::set<sal_Int32> IntDateSet;
152 class SVT_DLLPUBLIC Calendar : public Control
154 private:
155 IntDateSet* mpSelectTable;
156 IntDateSet* mpOldSelectTable;
157 IntDateSet* mpRestoreSelectTable;
158 OUString maDayTexts[31];
159 OUString maDayText;
160 OUString maWeekText;
161 CalendarWrapper maCalendarWrapper;
162 tools::Rectangle maPrevRect;
163 tools::Rectangle maNextRect;
164 OUString maDayOfWeekText;
165 long mnDayOfWeekAry[7];
166 Date maOldFormatFirstDate;
167 Date maOldFormatLastDate;
168 Date maFirstDate;
169 Date maOldFirstDate;
170 Date maCurDate;
171 Date maOldCurDate;
172 Date maAnchorDate;
173 Date maDropDate;
174 Color maSelColor;
175 Color maOtherColor;
176 Color* mpStandardColor;
177 Color* mpSaturdayColor;
178 Color* mpSundayColor;
179 sal_uLong mnDayCount;
180 long mnDaysOffX;
181 long mnWeekDayOffY;
182 long mnDaysOffY;
183 long mnMonthHeight;
184 long mnMonthWidth;
185 long mnMonthPerLine;
186 long mnLines;
187 long mnDayWidth;
188 long mnDayHeight;
189 long mnWeekWidth;
190 WinBits mnWinStyle;
191 sal_Int16 mnFirstYear;
192 sal_Int16 mnLastYear;
193 bool mbCalc:1,
194 mbFormat:1,
195 mbDrag:1,
196 mbSelection:1,
197 mbMultiSelection:1,
198 mbWeekSel:1,
199 mbUnSel:1,
200 mbMenuDown:1,
201 mbSpinDown:1,
202 mbPrevIn:1,
203 mbNextIn:1,
204 mbDirect:1,
205 mbTravelSelect:1,
206 mbScrollDateRange:1,
207 mbSelLeft:1,
208 mbAllSel:1,
209 mbDropPos:1;
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;
244 protected:
246 DECL_LINK( ScrollHdl, Timer *, void );
248 public:
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;
267 void Select();
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();
286 void EndSelection();
288 bool IsTravelSelect() const { return mbTravelSelect; }
290 Size CalcWindowSizePixel() const;
292 void SetSelectHdl( const Link<Calendar*,void>& rLink ) { maSelectHdl = rLink; }
296 /*************************************************************************
298 Description
299 ============
301 class CalendarField
303 This class is a DateField with which one can select a date via a DropDownButton
304 and the CalendarControl.
306 --------------------------------------------------------------------------
308 WinBits
310 See DateField
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
321 in the Calendar.
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
337 private:
338 VclPtr<ImplCFieldFloatWin> mpFloatWin;
339 VclPtr<Calendar> mpCalendar;
340 WinBits mnCalendarStyle;
341 VclPtr<PushButton> mpTodayBtn;
342 VclPtr<PushButton> mpNoneBtn;
343 Date maDefaultDate;
344 bool mbToday;
345 bool mbNone;
347 DECL_DLLPRIVATE_LINK( ImplSelectHdl, Calendar*, void );
348 DECL_DLLPRIVATE_LINK( ImplClickHdl, Button*, void );
349 DECL_DLLPRIVATE_LINK( ImplPopupModeEndHdl, FloatingWindow*, void );
351 public:
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; }
362 protected:
363 virtual void StateChanged( StateChangedType nStateChange ) override;
366 #endif // INCLUDED_SVTOOLS_CALENDAR_HXX
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */