/src/libreoffice/vcl/inc/calendar.hxx
Line | Count | Source |
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 | | #pragma once |
21 | | |
22 | | #include <unotools/calendarwrapper.hxx> |
23 | | |
24 | | #include <vcl/ctrl.hxx> |
25 | | #include <memory> |
26 | | #include <set> |
27 | | |
28 | | /************************************************************************* |
29 | | |
30 | | Description |
31 | | ============ |
32 | | |
33 | | class Calendar |
34 | | |
35 | | This class allows for the selection of a date. The displayed date range is |
36 | | the one specified by the Date class. We display as many months as we have |
37 | | space in the control. The user can switch between months using a ContextMenu |
38 | | (clicking on the month's name) or via two ScrollButtons in-between the months. |
39 | | |
40 | | -------------------------------------------------------------------------- |
41 | | |
42 | | WinBits |
43 | | |
44 | | WB_BORDER We draw a border around the window. |
45 | | WB_TABSTOP Keyboard control is possible. We get the focus, when |
46 | | the user clicks in the Control. |
47 | | |
48 | | -------------------------------------------------------------------------- |
49 | | |
50 | | We set and get the selected date by SetCurDate()/GetCurDate(). |
51 | | If the user selects a date Select() is called. If the user double clicks |
52 | | DoubleClick() is called. |
53 | | |
54 | | -------------------------------------------------------------------------- |
55 | | |
56 | | CalcWindowSizePixel() calculates the window size in pixel that is needed |
57 | | to display a certain number of months. |
58 | | |
59 | | -------------------------------------------------------------------------- |
60 | | |
61 | | SetSaturdayColor() and SetSundayColor() set a special color for Saturdays |
62 | | and Sundays. |
63 | | AddDateInfo() marks special days. With that we can set e.g. public holidays |
64 | | to another color or encircle them (for e.g. appointments). |
65 | | If we do not supply a year in the date, the day is used in EVERY year. |
66 | | |
67 | | AddDateInfo() can also add text for every date, which is displayed if the |
68 | | BalloonHelp is enabled. |
69 | | In order to not have to supply all years with the relevant data, we call |
70 | | the RequestDateInfo() handler if a new year is displayed. We can then query |
71 | | the year in the handler with GetRequestYear(). |
72 | | |
73 | | -------------------------------------------------------------------------- |
74 | | |
75 | | In order to display a ContextMenu for a date, we need to override the |
76 | | Command handler. GetDate() can infer the date from the mouse's position. |
77 | | If we use the keyboard, the current date should be use. |
78 | | |
79 | | If a ContextMenu is displayed, the baseclass' handler must not be called. |
80 | | |
81 | | -------------------------------------------------------------------------- |
82 | | |
83 | | SetNoSelection() deselects everything. |
84 | | SetCurDate() does not select the current date, but only defines the focus |
85 | | rectangle. |
86 | | GetSelectDateCount()/GetSelectDate() query the selected range. |
87 | | IsDateSelected() queries for the status of a date. |
88 | | |
89 | | The SelectionChanging() handler is being called while a user selects a |
90 | | date. In it, we can change the selected range. E.g. if we want to limit |
91 | | or extend the selected range. The selected range is realised via SelectDate() |
92 | | and SelectDateRange() and queried with GetSelectDateCount()/GetSelectDate(). |
93 | | |
94 | | IsSelectLeft() returns the direction of the selection: |
95 | | sal_True is a selection to the left or up |
96 | | sal_False is a selection to the right or down |
97 | | |
98 | | -------------------------------------------------------------------------- |
99 | | |
100 | | If the DateRange area changes and we want to take over the selection, we |
101 | | should only do this is if IsScrollDateRangeChanged() returns sal_True. |
102 | | This method returns sal_True if the area change was triggered by using the |
103 | | ScrollButtons and sal_False if it was triggered by Resize(), other method |
104 | | calls or by ending a selection. |
105 | | |
106 | | *************************************************************************/ |
107 | | |
108 | | typedef std::set<sal_Int32> IntDateSet; |
109 | | |
110 | | class Calendar final : public Control |
111 | | { |
112 | | std::unique_ptr<IntDateSet> mpSelectTable; |
113 | | std::unique_ptr<IntDateSet> mpOldSelectTable; |
114 | | OUString maDayTexts[31]; |
115 | | OUString maDayText; |
116 | | OUString maWeekText; |
117 | | CalendarWrapper maCalendarWrapper; |
118 | | tools::Rectangle maPrevRect; |
119 | | tools::Rectangle maNextRect; |
120 | | OUString maDayOfWeekText; |
121 | | sal_Int32 mnDayOfWeekAry[8]; |
122 | | Date maOldFormatFirstDate; |
123 | | Date maOldFormatLastDate; |
124 | | Date maFirstDate; |
125 | | Date maOldFirstDate; |
126 | | Date maCurDate; |
127 | | Date maOldCurDate; |
128 | | Color maSelColor; |
129 | | Color maOtherColor; |
130 | | sal_Int32 mnDayCount; |
131 | | tools::Long mnDaysOffX; |
132 | | tools::Long mnWeekDayOffY; |
133 | | tools::Long mnDaysOffY; |
134 | | tools::Long mnMonthHeight; |
135 | | tools::Long mnMonthWidth; |
136 | | tools::Long mnMonthPerLine; |
137 | | tools::Long mnLines; |
138 | | tools::Long mnDayWidth; |
139 | | tools::Long mnDayHeight; |
140 | | WinBits mnWinStyle; |
141 | | sal_Int16 mnFirstYear; |
142 | | sal_Int16 mnLastYear; |
143 | | bool mbCalc:1, |
144 | | mbFormat:1, |
145 | | mbDrag:1, |
146 | | mbMenuDown:1, |
147 | | mbSpinDown:1, |
148 | | mbPrevIn:1, |
149 | | mbNextIn:1; |
150 | | Link<Calendar*,void> maSelectHdl; |
151 | | Link<Calendar*,void> maActivateHdl; |
152 | | |
153 | | using Control::ImplInitSettings; |
154 | | using Window::ImplInit; |
155 | | void ImplInit( WinBits nWinStyle ); |
156 | | void ImplInitSettings(); |
157 | | |
158 | | virtual void ApplySettings(vcl::RenderContext& rRenderContext) override; |
159 | | |
160 | | void ImplFormat(); |
161 | | sal_uInt16 ImplDoHitTest( const Point& rPos, Date& rDate ) const; |
162 | | void ImplDrawSpin(vcl::RenderContext& rRenderContext); |
163 | | void ImplDrawDate(vcl::RenderContext& rRenderContext, tools::Long nX, tools::Long nY, |
164 | | sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear, |
165 | | bool bOther, sal_Int32 nToday); |
166 | | void ImplDraw(vcl::RenderContext& rRenderContext); |
167 | | void ImplUpdateDate( const Date& rDate ); |
168 | | void ImplUpdateSelection( IntDateSet* pOld ); |
169 | | void ImplMouseSelect( const Date& rDate, sal_uInt16 nHitTest ); |
170 | | void ImplUpdate( bool bCalcNew = false ); |
171 | | void ImplScrollCalendar( bool bPrev ); |
172 | | void ImplShowMenu( const Point& rPos, const Date& rDate ); |
173 | | void ImplTracking( const Point& rPos, bool bRepeat ); |
174 | | void ImplEndTracking( bool bCancel ); |
175 | | DayOfWeek ImplGetWeekStart() const; |
176 | | |
177 | | virtual Size GetOptimalSize() const override; |
178 | | public: |
179 | | Calendar( vcl::Window* pParent, WinBits nWinStyle ); |
180 | | virtual ~Calendar() override; |
181 | | virtual void dispose() override; |
182 | | |
183 | | virtual void MouseButtonDown( const MouseEvent& rMEvt ) override; |
184 | | virtual void Tracking( const TrackingEvent& rMEvt ) override; |
185 | | virtual void KeyInput( const KeyEvent& rKEvt ) override; |
186 | | virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override; |
187 | | virtual void Resize() override; |
188 | | virtual void GetFocus() override; |
189 | | virtual void LoseFocus() override; |
190 | | virtual void RequestHelp( const HelpEvent& rHEvt ) override; |
191 | | virtual void Command( const CommandEvent& rCEvt ) override; |
192 | | virtual void StateChanged( StateChangedType nStateChange ) override; |
193 | | virtual void DataChanged( const DataChangedEvent& rDCEvt ) override; |
194 | | |
195 | | void Select(); |
196 | | |
197 | | Date GetFirstSelectedDate() const; |
198 | | |
199 | | void SetCurDate( const Date& rNewDate ); |
200 | | void SetFirstDate( const Date& rNewFirstDate ); |
201 | 0 | const Date& GetFirstDate() const { return maFirstDate; } |
202 | 0 | Date GetLastDate() const { return GetFirstDate() + mnDayCount; } |
203 | | Date GetFirstMonth() const; |
204 | | Date GetLastMonth() const; |
205 | | sal_uInt16 GetMonthCount() const; |
206 | | bool GetDate( const Point& rPos, Date& rDate ) const; |
207 | | tools::Rectangle GetDateRect( const Date& rDate ) const; |
208 | | |
209 | | void EndSelection(); |
210 | | |
211 | | Size CalcWindowSizePixel() const; |
212 | | |
213 | 0 | void SetSelectHdl( const Link<Calendar*,void>& rLink ) { maSelectHdl = rLink; } |
214 | 0 | void SetActivateHdl( const Link<Calendar*,void>& rLink ) { maActivateHdl = rLink; } |
215 | | }; |
216 | | |
217 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |