1746 lines
54 KiB
C++
1746 lines
54 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 .
|
|
*/
|
|
|
|
#include <vcl/builder.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <vcl/help.hxx>
|
|
#include <vcl/kernarray.hxx>
|
|
#include <vcl/menu.hxx>
|
|
#include <vcl/settings.hxx>
|
|
#include <vcl/event.hxx>
|
|
#include <vcl/toolkit/calendar.hxx>
|
|
#include <vcl/commandevent.hxx>
|
|
#include <vcl/dockwin.hxx>
|
|
#include <unotools/calendarwrapper.hxx>
|
|
#include <unotools/localedatawrapper.hxx>
|
|
#include <com/sun/star/i18n/Weekdays.hpp>
|
|
#include <com/sun/star/i18n/CalendarDisplayIndex.hpp>
|
|
#include <com/sun/star/i18n/CalendarFieldIndex.hpp>
|
|
#include <sal/log.hxx>
|
|
#include <tools/json_writer.hxx>
|
|
|
|
#include <calendar.hxx>
|
|
#include <svdata.hxx>
|
|
#include <strings.hrc>
|
|
#include <memory>
|
|
|
|
#define DAY_OFFX 4
|
|
#define DAY_OFFY 2
|
|
#define MONTH_BORDERX 4
|
|
#define MONTH_OFFY 3
|
|
#define WEEKDAY_OFFY 3
|
|
#define TITLE_OFFY 3
|
|
#define TITLE_BORDERY 2
|
|
#define SPIN_OFFX 4
|
|
#define SPIN_OFFY TITLE_BORDERY
|
|
|
|
#define CALENDAR_HITTEST_DAY (sal_uInt16(0x0001))
|
|
#define CALENDAR_HITTEST_MONTHTITLE (sal_uInt16(0x0004))
|
|
#define CALENDAR_HITTEST_PREV (sal_uInt16(0x0008))
|
|
#define CALENDAR_HITTEST_NEXT (sal_uInt16(0x0010))
|
|
|
|
#define MENU_YEAR_COUNT 3
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
static void ImplCalendarSelectDate( IntDateSet* pTable, const Date& rDate, bool bSelect )
|
|
{
|
|
if ( bSelect )
|
|
pTable->insert( rDate.GetDate() );
|
|
else
|
|
pTable->erase( rDate.GetDate() );
|
|
}
|
|
|
|
|
|
|
|
void Calendar::ImplInit( WinBits nWinStyle )
|
|
{
|
|
mpSelectTable.reset(new IntDateSet);
|
|
mnDayCount = 0;
|
|
mnWinStyle = nWinStyle;
|
|
mnFirstYear = 0;
|
|
mnLastYear = 0;
|
|
mbCalc = true;
|
|
mbFormat = true;
|
|
mbDrag = false;
|
|
mbMenuDown = false;
|
|
mbSpinDown = false;
|
|
mbPrevIn = false;
|
|
mbNextIn = false;
|
|
|
|
OUString aGregorian( u"gregorian"_ustr);
|
|
maCalendarWrapper.loadCalendar( aGregorian,
|
|
Application::GetAppLocaleDataWrapper().getLanguageTag().getLocale());
|
|
if (maCalendarWrapper.getUniqueID() != aGregorian)
|
|
{
|
|
SAL_WARN( "vcl.control", "Calendar::ImplInit: No ``gregorian'' calendar available for locale ``"
|
|
<< Application::GetAppLocaleDataWrapper().getLanguageTag().getBcp47()
|
|
<< "'' and other calendars aren't supported. Using en-US fallback." );
|
|
|
|
/* If we ever wanted to support other calendars than Gregorian a lot of
|
|
* rewrite would be necessary to internally replace use of class Date
|
|
* with proper class CalendarWrapper methods, get rid of fixed 12
|
|
* months, fixed 7 days, ... */
|
|
maCalendarWrapper.loadCalendar( aGregorian, lang::Locale( u"en"_ustr, u"US"_ustr, u""_ustr));
|
|
}
|
|
|
|
SetFirstDate( maCurDate );
|
|
ImplCalendarSelectDate( mpSelectTable.get(), maCurDate, true );
|
|
|
|
// generate other strings
|
|
maDayText = VclResId(STR_SVT_CALENDAR_DAY);
|
|
maWeekText = VclResId(STR_SVT_CALENDAR_WEEK);
|
|
|
|
// create text for each day
|
|
for (sal_Int32 i = 0; i < 31; ++i)
|
|
maDayTexts[i] = OUString::number(i+1);
|
|
|
|
ImplInitSettings();
|
|
}
|
|
|
|
void Calendar::ApplySettings(vcl::RenderContext& rRenderContext)
|
|
{
|
|
const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
|
|
maSelColor = rStyleSettings.GetHighlightTextColor();
|
|
SetPointFont(rRenderContext, rStyleSettings.GetToolFont());
|
|
rRenderContext.SetTextColor(rStyleSettings.GetFieldTextColor());
|
|
rRenderContext.SetBackground(Wallpaper(rStyleSettings.GetFieldColor()));
|
|
}
|
|
|
|
void Calendar::ImplInitSettings()
|
|
{
|
|
const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
|
|
maSelColor = rStyleSettings.GetHighlightTextColor();
|
|
SetPointFont(*GetOutDev(), rStyleSettings.GetToolFont());
|
|
SetTextColor(rStyleSettings.GetFieldTextColor());
|
|
SetBackground(Wallpaper(rStyleSettings.GetFieldColor()));
|
|
}
|
|
|
|
Calendar::Calendar(vcl::Window* pParent, WinBits nWinStyle)
|
|
: Control(pParent, nWinStyle & (WB_TABSTOP | WB_GROUP | WB_BORDER | WB_3DLOOK))
|
|
, maCalendarWrapper(Application::GetAppLocaleDataWrapper().getComponentContext())
|
|
, maOldFormatFirstDate(0, 0, 1900)
|
|
, maOldFormatLastDate(0, 0, 1900)
|
|
, maFirstDate(0, 0, 1900)
|
|
, maOldFirstDate(0, 0, 1900)
|
|
, maCurDate(Date::SYSTEM)
|
|
, maOldCurDate(0, 0, 1900)
|
|
{
|
|
ImplInit( nWinStyle );
|
|
}
|
|
|
|
Calendar::~Calendar()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void Calendar::dispose()
|
|
{
|
|
mpSelectTable.reset();
|
|
mpOldSelectTable.reset();
|
|
Control::dispose();
|
|
}
|
|
|
|
DayOfWeek Calendar::ImplGetWeekStart() const
|
|
{
|
|
// Map i18n::Weekdays to Date DayOfWeek
|
|
DayOfWeek eDay;
|
|
sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek();
|
|
switch (nDay)
|
|
{
|
|
case i18n::Weekdays::SUNDAY :
|
|
eDay = SUNDAY;
|
|
break;
|
|
case i18n::Weekdays::MONDAY :
|
|
eDay = MONDAY;
|
|
break;
|
|
case i18n::Weekdays::TUESDAY :
|
|
eDay = TUESDAY;
|
|
break;
|
|
case i18n::Weekdays::WEDNESDAY :
|
|
eDay = WEDNESDAY;
|
|
break;
|
|
case i18n::Weekdays::THURSDAY :
|
|
eDay = THURSDAY;
|
|
break;
|
|
case i18n::Weekdays::FRIDAY :
|
|
eDay = FRIDAY;
|
|
break;
|
|
case i18n::Weekdays::SATURDAY :
|
|
eDay = SATURDAY;
|
|
break;
|
|
default:
|
|
SAL_WARN( "vcl.control", "Calendar::ImplGetWeekStart: broken i18n Gregorian calendar (getFirstDayOfWeek())");
|
|
eDay = SUNDAY;
|
|
}
|
|
return eDay;
|
|
}
|
|
|
|
void Calendar::ImplFormat()
|
|
{
|
|
if ( !mbFormat )
|
|
return;
|
|
|
|
if ( mbCalc )
|
|
{
|
|
Size aOutSize = GetOutputSizePixel();
|
|
|
|
if ( (aOutSize.Width() <= 1) || (aOutSize.Height() <= 1) )
|
|
return;
|
|
|
|
tools::Long n99TextWidth = GetTextWidth( u"99"_ustr );
|
|
tools::Long nTextHeight = GetTextHeight();
|
|
|
|
// calculate width and x-position
|
|
mnDayWidth = n99TextWidth+DAY_OFFX;
|
|
mnMonthWidth = mnDayWidth*7;
|
|
mnMonthWidth += MONTH_BORDERX*2;
|
|
mnMonthPerLine = aOutSize.Width() / mnMonthWidth;
|
|
if ( !mnMonthPerLine )
|
|
mnMonthPerLine = 1;
|
|
tools::Long nOver = (aOutSize.Width()-(mnMonthPerLine*mnMonthWidth)) / mnMonthPerLine;
|
|
mnMonthWidth += nOver;
|
|
mnDaysOffX = MONTH_BORDERX;
|
|
mnDaysOffX += nOver/2;
|
|
|
|
// calculate height and y-position
|
|
mnDayHeight = nTextHeight + DAY_OFFY;
|
|
mnWeekDayOffY = nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2);
|
|
mnDaysOffY = mnWeekDayOffY + nTextHeight + WEEKDAY_OFFY;
|
|
mnMonthHeight = (mnDayHeight*6) + mnDaysOffY;
|
|
mnMonthHeight += MONTH_OFFY;
|
|
mnLines = aOutSize.Height() / mnMonthHeight;
|
|
if ( !mnLines )
|
|
mnLines = 1;
|
|
mnMonthHeight += (aOutSize.Height()-(mnLines*mnMonthHeight)) / mnLines;
|
|
|
|
// calculate spinfields
|
|
tools::Long nSpinSize = nTextHeight+TITLE_BORDERY-SPIN_OFFY;
|
|
maPrevRect.SetLeft( SPIN_OFFX );
|
|
maPrevRect.SetTop( SPIN_OFFY );
|
|
maPrevRect.SetRight( maPrevRect.Left()+nSpinSize );
|
|
maPrevRect.SetBottom( maPrevRect.Top()+nSpinSize );
|
|
maNextRect.SetLeft( aOutSize.Width()-SPIN_OFFX-nSpinSize-1 );
|
|
maNextRect.SetTop( SPIN_OFFY );
|
|
maNextRect.SetRight( maNextRect.Left()+nSpinSize );
|
|
maNextRect.SetBottom( maNextRect.Top()+nSpinSize );
|
|
|
|
// Calculate DayOfWeekText (gets displayed in a narrow font)
|
|
maDayOfWeekText.clear();
|
|
tools::Long nStartOffX = 0;
|
|
sal_Int16 nDay = maCalendarWrapper.getFirstDayOfWeek();
|
|
for ( sal_Int16 nDayOfWeek = 0; nDayOfWeek < 7; nDayOfWeek++ )
|
|
{
|
|
// Use narrow name.
|
|
OUString aDayOfWeek( maCalendarWrapper.getDisplayName(
|
|
i18n::CalendarDisplayIndex::DAY, nDay, 2));
|
|
tools::Long nOffX = (mnDayWidth-GetTextWidth( aDayOfWeek ))/2;
|
|
if ( !nDayOfWeek )
|
|
nStartOffX = nOffX;
|
|
else
|
|
nOffX -= nStartOffX;
|
|
nOffX += nDayOfWeek * mnDayWidth;
|
|
mnDayOfWeekAry[nDayOfWeek] = nOffX;
|
|
maDayOfWeekText += aDayOfWeek;
|
|
nDay++;
|
|
nDay %= 7;
|
|
}
|
|
|
|
// header position for the last day of week
|
|
mnDayOfWeekAry[7] = mnMonthWidth;
|
|
|
|
mbCalc = false;
|
|
}
|
|
|
|
// calculate number of days
|
|
|
|
DayOfWeek eStartDay = ImplGetWeekStart();
|
|
|
|
sal_uInt16 nWeekDay;
|
|
Date aTempDate = GetFirstMonth();
|
|
maFirstDate = aTempDate;
|
|
nWeekDay = static_cast<sal_uInt16>(aTempDate.GetDayOfWeek());
|
|
nWeekDay = (nWeekDay+(7-static_cast<sal_uInt16>(eStartDay))) % 7;
|
|
maFirstDate.AddDays( -nWeekDay );
|
|
mnDayCount = nWeekDay;
|
|
sal_uInt16 nDaysInMonth;
|
|
sal_uInt16 nMonthCount = static_cast<sal_uInt16>(mnMonthPerLine*mnLines);
|
|
for ( sal_uInt16 i = 0; i < nMonthCount; i++ )
|
|
{
|
|
nDaysInMonth = aTempDate.GetDaysInMonth();
|
|
mnDayCount += nDaysInMonth;
|
|
aTempDate.AddDays( nDaysInMonth );
|
|
}
|
|
Date aTempDate2 = aTempDate;
|
|
--aTempDate2;
|
|
nDaysInMonth = aTempDate2.GetDaysInMonth();
|
|
aTempDate2.AddDays( -(nDaysInMonth-1) );
|
|
nWeekDay = static_cast<sal_uInt16>(aTempDate2.GetDayOfWeek());
|
|
nWeekDay = (nWeekDay+(7-static_cast<sal_uInt16>(eStartDay))) % 7;
|
|
mnDayCount += 42-nDaysInMonth-nWeekDay;
|
|
|
|
// determine colours
|
|
maOtherColor = COL_LIGHTGRAY;
|
|
if ( maOtherColor.IsRGBEqual( GetBackground().GetColor() ) )
|
|
maOtherColor = COL_GRAY;
|
|
|
|
Date aLastDate = GetLastDate();
|
|
if ( (maOldFormatLastDate != aLastDate) ||
|
|
(maOldFormatFirstDate != maFirstDate) )
|
|
{
|
|
maOldFormatFirstDate = maFirstDate;
|
|
maOldFormatLastDate = aLastDate;
|
|
}
|
|
|
|
// get DateInfo
|
|
sal_Int16 nNewFirstYear = maFirstDate.GetYear();
|
|
sal_Int16 nNewLastYear = GetLastDate().GetYear();
|
|
if ( mnFirstYear )
|
|
{
|
|
if ( nNewFirstYear < mnFirstYear )
|
|
{
|
|
mnFirstYear = nNewFirstYear;
|
|
}
|
|
if ( nNewLastYear > mnLastYear )
|
|
{
|
|
mnLastYear = nNewLastYear;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
mnFirstYear = nNewFirstYear;
|
|
mnLastYear = nNewLastYear;
|
|
}
|
|
|
|
mbFormat = false;
|
|
}
|
|
|
|
sal_uInt16 Calendar::ImplDoHitTest( const Point& rPos, Date& rDate ) const
|
|
{
|
|
if ( mbFormat )
|
|
return 0;
|
|
|
|
if ( maPrevRect.Contains( rPos ) )
|
|
return CALENDAR_HITTEST_PREV;
|
|
else if ( maNextRect.Contains( rPos ) )
|
|
return CALENDAR_HITTEST_NEXT;
|
|
|
|
tools::Long nY;
|
|
tools::Long nOffX;
|
|
sal_Int32 nDay;
|
|
DayOfWeek eStartDay = ImplGetWeekStart();
|
|
|
|
rDate = GetFirstMonth();
|
|
nY = 0;
|
|
for ( tools::Long i = 0; i < mnLines; i++ )
|
|
{
|
|
if ( rPos.Y() < nY )
|
|
return 0;
|
|
|
|
tools::Long nX = 0;
|
|
tools::Long nYMonth = nY+mnMonthHeight;
|
|
for ( tools::Long j = 0; j < mnMonthPerLine; j++ )
|
|
{
|
|
if ( (rPos.X() < nX) && (rPos.Y() < nYMonth) )
|
|
return 0;
|
|
|
|
sal_uInt16 nDaysInMonth = rDate.GetDaysInMonth();
|
|
|
|
// matching month was found
|
|
if ( (rPos.X() > nX) && (rPos.Y() < nYMonth) &&
|
|
(rPos.X() < nX+mnMonthWidth) )
|
|
{
|
|
if ( rPos.Y() < (nY+(TITLE_BORDERY*2)+mnDayHeight))
|
|
return CALENDAR_HITTEST_MONTHTITLE;
|
|
else
|
|
{
|
|
tools::Long nDayX = nX+mnDaysOffX;
|
|
tools::Long nDayY = nY+mnDaysOffY;
|
|
if ( rPos.Y() < nDayY )
|
|
return 0;
|
|
sal_Int32 nDayIndex = static_cast<sal_Int32>(rDate.GetDayOfWeek());
|
|
nDayIndex = (nDayIndex+(7-static_cast<sal_Int32>(eStartDay))) % 7;
|
|
if ( (i == 0) && (j == 0) )
|
|
{
|
|
Date aTempDate = rDate;
|
|
aTempDate.AddDays( -nDayIndex );
|
|
for ( nDay = 0; nDay < nDayIndex; nDay++ )
|
|
{
|
|
nOffX = nDayX + (nDay*mnDayWidth);
|
|
if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
|
|
(rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
|
|
{
|
|
rDate = aTempDate;
|
|
rDate.AddDays( nDay );
|
|
return CALENDAR_HITTEST_DAY;
|
|
}
|
|
}
|
|
}
|
|
for ( nDay = 1; nDay <= nDaysInMonth; nDay++ )
|
|
{
|
|
if ( rPos.Y() < nDayY )
|
|
{
|
|
rDate.AddDays( nDayIndex );
|
|
return 0;
|
|
}
|
|
nOffX = nDayX + (nDayIndex*mnDayWidth);
|
|
if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
|
|
(rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
|
|
{
|
|
rDate.AddDays( nDay-1 );
|
|
return CALENDAR_HITTEST_DAY;
|
|
}
|
|
if ( nDayIndex == 6 )
|
|
{
|
|
nDayIndex = 0;
|
|
nDayY += mnDayHeight;
|
|
}
|
|
else
|
|
nDayIndex++;
|
|
}
|
|
if ( (i == mnLines-1) && (j == mnMonthPerLine-1) )
|
|
{
|
|
sal_uInt16 nWeekDay = static_cast<sal_uInt16>(rDate.GetDayOfWeek());
|
|
nWeekDay = (nWeekDay+(7-static_cast<sal_uInt16>(eStartDay))) % 7;
|
|
sal_Int32 nDayCount = 42-nDaysInMonth-nWeekDay;
|
|
Date aTempDate = rDate;
|
|
aTempDate.AddDays( nDaysInMonth );
|
|
for ( nDay = 1; nDay <= nDayCount; nDay++ )
|
|
{
|
|
if ( rPos.Y() < nDayY )
|
|
{
|
|
rDate.AddDays( nDayIndex );
|
|
return 0;
|
|
}
|
|
nOffX = nDayX + (nDayIndex*mnDayWidth);
|
|
if ( (rPos.Y() >= nDayY) && (rPos.Y() < nDayY+mnDayHeight) &&
|
|
(rPos.X() >= nOffX) && (rPos.X() < nOffX+mnDayWidth) )
|
|
{
|
|
rDate = aTempDate;
|
|
rDate.AddDays( nDay-1 );
|
|
return CALENDAR_HITTEST_DAY;
|
|
}
|
|
if ( nDayIndex == 6 )
|
|
{
|
|
nDayIndex = 0;
|
|
nDayY += mnDayHeight;
|
|
}
|
|
else
|
|
nDayIndex++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
rDate.AddDays( nDaysInMonth );
|
|
nX += mnMonthWidth;
|
|
}
|
|
|
|
nY += mnMonthHeight;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
|
|
void ImplDrawSpinArrow(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect, bool bPrev)
|
|
{
|
|
tools::Long i;
|
|
tools::Long n;
|
|
tools::Long nLines;
|
|
tools::Long nHeight = rRect.GetHeight();
|
|
tools::Long nWidth = rRect.GetWidth();
|
|
if (nWidth < nHeight)
|
|
n = nWidth;
|
|
else
|
|
n = nHeight;
|
|
if (!(n & 0x01))
|
|
n--;
|
|
nLines = n/2;
|
|
|
|
tools::Rectangle aRect(Point( rRect.Left() + (nWidth / 2) - (nLines / 2),
|
|
rRect.Top() + (nHeight / 2) ),
|
|
Size(1, 1));
|
|
if (!bPrev)
|
|
{
|
|
aRect.AdjustLeft(nLines );
|
|
aRect.AdjustRight(nLines );
|
|
}
|
|
|
|
rRenderContext.DrawRect(aRect);
|
|
for (i = 0; i < nLines; i++)
|
|
{
|
|
if (bPrev)
|
|
{
|
|
aRect.AdjustLeft( 1 );
|
|
aRect.AdjustRight( 1 );
|
|
}
|
|
else
|
|
{
|
|
aRect.AdjustLeft( -1 );
|
|
aRect.AdjustRight( -1 );
|
|
}
|
|
aRect.AdjustTop( -1 );
|
|
aRect.AdjustBottom( 1 );
|
|
rRenderContext.DrawRect(aRect);
|
|
}
|
|
}
|
|
|
|
} //end anonymous namespace
|
|
|
|
void Calendar::ImplDrawSpin(vcl::RenderContext& rRenderContext )
|
|
{
|
|
rRenderContext.SetLineColor();
|
|
rRenderContext.SetFillColor(rRenderContext.GetSettings().GetStyleSettings().GetButtonTextColor());
|
|
tools::Rectangle aOutRect = maPrevRect;
|
|
aOutRect.AdjustLeft(3 );
|
|
aOutRect.AdjustTop(3 );
|
|
aOutRect.AdjustRight( -3 );
|
|
aOutRect.AdjustBottom( -3 );
|
|
ImplDrawSpinArrow(rRenderContext, aOutRect, true);
|
|
aOutRect = maNextRect;
|
|
aOutRect.AdjustLeft(3 );
|
|
aOutRect.AdjustTop(3 );
|
|
aOutRect.AdjustRight( -3 );
|
|
aOutRect.AdjustBottom( -3 );
|
|
ImplDrawSpinArrow(rRenderContext, aOutRect, false);
|
|
}
|
|
|
|
void Calendar::ImplDrawDate(vcl::RenderContext& rRenderContext,
|
|
tools::Long nX, tools::Long nY,
|
|
sal_uInt16 nDay, sal_uInt16 nMonth, sal_Int16 nYear,
|
|
bool bOther, sal_Int32 nToday )
|
|
{
|
|
Color const * pTextColor = nullptr;
|
|
const OUString& rDay = maDayTexts[(nDay - 1) % std::size(maDayTexts)];
|
|
tools::Rectangle aDateRect(nX, nY, nX + mnDayWidth - 1, nY + mnDayHeight - 1);
|
|
|
|
bool bSel = false;
|
|
bool bFocus = false;
|
|
// actual day
|
|
if ((nDay == maCurDate.GetDay()) &&
|
|
(nMonth == maCurDate.GetMonth()) &&
|
|
(nYear == maCurDate.GetYear()))
|
|
{
|
|
bFocus = true;
|
|
}
|
|
if (mpSelectTable)
|
|
{
|
|
if (mpSelectTable->find(Date(nDay, nMonth, nYear).GetDate()) != mpSelectTable->end())
|
|
bSel = true;
|
|
}
|
|
|
|
// get textcolour
|
|
if (bSel)
|
|
pTextColor = &maSelColor;
|
|
else if (bOther)
|
|
pTextColor = &maOtherColor;
|
|
|
|
if (bFocus)
|
|
HideFocus();
|
|
|
|
// display background
|
|
const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
|
|
if (bSel)
|
|
{
|
|
rRenderContext.SetLineColor();
|
|
rRenderContext.SetFillColor(rStyleSettings.GetHighlightColor());
|
|
rRenderContext.DrawRect(aDateRect);
|
|
}
|
|
|
|
// display text
|
|
tools::Long nTextX = nX + (mnDayWidth - GetTextWidth(rDay)) - (DAY_OFFX / 2);
|
|
tools::Long nTextY = nY + (mnDayHeight - GetTextHeight()) / 2;
|
|
if (pTextColor)
|
|
{
|
|
Color aOldColor = rRenderContext.GetTextColor();
|
|
rRenderContext.SetTextColor(*pTextColor);
|
|
rRenderContext.DrawText(Point(nTextX, nTextY), rDay);
|
|
rRenderContext.SetTextColor(aOldColor);
|
|
}
|
|
else
|
|
rRenderContext.DrawText(Point(nTextX, nTextY), rDay);
|
|
|
|
// today
|
|
Date aTodayDate(maCurDate);
|
|
if (nToday)
|
|
aTodayDate.SetDate(nToday);
|
|
else
|
|
aTodayDate = Date(Date::SYSTEM);
|
|
if ((nDay == aTodayDate.GetDay()) &&
|
|
(nMonth == aTodayDate.GetMonth()) &&
|
|
(nYear == aTodayDate.GetYear()))
|
|
{
|
|
rRenderContext.SetLineColor(rStyleSettings.GetWindowTextColor());
|
|
rRenderContext.SetFillColor();
|
|
rRenderContext.DrawRect(aDateRect);
|
|
}
|
|
|
|
// if needed do FocusRect
|
|
if (bFocus && HasFocus())
|
|
ShowFocus(aDateRect);
|
|
}
|
|
|
|
void Calendar::ImplDraw(vcl::RenderContext& rRenderContext)
|
|
{
|
|
ImplFormat();
|
|
|
|
const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
|
|
Size aOutSize(GetOutputSizePixel());
|
|
tools::Long i;
|
|
tools::Long j;
|
|
tools::Long nY;
|
|
tools::Long nDeltaX;
|
|
tools::Long nDeltaY;
|
|
tools::Long nDayX;
|
|
tools::Long nDayY;
|
|
sal_Int32 nToday = Date(Date::SYSTEM).GetDate();
|
|
sal_uInt16 nDay;
|
|
sal_uInt16 nMonth;
|
|
sal_Int16 nYear;
|
|
Date aDate = GetFirstMonth();
|
|
DayOfWeek eStartDay = ImplGetWeekStart();
|
|
|
|
HideFocus();
|
|
|
|
nY = 0;
|
|
for (i = 0; i < mnLines; i++)
|
|
{
|
|
// display title bar
|
|
rRenderContext.SetLineColor();
|
|
rRenderContext.SetFillColor(rStyleSettings.GetFaceColor());
|
|
tools::Rectangle aTitleRect(0, nY, aOutSize.Width() - 1, nY + mnDayHeight - DAY_OFFY + TITLE_BORDERY * 2);
|
|
rRenderContext.DrawRect(aTitleRect);
|
|
Point aTopLeft1(aTitleRect.Left(), aTitleRect.Top());
|
|
Point aTopLeft2(aTitleRect.Left(), aTitleRect.Top() + 1);
|
|
Point aBottomRight1(aTitleRect.Right(), aTitleRect.Bottom());
|
|
Point aBottomRight2(aTitleRect.Right(), aTitleRect.Bottom() - 1);
|
|
rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
|
|
rRenderContext.DrawLine(aTopLeft1, Point(aBottomRight1.X(), aTopLeft1.Y()));
|
|
rRenderContext.SetLineColor(rStyleSettings.GetLightColor() );
|
|
rRenderContext.DrawLine(aTopLeft2, Point(aBottomRight2.X(), aTopLeft2.Y()));
|
|
rRenderContext.DrawLine(aTopLeft2, Point(aTopLeft2.X(), aBottomRight2.Y()));
|
|
rRenderContext.SetLineColor(rStyleSettings.GetShadowColor() );
|
|
rRenderContext.DrawLine(Point(aTopLeft2.X(), aBottomRight2.Y()), aBottomRight2);
|
|
rRenderContext.DrawLine(Point(aBottomRight2.X(), aTopLeft2.Y()), aBottomRight2);
|
|
rRenderContext.SetLineColor(rStyleSettings.GetDarkShadowColor());
|
|
rRenderContext.DrawLine(Point(aTopLeft1.X(), aBottomRight1.Y()), aBottomRight1);
|
|
Point aSepPos1(0, aTitleRect.Top() + TITLE_BORDERY);
|
|
Point aSepPos2(0, aTitleRect.Bottom() - TITLE_BORDERY);
|
|
for (j = 0; j < mnMonthPerLine-1; j++)
|
|
{
|
|
aSepPos1.AdjustX(mnMonthWidth-1 );
|
|
aSepPos2.setX( aSepPos1.X() );
|
|
rRenderContext.SetLineColor(rStyleSettings.GetShadowColor());
|
|
rRenderContext.DrawLine(aSepPos1, aSepPos2);
|
|
aSepPos1.AdjustX( 1 );
|
|
aSepPos2.setX( aSepPos1.X() );
|
|
rRenderContext.SetLineColor(rStyleSettings.GetLightColor());
|
|
rRenderContext.DrawLine(aSepPos1, aSepPos2);
|
|
}
|
|
|
|
tools::Long nX = 0;
|
|
for (j = 0; j < mnMonthPerLine; j++)
|
|
{
|
|
nMonth = aDate.GetMonth();
|
|
nYear = aDate.GetYear();
|
|
|
|
// display month in title bar
|
|
nDeltaX = nX;
|
|
nDeltaY = nY + TITLE_BORDERY;
|
|
OUString aMonthText = maCalendarWrapper.getDisplayName(i18n::CalendarDisplayIndex::MONTH, nMonth - 1, 1)
|
|
+ " "
|
|
+ OUString::number(nYear);
|
|
tools::Long nMonthTextWidth = rRenderContext.GetTextWidth(aMonthText);
|
|
tools::Long nMonthOffX1 = 0;
|
|
tools::Long nMonthOffX2 = 0;
|
|
if (i == 0)
|
|
{
|
|
if (j == 0)
|
|
nMonthOffX1 = maPrevRect.Right() + 1;
|
|
if (j == mnMonthPerLine - 1)
|
|
nMonthOffX2 = aOutSize.Width() - maNextRect.Left() + 1;
|
|
}
|
|
tools::Long nMaxMonthWidth = mnMonthWidth - nMonthOffX1 - nMonthOffX2 - 4;
|
|
if (nMonthTextWidth > nMaxMonthWidth)
|
|
{
|
|
// Abbreviated month name.
|
|
aMonthText = maCalendarWrapper.getDisplayName(i18n::CalendarDisplayIndex::MONTH, nMonth - 1, 0)
|
|
+ " "
|
|
+ OUString::number(nYear);
|
|
nMonthTextWidth = rRenderContext.GetTextWidth(aMonthText);
|
|
}
|
|
tools::Long nTempOff = (mnMonthWidth - nMonthTextWidth + 1) / 2;
|
|
if (nTempOff < nMonthOffX1)
|
|
nDeltaX += nMonthOffX1 + 1;
|
|
else
|
|
{
|
|
if (nTempOff + nMonthTextWidth > mnMonthWidth - nMonthOffX2)
|
|
nDeltaX += mnMonthWidth - nMonthOffX2 - nMonthTextWidth;
|
|
else
|
|
nDeltaX += nTempOff;
|
|
}
|
|
rRenderContext.SetTextColor(rStyleSettings.GetButtonTextColor());
|
|
rRenderContext.DrawText(Point(nDeltaX, nDeltaY), aMonthText);
|
|
rRenderContext.SetTextColor(rStyleSettings.GetWindowTextColor());
|
|
|
|
// display week bar
|
|
nDayX = nX + mnDaysOffX;
|
|
nDayY = nY + mnWeekDayOffY;
|
|
nDeltaY = nDayY + mnDayHeight;
|
|
rRenderContext.SetLineColor(rStyleSettings.GetWindowTextColor());
|
|
Point aStartPos(nDayX, nDeltaY);
|
|
rRenderContext.DrawLine(aStartPos, Point(nDayX + (7 * mnDayWidth), nDeltaY));
|
|
KernArray aTmp;
|
|
for (int k=0; k<7; ++k)
|
|
aTmp.push_back(mnDayOfWeekAry[k+1]);
|
|
rRenderContext.DrawTextArray(Point(nDayX + mnDayOfWeekAry[0], nDayY), maDayOfWeekText, aTmp, {}, 0, aTmp.size());
|
|
|
|
// display days
|
|
sal_uInt16 nDaysInMonth = aDate.GetDaysInMonth();
|
|
nDayX = nX + mnDaysOffX;
|
|
nDayY = nY + mnDaysOffY;
|
|
sal_uInt16 nDayIndex = static_cast<sal_uInt16>(aDate.GetDayOfWeek());
|
|
nDayIndex = (nDayIndex + (7 - static_cast<sal_uInt16>(eStartDay))) % 7;
|
|
if (i == 0 && j == 0)
|
|
{
|
|
Date aTempDate = aDate;
|
|
aTempDate.AddDays( -nDayIndex );
|
|
for (nDay = 0; nDay < nDayIndex; ++nDay)
|
|
{
|
|
nDeltaX = nDayX + (nDay * mnDayWidth);
|
|
ImplDrawDate(rRenderContext, nDeltaX, nDayY, nDay + aTempDate.GetDay(),
|
|
aTempDate.GetMonth(), aTempDate.GetYear(),
|
|
true, nToday);
|
|
}
|
|
}
|
|
for (nDay = 1; nDay <= nDaysInMonth; nDay++)
|
|
{
|
|
nDeltaX = nDayX + (nDayIndex * mnDayWidth);
|
|
ImplDrawDate(rRenderContext, nDeltaX, nDayY, nDay, nMonth, nYear,
|
|
false, nToday);
|
|
if (nDayIndex == 6)
|
|
{
|
|
nDayIndex = 0;
|
|
nDayY += mnDayHeight;
|
|
}
|
|
else
|
|
nDayIndex++;
|
|
}
|
|
if ((i == mnLines - 1) && (j == mnMonthPerLine - 1))
|
|
{
|
|
sal_uInt16 nWeekDay = static_cast<sal_uInt16>(aDate.GetDayOfWeek());
|
|
nWeekDay = (nWeekDay + (7 - static_cast<sal_uInt16>(eStartDay))) % 7;
|
|
sal_uInt16 nDayCount = 42 - nDaysInMonth - nWeekDay;
|
|
Date aTempDate = aDate;
|
|
aTempDate.AddDays( nDaysInMonth );
|
|
for (nDay = 1; nDay <= nDayCount; ++nDay)
|
|
{
|
|
nDeltaX = nDayX + (nDayIndex * mnDayWidth);
|
|
ImplDrawDate(rRenderContext, nDeltaX, nDayY, nDay,
|
|
aTempDate.GetMonth(), aTempDate.GetYear(),
|
|
true, nToday);
|
|
if (nDayIndex == 6)
|
|
{
|
|
nDayIndex = 0;
|
|
nDayY += mnDayHeight;
|
|
}
|
|
else
|
|
nDayIndex++;
|
|
}
|
|
}
|
|
|
|
aDate.AddDays( nDaysInMonth );
|
|
nX += mnMonthWidth;
|
|
}
|
|
|
|
nY += mnMonthHeight;
|
|
}
|
|
|
|
// draw spin buttons
|
|
ImplDrawSpin(rRenderContext);
|
|
}
|
|
|
|
void Calendar::ImplUpdateDate( const Date& rDate )
|
|
{
|
|
if (IsReallyVisible() && IsUpdateMode())
|
|
{
|
|
tools::Rectangle aDateRect(GetDateRect(rDate));
|
|
if (!aDateRect.IsEmpty())
|
|
{
|
|
Invalidate(aDateRect);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Calendar::ImplUpdateSelection( IntDateSet* pOld )
|
|
{
|
|
IntDateSet* pNew = mpSelectTable.get();
|
|
|
|
for (auto const& nKey : *pOld)
|
|
{
|
|
if ( pNew->find(nKey) == pNew->end() )
|
|
{
|
|
Date aTempDate(nKey);
|
|
ImplUpdateDate(aTempDate);
|
|
}
|
|
}
|
|
|
|
for (auto const& nKey : *pNew)
|
|
{
|
|
if ( pOld->find(nKey) == pOld->end() )
|
|
{
|
|
Date aTempDate(nKey);
|
|
ImplUpdateDate(aTempDate);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Calendar::ImplMouseSelect( const Date& rDate, sal_uInt16 nHitTest )
|
|
{
|
|
IntDateSet aOldSel( *mpSelectTable );
|
|
Date aOldDate = maCurDate;
|
|
Date aTempDate = rDate;
|
|
|
|
if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
|
|
--aTempDate;
|
|
|
|
if ( !(nHitTest & CALENDAR_HITTEST_DAY) )
|
|
aTempDate = maOldCurDate;
|
|
if ( aTempDate != maCurDate )
|
|
{
|
|
maCurDate = aTempDate;
|
|
ImplCalendarSelectDate( mpSelectTable.get(), aOldDate, false );
|
|
ImplCalendarSelectDate( mpSelectTable.get(), maCurDate, true );
|
|
}
|
|
|
|
bool bNewSel = aOldSel != *mpSelectTable;
|
|
if ( (maCurDate != aOldDate) || bNewSel )
|
|
{
|
|
HideFocus();
|
|
if ( bNewSel )
|
|
ImplUpdateSelection( &aOldSel );
|
|
if ( !bNewSel || aOldSel.find( aOldDate.GetDate() ) == aOldSel.end() )
|
|
ImplUpdateDate( aOldDate );
|
|
// assure focus rectangle is displayed again
|
|
if ( HasFocus() || !bNewSel
|
|
|| mpSelectTable->find( maCurDate.GetDate() ) == mpSelectTable->end() )
|
|
ImplUpdateDate( maCurDate );
|
|
}
|
|
}
|
|
|
|
void Calendar::ImplUpdate( bool bCalcNew )
|
|
{
|
|
if (IsReallyVisible() && IsUpdateMode())
|
|
{
|
|
if (bCalcNew && !mbCalc)
|
|
{
|
|
Invalidate();
|
|
}
|
|
else if (!mbFormat && !mbCalc)
|
|
{
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
if (bCalcNew)
|
|
mbCalc = true;
|
|
mbFormat = true;
|
|
}
|
|
|
|
void Calendar::ImplScrollCalendar( bool bPrev )
|
|
{
|
|
Date aNewFirstMonth = GetFirstMonth();
|
|
if ( bPrev )
|
|
{
|
|
--aNewFirstMonth;
|
|
aNewFirstMonth.AddDays( -(aNewFirstMonth.GetDaysInMonth()-1));
|
|
}
|
|
else
|
|
aNewFirstMonth.AddDays( aNewFirstMonth.GetDaysInMonth());
|
|
SetFirstDate( aNewFirstMonth );
|
|
}
|
|
|
|
void Calendar::ImplShowMenu( const Point& rPos, const Date& rDate )
|
|
{
|
|
EndSelection();
|
|
|
|
Date aOldFirstDate = GetFirstMonth();
|
|
ScopedVclPtrInstance<PopupMenu> aPopupMenu;
|
|
sal_uInt16 nMonthOff;
|
|
sal_uInt16 nCurItemId;
|
|
sal_uInt16 nYear = rDate.GetYear()-1;
|
|
sal_uInt16 i;
|
|
sal_uInt16 j;
|
|
sal_uInt16 nYearIdCount = 1000;
|
|
|
|
nMonthOff = (rDate.GetYear()-aOldFirstDate.GetYear())*12;
|
|
if ( aOldFirstDate.GetMonth() < rDate.GetMonth() )
|
|
nMonthOff += rDate.GetMonth()-aOldFirstDate.GetMonth();
|
|
else
|
|
nMonthOff -= aOldFirstDate.GetMonth()-rDate.GetMonth();
|
|
|
|
// construct menu (include years with different months)
|
|
for ( i = 0; i < MENU_YEAR_COUNT; i++ )
|
|
{
|
|
VclPtrInstance<PopupMenu> pYearPopupMenu;
|
|
for ( j = 1; j <= 12; j++ )
|
|
pYearPopupMenu->InsertItem( nYearIdCount+j,
|
|
maCalendarWrapper.getDisplayName(
|
|
i18n::CalendarDisplayIndex::MONTH, j-1, 1));
|
|
aPopupMenu->InsertItem( 10+i, OUString::number( nYear+i ) );
|
|
aPopupMenu->SetPopupMenu( 10+i, pYearPopupMenu );
|
|
nYearIdCount += 1000;
|
|
}
|
|
|
|
mbMenuDown = true;
|
|
nCurItemId = aPopupMenu->Execute( this, rPos );
|
|
mbMenuDown = false;
|
|
|
|
if ( !nCurItemId )
|
|
return;
|
|
|
|
sal_uInt16 nTempMonthOff = nMonthOff % 12;
|
|
sal_uInt16 nTempYearOff = nMonthOff / 12;
|
|
sal_uInt16 nNewMonth = nCurItemId % 1000;
|
|
sal_uInt16 nNewYear = nYear+((nCurItemId-1000)/1000);
|
|
if ( nTempMonthOff < nNewMonth )
|
|
nNewMonth = nNewMonth - nTempMonthOff;
|
|
else
|
|
{
|
|
nNewYear--;
|
|
nNewMonth = 12-(nTempMonthOff-nNewMonth);
|
|
}
|
|
nNewYear = nNewYear - nTempYearOff;
|
|
SetFirstDate( Date( 1, nNewMonth, nNewYear ) );
|
|
}
|
|
|
|
void Calendar::ImplTracking( const Point& rPos, bool bRepeat )
|
|
{
|
|
Date aTempDate = maCurDate;
|
|
sal_uInt16 nHitTest = ImplDoHitTest( rPos, aTempDate );
|
|
|
|
if ( mbSpinDown )
|
|
{
|
|
mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
|
|
mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
|
|
|
|
if ( bRepeat && (mbPrevIn || mbNextIn) )
|
|
{
|
|
ImplScrollCalendar( mbPrevIn );
|
|
}
|
|
}
|
|
else
|
|
ImplMouseSelect( aTempDate, nHitTest );
|
|
}
|
|
|
|
void Calendar::ImplEndTracking( bool bCancel )
|
|
{
|
|
bool bSpinDown = mbSpinDown;
|
|
|
|
mbDrag = false;
|
|
mbSpinDown = false;
|
|
mbPrevIn = false;
|
|
mbNextIn = false;
|
|
|
|
if ( bCancel )
|
|
{
|
|
if ( maOldFirstDate != maFirstDate )
|
|
SetFirstDate( maOldFirstDate );
|
|
|
|
if ( !bSpinDown )
|
|
{
|
|
IntDateSet aOldSel( *mpSelectTable );
|
|
Date aOldDate = maCurDate;
|
|
maCurDate = maOldCurDate;
|
|
*mpSelectTable = *mpOldSelectTable;
|
|
HideFocus();
|
|
ImplUpdateSelection( &aOldSel );
|
|
if ( aOldSel.find( aOldDate.GetDate() ) == aOldSel.end() )
|
|
ImplUpdateDate( aOldDate );
|
|
// assure focus rectangle is displayed again
|
|
if ( HasFocus() || mpSelectTable->find( maCurDate.GetDate() ) == mpSelectTable->end() )
|
|
ImplUpdateDate( maCurDate );
|
|
}
|
|
}
|
|
|
|
if ( bSpinDown )
|
|
return;
|
|
|
|
if ( !bCancel )
|
|
{
|
|
// determine if we should scroll the visible area
|
|
if ( !mpSelectTable->empty() )
|
|
{
|
|
Date aFirstSelDate( *mpSelectTable->begin() );
|
|
Date aLastSelDate( *mpSelectTable->rbegin() );
|
|
if ( aLastSelDate < GetFirstMonth() )
|
|
ImplScrollCalendar( true );
|
|
else if ( GetLastMonth() < aFirstSelDate )
|
|
ImplScrollCalendar( false );
|
|
}
|
|
}
|
|
|
|
if ( !bCancel && ((maCurDate != maOldCurDate) || (*mpOldSelectTable != *mpSelectTable)) )
|
|
Select();
|
|
|
|
if ( (mnWinStyle & WB_TABSTOP) && !bCancel )
|
|
GrabFocus();
|
|
|
|
mpOldSelectTable.reset();
|
|
}
|
|
|
|
void Calendar::MouseButtonDown( const MouseEvent& rMEvt )
|
|
{
|
|
if ( rMEvt.IsLeft() && !mbMenuDown )
|
|
{
|
|
Date aTempDate = maCurDate;
|
|
sal_uInt16 nHitTest = ImplDoHitTest( rMEvt.GetPosPixel(), aTempDate );
|
|
if ( nHitTest )
|
|
{
|
|
if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
|
|
ImplShowMenu( rMEvt.GetPosPixel(), aTempDate );
|
|
else
|
|
{
|
|
maOldFirstDate = maFirstDate;
|
|
|
|
mbPrevIn = (nHitTest & CALENDAR_HITTEST_PREV) != 0;
|
|
mbNextIn = (nHitTest & CALENDAR_HITTEST_NEXT) != 0;
|
|
if ( mbPrevIn || mbNextIn )
|
|
{
|
|
mbSpinDown = true;
|
|
ImplScrollCalendar( mbPrevIn );
|
|
// it should really read BUTTONREPEAT, therefore do not
|
|
// change it to SCROLLREPEAT, check with TH,
|
|
// why it could be different (71775)
|
|
StartTracking( StartTrackingFlags::ButtonRepeat );
|
|
}
|
|
else
|
|
{
|
|
if ( (rMEvt.GetClicks() != 2) || !(nHitTest & CALENDAR_HITTEST_DAY) )
|
|
{
|
|
maOldCurDate = maCurDate;
|
|
mpOldSelectTable.reset(new IntDateSet( *mpSelectTable ));
|
|
|
|
mbDrag = true;
|
|
StartTracking();
|
|
|
|
ImplMouseSelect( aTempDate, nHitTest );
|
|
}
|
|
if (rMEvt.GetClicks() == 2)
|
|
maActivateHdl.Call(this);
|
|
}
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
Control::MouseButtonDown( rMEvt );
|
|
}
|
|
|
|
void Calendar::Tracking( const TrackingEvent& rTEvt )
|
|
{
|
|
Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
|
|
|
|
if ( rTEvt.IsTrackingEnded() )
|
|
ImplEndTracking( rTEvt.IsTrackingCanceled() );
|
|
else
|
|
ImplTracking( aMousePos, rTEvt.IsTrackingRepeat() );
|
|
}
|
|
|
|
void Calendar::KeyInput( const KeyEvent& rKEvt )
|
|
{
|
|
Date aNewDate = maCurDate;
|
|
|
|
switch ( rKEvt.GetKeyCode().GetCode() )
|
|
{
|
|
case KEY_HOME:
|
|
aNewDate.SetDay( 1 );
|
|
break;
|
|
|
|
case KEY_END:
|
|
aNewDate.SetDay( aNewDate.GetDaysInMonth() );
|
|
break;
|
|
|
|
case KEY_LEFT:
|
|
--aNewDate;
|
|
break;
|
|
|
|
case KEY_RIGHT:
|
|
++aNewDate;
|
|
break;
|
|
|
|
case KEY_UP:
|
|
aNewDate.AddDays( -7 );
|
|
break;
|
|
|
|
case KEY_DOWN:
|
|
aNewDate.AddDays( 7 );
|
|
break;
|
|
|
|
case KEY_PAGEUP:
|
|
{
|
|
Date aTempDate = aNewDate;
|
|
aTempDate.AddDays( -(aNewDate.GetDay()+1) );
|
|
aNewDate.AddDays( -aTempDate.GetDaysInMonth() );
|
|
}
|
|
break;
|
|
|
|
case KEY_PAGEDOWN:
|
|
aNewDate.AddDays( aNewDate.GetDaysInMonth() );
|
|
break;
|
|
|
|
case KEY_RETURN:
|
|
break;
|
|
|
|
default:
|
|
Control::KeyInput( rKEvt );
|
|
break;
|
|
}
|
|
|
|
if ( aNewDate != maCurDate )
|
|
{
|
|
SetCurDate( aNewDate );
|
|
Select();
|
|
}
|
|
|
|
if (rKEvt.GetKeyCode().GetCode() == KEY_RETURN)
|
|
{
|
|
if (maActivateHdl.IsSet())
|
|
maActivateHdl.Call(this);
|
|
else
|
|
Control::KeyInput(rKEvt);
|
|
}
|
|
}
|
|
|
|
void Calendar::Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& )
|
|
{
|
|
ImplDraw(rRenderContext);
|
|
}
|
|
|
|
void Calendar::GetFocus()
|
|
{
|
|
ImplUpdateDate( maCurDate );
|
|
Control::GetFocus();
|
|
}
|
|
|
|
void Calendar::LoseFocus()
|
|
{
|
|
HideFocus();
|
|
Control::LoseFocus();
|
|
}
|
|
|
|
void Calendar::Resize()
|
|
{
|
|
ImplUpdate( true );
|
|
Control::Resize();
|
|
}
|
|
|
|
void Calendar::RequestHelp( const HelpEvent& rHEvt )
|
|
{
|
|
if ( rHEvt.GetMode() & (HelpEventMode::QUICK | HelpEventMode::BALLOON) )
|
|
{
|
|
Date aDate = maCurDate;
|
|
if ( GetDate( ScreenToOutputPixel( rHEvt.GetMousePosPixel() ), aDate ) )
|
|
{
|
|
tools::Rectangle aDateRect = GetDateRect( aDate );
|
|
Point aPt = OutputToScreenPixel( aDateRect.TopLeft() );
|
|
aDateRect.SetLeft( aPt.X() );
|
|
aDateRect.SetTop( aPt.Y() );
|
|
aPt = OutputToScreenPixel( aDateRect.BottomRight() );
|
|
aDateRect.SetRight( aPt.X() );
|
|
aDateRect.SetBottom( aPt.Y() );
|
|
|
|
if ( rHEvt.GetMode() & HelpEventMode::QUICK )
|
|
{
|
|
maCalendarWrapper.setGregorianDateTime( DateTime(aDate) );
|
|
sal_uInt16 nWeek = static_cast<sal_uInt16>(maCalendarWrapper.getValue( i18n::CalendarFieldIndex::WEEK_OF_YEAR));
|
|
sal_uInt16 nMonth = aDate.GetMonth();
|
|
OUString aStr = maDayText
|
|
+ ": "
|
|
+ OUString::number(aDate.GetDayOfYear())
|
|
+ " / "
|
|
+ maWeekText
|
|
+ ": "
|
|
+ OUString::number(nWeek);
|
|
// if year is not the same, add it
|
|
if ( (nMonth == 12) && (nWeek == 1) )
|
|
{
|
|
aStr += ", " + OUString::number(aDate.GetNextYear());
|
|
}
|
|
else if ( (nMonth == 1) && (nWeek > 50) )
|
|
{
|
|
aStr += ", " + OUString::number(aDate.GetYear()-1);
|
|
}
|
|
Help::ShowQuickHelp( this, aDateRect, aStr );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
Control::RequestHelp( rHEvt );
|
|
}
|
|
|
|
void Calendar::Command( const CommandEvent& rCEvt )
|
|
{
|
|
if ( rCEvt.GetCommand() == CommandEventId::ContextMenu )
|
|
{
|
|
if ( rCEvt.IsMouseEvent() )
|
|
{
|
|
Date aTempDate = maCurDate;
|
|
sal_uInt16 nHitTest = ImplDoHitTest( rCEvt.GetMousePosPixel(), aTempDate );
|
|
if ( nHitTest & CALENDAR_HITTEST_MONTHTITLE )
|
|
{
|
|
ImplShowMenu( rCEvt.GetMousePosPixel(), aTempDate );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else if ( rCEvt.GetCommand() == CommandEventId::Wheel )
|
|
{
|
|
const CommandWheelData* pData = rCEvt.GetWheelData();
|
|
if ( pData->GetMode() == CommandWheelMode::SCROLL )
|
|
{
|
|
tools::Long nNotchDelta = pData->GetNotchDelta();
|
|
if ( nNotchDelta < 0 )
|
|
{
|
|
while ( nNotchDelta < 0 )
|
|
{
|
|
ImplScrollCalendar( true );
|
|
nNotchDelta++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while ( nNotchDelta > 0 )
|
|
{
|
|
ImplScrollCalendar( false );
|
|
nNotchDelta--;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
Control::Command( rCEvt );
|
|
}
|
|
|
|
void Calendar::StateChanged( StateChangedType nType )
|
|
{
|
|
Control::StateChanged( nType );
|
|
|
|
if ( nType == StateChangedType::InitShow )
|
|
ImplFormat();
|
|
}
|
|
|
|
void Calendar::DataChanged( const DataChangedEvent& rDCEvt )
|
|
{
|
|
Control::DataChanged( rDCEvt );
|
|
|
|
if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
|
|
(rDCEvt.GetType() == DataChangedEventType::FONTSUBSTITUTION) ||
|
|
((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
|
|
(rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
|
|
{
|
|
ImplInitSettings();
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
void Calendar::Select()
|
|
{
|
|
maSelectHdl.Call( this );
|
|
}
|
|
|
|
Date Calendar::GetFirstSelectedDate() const
|
|
{
|
|
if ( !mpSelectTable->empty() )
|
|
return Date( *mpSelectTable->begin() );
|
|
else
|
|
{
|
|
Date aDate( 0, 0, 0 );
|
|
return aDate;
|
|
}
|
|
}
|
|
|
|
void Calendar::SetCurDate( const Date& rNewDate )
|
|
{
|
|
if ( !rNewDate.IsValidAndGregorian() )
|
|
return;
|
|
|
|
if ( maCurDate == rNewDate )
|
|
return;
|
|
|
|
bool bUpdate = IsVisible() && IsUpdateMode();
|
|
Date aOldDate = maCurDate;
|
|
maCurDate = rNewDate;
|
|
|
|
ImplCalendarSelectDate( mpSelectTable.get(), aOldDate, false );
|
|
ImplCalendarSelectDate( mpSelectTable.get(), maCurDate, true );
|
|
|
|
// shift actual date in the visible area
|
|
if ( mbFormat || (maCurDate < GetFirstMonth()) )
|
|
SetFirstDate( maCurDate );
|
|
else if ( maCurDate > GetLastMonth() )
|
|
{
|
|
Date aTempDate = GetLastMonth();
|
|
tools::Long nDateOff = maCurDate-aTempDate;
|
|
if ( nDateOff < 365 )
|
|
{
|
|
Date aFirstDate = GetFirstMonth();
|
|
aFirstDate.AddDays( aFirstDate.GetDaysInMonth() );
|
|
++aTempDate;
|
|
while ( nDateOff > aTempDate.GetDaysInMonth() )
|
|
{
|
|
aFirstDate.AddDays( aFirstDate.GetDaysInMonth() );
|
|
sal_Int32 nDaysInMonth = aTempDate.GetDaysInMonth();
|
|
aTempDate.AddDays( nDaysInMonth );
|
|
nDateOff -= nDaysInMonth;
|
|
}
|
|
SetFirstDate( aFirstDate );
|
|
}
|
|
else
|
|
SetFirstDate( maCurDate );
|
|
}
|
|
else
|
|
{
|
|
if ( bUpdate )
|
|
{
|
|
HideFocus();
|
|
ImplUpdateDate( aOldDate );
|
|
ImplUpdateDate( maCurDate );
|
|
}
|
|
}
|
|
}
|
|
|
|
void Calendar::SetFirstDate( const Date& rNewFirstDate )
|
|
{
|
|
if ( maFirstDate != rNewFirstDate )
|
|
{
|
|
maFirstDate = Date( 1, rNewFirstDate.GetMonth(), rNewFirstDate.GetYear() );
|
|
ImplUpdate();
|
|
}
|
|
}
|
|
|
|
Date Calendar::GetFirstMonth() const
|
|
{
|
|
if ( maFirstDate.GetDay() > 1 )
|
|
{
|
|
if ( maFirstDate.GetMonth() == 12 )
|
|
return Date( 1, 1, maFirstDate.GetNextYear() );
|
|
else
|
|
return Date( 1, maFirstDate.GetMonth()+1, maFirstDate.GetYear() );
|
|
}
|
|
else
|
|
return maFirstDate;
|
|
}
|
|
|
|
Date Calendar::GetLastMonth() const
|
|
{
|
|
Date aDate = GetFirstMonth();
|
|
sal_uInt16 nMonthCount = GetMonthCount();
|
|
for ( sal_uInt16 i = 0; i < nMonthCount; i++ )
|
|
aDate.AddDays( aDate.GetDaysInMonth() );
|
|
--aDate;
|
|
return aDate;
|
|
}
|
|
|
|
sal_uInt16 Calendar::GetMonthCount() const
|
|
{
|
|
if ( mbFormat )
|
|
return 1;
|
|
else
|
|
return static_cast<sal_uInt16>(mnMonthPerLine*mnLines);
|
|
}
|
|
|
|
bool Calendar::GetDate( const Point& rPos, Date& rDate ) const
|
|
{
|
|
Date aDate = maCurDate;
|
|
sal_uInt16 nHitTest = ImplDoHitTest( rPos, aDate );
|
|
if ( nHitTest & CALENDAR_HITTEST_DAY )
|
|
{
|
|
rDate = aDate;
|
|
return true;
|
|
}
|
|
else
|
|
return false;
|
|
}
|
|
|
|
tools::Rectangle Calendar::GetDateRect( const Date& rDate ) const
|
|
{
|
|
tools::Rectangle aRect;
|
|
|
|
if ( mbFormat || (rDate < maFirstDate) || (rDate > (maFirstDate+mnDayCount)) )
|
|
return aRect;
|
|
|
|
tools::Long nX;
|
|
tools::Long nY;
|
|
sal_Int32 nDaysOff;
|
|
sal_uInt16 nDayIndex;
|
|
Date aDate = GetFirstMonth();
|
|
|
|
if ( rDate < aDate )
|
|
{
|
|
aRect = GetDateRect( aDate );
|
|
nDaysOff = aDate-rDate;
|
|
nX = nDaysOff*mnDayWidth;
|
|
aRect.AdjustLeft( -nX );
|
|
aRect.AdjustRight( -nX );
|
|
return aRect;
|
|
}
|
|
else
|
|
{
|
|
Date aLastDate = GetLastMonth();
|
|
if ( rDate > aLastDate )
|
|
{
|
|
sal_Int32 nWeekDay = static_cast<sal_Int32>(aLastDate.GetDayOfWeek());
|
|
nWeekDay = (nWeekDay+(7-ImplGetWeekStart())) % 7;
|
|
aLastDate.AddDays( -nWeekDay );
|
|
aRect = GetDateRect( aLastDate );
|
|
nDaysOff = rDate-aLastDate;
|
|
nDayIndex = 0;
|
|
for ( sal_Int32 i = 0; i <= nDaysOff; i++ )
|
|
{
|
|
if ( aLastDate == rDate )
|
|
{
|
|
aRect.AdjustLeft(nDayIndex*mnDayWidth );
|
|
aRect.SetRight( aRect.Left()+mnDayWidth );
|
|
return aRect;
|
|
}
|
|
if ( nDayIndex == 6 )
|
|
{
|
|
nDayIndex = 0;
|
|
aRect.AdjustTop(mnDayHeight );
|
|
aRect.AdjustBottom(mnDayHeight );
|
|
}
|
|
else
|
|
nDayIndex++;
|
|
++aLastDate;
|
|
}
|
|
}
|
|
}
|
|
|
|
nY = 0;
|
|
for ( tools::Long i = 0; i < mnLines; i++ )
|
|
{
|
|
nX = 0;
|
|
for ( tools::Long j = 0; j < mnMonthPerLine; j++ )
|
|
{
|
|
sal_uInt16 nDaysInMonth = aDate.GetDaysInMonth();
|
|
|
|
// month is called
|
|
if ( (aDate.GetMonth() == rDate.GetMonth()) &&
|
|
(aDate.GetYear() == rDate.GetYear()) )
|
|
{
|
|
tools::Long nDayX = nX+mnDaysOffX;
|
|
tools::Long nDayY = nY+mnDaysOffY;
|
|
nDayIndex = static_cast<sal_uInt16>(aDate.GetDayOfWeek());
|
|
nDayIndex = (nDayIndex+(7-static_cast<sal_uInt16>(ImplGetWeekStart()))) % 7;
|
|
for ( sal_uInt16 nDay = 1; nDay <= nDaysInMonth; nDay++ )
|
|
{
|
|
if ( nDay == rDate.GetDay() )
|
|
{
|
|
aRect.SetLeft( nDayX + (nDayIndex*mnDayWidth) );
|
|
aRect.SetTop( nDayY );
|
|
aRect.SetRight( aRect.Left()+mnDayWidth );
|
|
aRect.SetBottom( aRect.Top()+mnDayHeight );
|
|
break;
|
|
}
|
|
if ( nDayIndex == 6 )
|
|
{
|
|
nDayIndex = 0;
|
|
nDayY += mnDayHeight;
|
|
}
|
|
else
|
|
nDayIndex++;
|
|
}
|
|
}
|
|
|
|
aDate.AddDays( nDaysInMonth );
|
|
nX += mnMonthWidth;
|
|
}
|
|
|
|
nY += mnMonthHeight;
|
|
}
|
|
|
|
return aRect;
|
|
}
|
|
|
|
void Calendar::EndSelection()
|
|
{
|
|
if ( mbDrag || mbSpinDown )
|
|
{
|
|
ReleaseMouse();
|
|
|
|
mbDrag = false;
|
|
mbSpinDown = false;
|
|
mbPrevIn = false;
|
|
mbNextIn = false;
|
|
}
|
|
}
|
|
|
|
Size Calendar::CalcWindowSizePixel() const
|
|
{
|
|
Size aSize;
|
|
tools::Long n99TextWidth = GetTextWidth( u"99"_ustr );
|
|
tools::Long nTextHeight = GetTextHeight();
|
|
|
|
aSize.AdjustWidth((n99TextWidth+DAY_OFFX)*7);
|
|
aSize.AdjustWidth(MONTH_BORDERX*2 );
|
|
|
|
aSize.setHeight( nTextHeight + TITLE_OFFY + (TITLE_BORDERY*2) );
|
|
aSize.AdjustHeight(nTextHeight + WEEKDAY_OFFY );
|
|
aSize.AdjustHeight((nTextHeight+DAY_OFFY)*6);
|
|
aSize.AdjustHeight(MONTH_OFFY );
|
|
|
|
return aSize;
|
|
}
|
|
|
|
Size Calendar::GetOptimalSize() const
|
|
{
|
|
return CalcWindowSizePixel();
|
|
}
|
|
|
|
void Calendar::DumpAsPropertyTree(tools::JsonWriter& rJsonWriter)
|
|
{
|
|
Control::DumpAsPropertyTree(rJsonWriter);
|
|
|
|
auto aDate = GetFirstSelectedDate();
|
|
|
|
rJsonWriter.put("type", "calendar");
|
|
rJsonWriter.put("day", aDate.GetDay());
|
|
rJsonWriter.put("month", aDate.GetMonth());
|
|
rJsonWriter.put("year", aDate.GetYear());
|
|
}
|
|
|
|
namespace
|
|
{
|
|
class ImplCFieldFloat final
|
|
{
|
|
private:
|
|
std::unique_ptr<weld::Builder> mxBuilder;
|
|
std::unique_ptr<weld::Container> mxContainer;
|
|
std::unique_ptr<weld::Calendar> mxCalendar;
|
|
std::unique_ptr<weld::Button> mxTodayBtn;
|
|
std::unique_ptr<weld::Button> mxNoneBtn;
|
|
|
|
public:
|
|
ImplCFieldFloat(vcl::Window* pContainer)
|
|
: mxBuilder(Application::CreateInterimBuilder(pContainer, u"svt/ui/calendar.ui"_ustr, false))
|
|
, mxContainer(mxBuilder->weld_container(u"Calendar"_ustr))
|
|
, mxCalendar(mxBuilder->weld_calendar(u"date"_ustr))
|
|
, mxTodayBtn(mxBuilder->weld_button(u"today"_ustr))
|
|
, mxNoneBtn(mxBuilder->weld_button(u"none"_ustr))
|
|
{
|
|
}
|
|
|
|
weld::Calendar* GetCalendar() { return mxCalendar.get(); }
|
|
weld::Button* EnableTodayBtn(bool bEnable);
|
|
weld::Button* EnableNoneBtn(bool bEnable);
|
|
|
|
void GrabFocus()
|
|
{
|
|
mxCalendar->grab_focus();
|
|
}
|
|
};
|
|
}
|
|
|
|
struct ImplCFieldFloatWin : public DropdownDockingWindow
|
|
{
|
|
explicit ImplCFieldFloatWin(vcl::Window* pParent);
|
|
virtual void dispose() override;
|
|
virtual ~ImplCFieldFloatWin() override;
|
|
virtual void GetFocus() override;
|
|
|
|
std::unique_ptr<ImplCFieldFloat> mxWidget;
|
|
};
|
|
|
|
ImplCFieldFloatWin::ImplCFieldFloatWin(vcl::Window* pParent)
|
|
: DropdownDockingWindow(pParent)
|
|
{
|
|
setDeferredProperties();
|
|
mxWidget.reset(new ImplCFieldFloat(m_xBox.get()));
|
|
}
|
|
|
|
ImplCFieldFloatWin::~ImplCFieldFloatWin()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void ImplCFieldFloatWin::dispose()
|
|
{
|
|
mxWidget.reset();
|
|
DropdownDockingWindow::dispose();
|
|
}
|
|
|
|
void ImplCFieldFloatWin::GetFocus()
|
|
{
|
|
DropdownDockingWindow::GetFocus();
|
|
if (!mxWidget)
|
|
return;
|
|
mxWidget->GrabFocus();
|
|
}
|
|
|
|
weld::Button* ImplCFieldFloat::EnableTodayBtn(bool bEnable)
|
|
{
|
|
mxTodayBtn->set_visible(bEnable);
|
|
return bEnable ? mxTodayBtn.get() : nullptr;
|
|
}
|
|
|
|
weld::Button* ImplCFieldFloat::EnableNoneBtn(bool bEnable)
|
|
{
|
|
mxNoneBtn->set_visible(bEnable);
|
|
return bEnable ? mxNoneBtn.get() : nullptr;
|
|
}
|
|
|
|
CalendarField::CalendarField(vcl::Window* pParent, WinBits nWinStyle)
|
|
: DateField(pParent, nWinStyle)
|
|
, mpFloatWin(nullptr)
|
|
, mpTodayBtn(nullptr)
|
|
, mpNoneBtn(nullptr)
|
|
, mbToday(false)
|
|
, mbNone(false)
|
|
{
|
|
}
|
|
|
|
CalendarField::~CalendarField()
|
|
{
|
|
disposeOnce();
|
|
}
|
|
|
|
void CalendarField::dispose()
|
|
{
|
|
mpTodayBtn = nullptr;
|
|
mpNoneBtn = nullptr;
|
|
mpFloatWin.disposeAndClear();
|
|
DateField::dispose();
|
|
}
|
|
|
|
IMPL_LINK(CalendarField, ImplSelectHdl, weld::Calendar&, rCalendar, void)
|
|
{
|
|
Date aNewDate = rCalendar.get_date();
|
|
|
|
vcl::Window::GetDockingManager()->EndPopupMode(mpFloatWin);
|
|
mpFloatWin->EnableDocking(false);
|
|
EndDropDown();
|
|
GrabFocus();
|
|
if ( IsEmptyDate() || ( aNewDate != GetDate() ) )
|
|
{
|
|
SetDate( aNewDate );
|
|
SetModifyFlag();
|
|
Modify();
|
|
}
|
|
}
|
|
|
|
IMPL_LINK(CalendarField, ImplClickHdl, weld::Button&, rBtn, void)
|
|
{
|
|
vcl::Window::GetDockingManager()->EndPopupMode(mpFloatWin);
|
|
mpFloatWin->EnableDocking(false);
|
|
EndDropDown();
|
|
GrabFocus();
|
|
|
|
if (&rBtn == mpTodayBtn)
|
|
{
|
|
Date aToday( Date::SYSTEM );
|
|
if ( (aToday != GetDate()) || IsEmptyDate() )
|
|
{
|
|
SetDate( aToday );
|
|
SetModifyFlag();
|
|
Modify();
|
|
}
|
|
}
|
|
else if (&rBtn == mpNoneBtn)
|
|
{
|
|
if ( !IsEmptyDate() )
|
|
{
|
|
SetEmptyDate();
|
|
SetModifyFlag();
|
|
Modify();
|
|
}
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(CalendarField, ImplPopupModeEndHdl, FloatingWindow*, void)
|
|
{
|
|
EndDropDown();
|
|
GrabFocus();
|
|
}
|
|
|
|
bool CalendarField::ShowDropDown( bool bShow )
|
|
{
|
|
if ( bShow )
|
|
{
|
|
if ( !mpFloatWin )
|
|
mpFloatWin = VclPtr<ImplCFieldFloatWin>::Create( this );
|
|
|
|
Date aDate = GetDate();
|
|
if ( IsEmptyDate() || !aDate.IsValidAndGregorian() )
|
|
{
|
|
aDate = Date( Date::SYSTEM );
|
|
}
|
|
weld::Calendar* pCalendar = mpFloatWin->mxWidget->GetCalendar();
|
|
pCalendar->set_date( aDate );
|
|
pCalendar->connect_activated(LINK(this, CalendarField, ImplSelectHdl));
|
|
mpTodayBtn = mpFloatWin->mxWidget->EnableTodayBtn(mbToday);
|
|
mpNoneBtn = mpFloatWin->mxWidget->EnableNoneBtn(mbNone);
|
|
if (mpTodayBtn)
|
|
mpTodayBtn->connect_clicked( LINK( this, CalendarField, ImplClickHdl ) );
|
|
if (mpNoneBtn)
|
|
mpNoneBtn->connect_clicked( LINK( this, CalendarField, ImplClickHdl ) );
|
|
Point aPos(GetParent()->OutputToScreenPixel(GetPosPixel()));
|
|
tools::Rectangle aRect(aPos, GetSizePixel());
|
|
aRect.AdjustBottom( -1 );
|
|
DockingManager* pDockingManager = vcl::Window::GetDockingManager();
|
|
mpFloatWin->EnableDocking(true);
|
|
pDockingManager->SetPopupModeEndHdl(mpFloatWin, LINK(this, CalendarField, ImplPopupModeEndHdl));
|
|
pDockingManager->StartPopupMode(mpFloatWin, aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus);
|
|
}
|
|
else
|
|
{
|
|
vcl::Window::GetDockingManager()->EndPopupMode(mpFloatWin);
|
|
mpFloatWin->EnableDocking(false);
|
|
EndDropDown();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CalendarField::StateChanged( StateChangedType nStateChange )
|
|
{
|
|
DateField::StateChanged( nStateChange );
|
|
|
|
if ( ( nStateChange == StateChangedType::Style ) && GetSubEdit() )
|
|
{
|
|
WinBits nAllAlignmentBits = ( WB_LEFT | WB_CENTER | WB_RIGHT | WB_TOP | WB_VCENTER | WB_BOTTOM );
|
|
WinBits nMyAlignment = GetStyle() & nAllAlignmentBits;
|
|
GetSubEdit()->SetStyle( ( GetSubEdit()->GetStyle() & ~nAllAlignmentBits ) | nMyAlignment );
|
|
}
|
|
}
|
|
|
|
// tdf#142783 consider the Edit and its DropDown as one compound control for the purpose of
|
|
// notification of loss of focus from the control
|
|
bool CalendarField::FocusWindowBelongsToControl(const vcl::Window* pFocusWin) const
|
|
{
|
|
return DateField::FocusWindowBelongsToControl(pFocusWin) || (mpFloatWin && mpFloatWin->ImplIsWindowOrChild(pFocusWin));
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|