office-gobmx/svtools/source/control/calendar.cxx
Caolán McNamara bafd50ee06 weld DateField Calendar floating window
Change-Id: I8d839a09b787e2b8ac1389633a39a3cd969fb1c9
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96816
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
2020-06-21 21:14:36 +02:00

235 lines
6.8 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/InterimItemWindow.hxx>
#include <vcl/event.hxx>
#include <vcl/dockwin.hxx>
#include <vcl/svapp.hxx>
#include <svtools/strings.hrc>
#include <svtools/svtresid.hxx>
#include <svtools/calendar.hxx>
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, "svt/ui/calendar.ui"))
, mxContainer(mxBuilder->weld_container("Calendar"))
, mxCalendar(mxBuilder->weld_calendar("date"))
, mxTodayBtn(mxBuilder->weld_button("today"))
, mxNoneBtn(mxBuilder->weld_button("none"))
{
}
weld::Calendar* GetCalendar() { return mxCalendar.get(); }
weld::Button* EnableTodayBtn(bool bEnable);
weld::Button* EnableNoneBtn(bool bEnable);
void GrabFocus()
{
mxCalendar->grab_focus();
}
};
}
struct ImplCFieldFloatWin : public DockingWindow
{
explicit ImplCFieldFloatWin(vcl::Window* pParent);
virtual void dispose() override;
virtual ~ImplCFieldFloatWin() override;
virtual void GetFocus() override;
VclPtr<vcl::Window> mxBox;
std::unique_ptr<ImplCFieldFloat> mxWidget;
};
ImplCFieldFloatWin::ImplCFieldFloatWin(vcl::Window* pParent)
: DockingWindow(pParent, "InterimDockParent", "svx/ui/interimdockparent.ui")
, mxBox(get("box"))
{
setDeferredProperties();
mxWidget.reset(new ImplCFieldFloat(mxBox.get()));
}
ImplCFieldFloatWin::~ImplCFieldFloatWin()
{
disposeOnce();
}
void ImplCFieldFloatWin::dispose()
{
mxWidget.reset();
mxBox.disposeAndClear();
DockingWindow::dispose();
}
void ImplCFieldFloatWin::GetFocus()
{
DockingWindow::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 );
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */