bc413e15fa
Change-Id: I36ddc11b39763dc77086591fe9bb756195b4294f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/124459 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
228 lines
9.1 KiB
C++
228 lines
9.1 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#ifndef INCLUDED_VCL_CALENDAR_HXX
|
|
#define INCLUDED_VCL_CALENDAR_HXX
|
|
|
|
#include <vcl/dllapi.h>
|
|
#include <unotools/calendarwrapper.hxx>
|
|
|
|
#include <vcl/ctrl.hxx>
|
|
#include <memory>
|
|
#include <set>
|
|
|
|
class MouseEvent;
|
|
class TrackingEvent;
|
|
class KeyEvent;
|
|
class HelpEvent;
|
|
class DataChangedEvent;
|
|
|
|
/*************************************************************************
|
|
|
|
Description
|
|
============
|
|
|
|
class Calendar
|
|
|
|
This class allows for the selection of a date. The displayed date range is
|
|
the one specified by the Date class. We display as many months as we have
|
|
space in the control. The user can switch between months using a ContextMenu
|
|
(clicking on the month's name) or via two ScrollButtons in-between the months.
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
WinBits
|
|
|
|
WB_BORDER We draw a border around the window.
|
|
WB_TABSTOP Keyboard control is possible. We get the focus, when
|
|
the user clicks in the Control.
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
We set and get the selected date by SetCurDate()/GetCurDate().
|
|
If the user selects a date Select() is called. If the user double clicks
|
|
DoubleClick() is called.
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
CalcWindowSizePixel() calculates the window size in pixel that is needed
|
|
to display a certain number of months.
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
SetSaturdayColor() and SetSundayColor() set a special color for Saturdays
|
|
and Sundays.
|
|
AddDateInfo() marks special days. With that we can set e.g. public holidays
|
|
to another color or encircle them (for e.g. appointments).
|
|
If we do not supply a year in the date, the day is used in EVERY year.
|
|
|
|
AddDateInfo() can also add text for every date, which is displayed if the
|
|
BalloonHelp is enabled.
|
|
In order to not have to supply all years with the relevant data, we call
|
|
the RequestDateInfo() handler if a new year is displayed. We can then query
|
|
the year in the handler with GetRequestYear().
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
In order to display a ContextMenu for a date, we need to override the
|
|
Command handler. GetDate() can infer the date from the mouse's position.
|
|
If we use the keyboard, the current date should be use.
|
|
|
|
If a ContextMenu is displayed, the baseclass' handler must not be called.
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
SetNoSelection() deselects everything.
|
|
SetCurDate() does not select the current date, but only defines the focus
|
|
rectangle.
|
|
GetSelectDateCount()/GetSelectDate() query the selected range.
|
|
IsDateSelected() queries for the status of a date.
|
|
|
|
The SelectionChanging() handler is being called while a user selects a
|
|
date. In it, we can change the selected range. E.g. if we want to limit
|
|
or extend the selected range. The selected range is realised via SelectDate()
|
|
and SelectDateRange() and queried with GetSelectDateCount()/GetSelectDate().
|
|
|
|
IsSelectLeft() returns the direction of the selection:
|
|
sal_True is a selection to the left or up
|
|
sal_False is a selection to the right or down
|
|
|
|
--------------------------------------------------------------------------
|
|
|
|
If the DateRange area changes and we want to take over the selection, we
|
|
should only do this is if IsScrollDateRangeChanged() returns sal_True.
|
|
This method returns sal_True if the area change was triggered by using the
|
|
ScrollButtons and sal_False if it was triggered by Resize(), other method
|
|
calls or by ending a selection.
|
|
|
|
*************************************************************************/
|
|
|
|
typedef std::set<sal_Int32> IntDateSet;
|
|
|
|
class Calendar final : public Control
|
|
{
|
|
std::unique_ptr<IntDateSet> mpSelectTable;
|
|
std::unique_ptr<IntDateSet> mpOldSelectTable;
|
|
OUString maDayTexts[31];
|
|
OUString maDayText;
|
|
OUString maWeekText;
|
|
CalendarWrapper maCalendarWrapper;
|
|
tools::Rectangle maPrevRect;
|
|
tools::Rectangle maNextRect;
|
|
OUString maDayOfWeekText;
|
|
sal_Int32 mnDayOfWeekAry[7];
|
|
Date maOldFormatFirstDate;
|
|
Date maOldFormatLastDate;
|
|
Date maFirstDate;
|
|
Date maOldFirstDate;
|
|
Date maCurDate;
|
|
Date maOldCurDate;
|
|
Color maSelColor;
|
|
Color maOtherColor;
|
|
sal_Int32 mnDayCount;
|
|
tools::Long mnDaysOffX;
|
|
tools::Long mnWeekDayOffY;
|
|
tools::Long mnDaysOffY;
|
|
tools::Long mnMonthHeight;
|
|
tools::Long mnMonthWidth;
|
|
tools::Long mnMonthPerLine;
|
|
tools::Long mnLines;
|
|
tools::Long mnDayWidth;
|
|
tools::Long mnDayHeight;
|
|
WinBits mnWinStyle;
|
|
sal_Int16 mnFirstYear;
|
|
sal_Int16 mnLastYear;
|
|
bool mbCalc:1,
|
|
mbFormat:1,
|
|
mbDrag:1,
|
|
mbMenuDown:1,
|
|
mbSpinDown:1,
|
|
mbPrevIn:1,
|
|
mbNextIn:1;
|
|
Link<Calendar*,void> maSelectHdl;
|
|
Link<Calendar*,void> maActivateHdl;
|
|
|
|
using Control::ImplInitSettings;
|
|
using Window::ImplInit;
|
|
void ImplInit( WinBits nWinStyle );
|
|
void ImplInitSettings();
|
|
|
|
virtual void ApplySettings(vcl::RenderContext& rRenderContext) override;
|
|
|
|
void ImplFormat();
|
|
sal_uInt16 ImplDoHitTest( const Point& rPos, Date& rDate ) const;
|
|
void ImplDrawSpin(vcl::RenderContext& rRenderContext);
|
|
void ImplDrawDate(vcl::RenderContext& rRenderContext, tools::Long nX, tools::Long nY,
|
|
sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear,
|
|
bool bOther, sal_Int32 nToday);
|
|
void ImplDraw(vcl::RenderContext& rRenderContext);
|
|
void ImplUpdateDate( const Date& rDate );
|
|
void ImplUpdateSelection( IntDateSet* pOld );
|
|
void ImplMouseSelect( const Date& rDate, sal_uInt16 nHitTest );
|
|
void ImplUpdate( bool bCalcNew = false );
|
|
using Window::ImplScroll;
|
|
void ImplScroll( bool bPrev );
|
|
void ImplShowMenu( const Point& rPos, const Date& rDate );
|
|
void ImplTracking( const Point& rPos, bool bRepeat );
|
|
void ImplEndTracking( bool bCancel );
|
|
DayOfWeek ImplGetWeekStart() const;
|
|
|
|
virtual Size GetOptimalSize() const override;
|
|
public:
|
|
Calendar( vcl::Window* pParent, WinBits nWinStyle );
|
|
virtual ~Calendar() override;
|
|
virtual void dispose() override;
|
|
|
|
virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
|
|
virtual void Tracking( const TrackingEvent& rMEvt ) override;
|
|
virtual void KeyInput( const KeyEvent& rKEvt ) override;
|
|
virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
|
|
virtual void Resize() override;
|
|
virtual void GetFocus() override;
|
|
virtual void LoseFocus() override;
|
|
virtual void RequestHelp( const HelpEvent& rHEvt ) override;
|
|
virtual void Command( const CommandEvent& rCEvt ) override;
|
|
virtual void StateChanged( StateChangedType nStateChange ) override;
|
|
virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
|
|
|
|
void Select();
|
|
|
|
Date GetFirstSelectedDate() const;
|
|
|
|
void SetCurDate( const Date& rNewDate );
|
|
void SetFirstDate( const Date& rNewFirstDate );
|
|
const Date& GetFirstDate() const { return maFirstDate; }
|
|
Date GetLastDate() const { return GetFirstDate() + mnDayCount; }
|
|
Date GetFirstMonth() const;
|
|
Date GetLastMonth() const;
|
|
sal_uInt16 GetMonthCount() const;
|
|
bool GetDate( const Point& rPos, Date& rDate ) const;
|
|
tools::Rectangle GetDateRect( const Date& rDate ) const;
|
|
|
|
void EndSelection();
|
|
|
|
Size CalcWindowSizePixel() const;
|
|
|
|
void SetSelectHdl( const Link<Calendar*,void>& rLink ) { maSelectHdl = rLink; }
|
|
void SetActivateHdl( const Link<Calendar*,void>& rLink ) { maActivateHdl = rLink; }
|
|
};
|
|
|
|
#endif // INCLUDED_VCL_CALENDAR_HXX
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|