Coverage Report

Created: 2026-06-30 11:14

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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: */