include/xmloff/odffields.hxx | 1 sw/Library_sw.mk | 2 sw/source/core/crsr/DateFormFieldButton.cxx | 97 +++++++++++++++ sw/source/core/crsr/DropDownFormFieldButton.cxx | 123 ------------------- sw/source/core/crsr/FormFieldButton.cxx | 155 ++++++++++++++++++++++++ sw/source/core/crsr/bookmrk.cxx | 77 ++++------- sw/source/core/doc/docbm.cxx | 13 +- sw/source/core/inc/DateFormFieldButton.hxx | 42 ++++++ sw/source/core/inc/DropDownFormFieldButton.hxx | 19 -- sw/source/core/inc/FormFieldButton.hxx | 56 ++++++++ sw/source/core/inc/MarkManager.hxx | 4 sw/source/core/inc/bookmrk.hxx | 40 +++--- 12 files changed, 416 insertions(+), 213 deletions(-)
New commits: commit f5bb449dbaf838c3a840a8a9e816edfe714afb44 Author: Tamás Zolnai <[email protected]> AuthorDate: Fri Jul 12 00:59:09 2019 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Jul 14 00:15:55 2019 +0200 MSForms: Add a drop-down button for the text-based date field * A calendar is opened by this button, where the user can select a date. * I used the same activation method which is used for drop-down form fields. Reviewed-on: https://gerrit.libreoffice.org/75443 Reviewed-by: Tamás Zolnai <[email protected]> Tested-by: Tamás Zolnai <[email protected]> (cherry picked from commit 836d688476afc22288c4f032af07c7d65d553c68) Change-Id: If0e63083463b9ead93baa2f27bdaaaf80aa9ce2f Reviewed-on: https://gerrit.libreoffice.org/75536 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Andras Timar <[email protected]> diff --git a/include/xmloff/odffields.hxx b/include/xmloff/odffields.hxx index 0b0ec4676f39..fc119fe0a295 100644 --- a/include/xmloff/odffields.hxx +++ b/include/xmloff/odffields.hxx @@ -35,6 +35,7 @@ #define ODF_FORMDATE "vnd.oasis.opendocument.field.FORMDATE" #define ODF_FORMDATE_DATEFORMAT "DateField_DateFormat" +#define ODF_FORMDATE_CURRENTDATE "DateField_CurrentDate" #define ODF_TOC "vnd.oasis.opendocument.field.TOC" diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index 0a4bbe9ede39..df050fd4310d 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -149,6 +149,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ sw/source/core/crsr/crsrsh \ sw/source/core/crsr/crstrvl \ sw/source/core/crsr/crstrvl1 \ + sw/source/core/crsr/DateFormFieldButton \ sw/source/core/crsr/DropDownFormFieldButton \ sw/source/core/crsr/findattr \ sw/source/core/crsr/findcoll \ diff --git a/sw/source/core/crsr/DateFormFieldButton.cxx b/sw/source/core/crsr/DateFormFieldButton.cxx new file mode 100644 index 000000000000..d2f2267e0d46 --- /dev/null +++ b/sw/source/core/crsr/DateFormFieldButton.cxx @@ -0,0 +1,97 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include <DateFormFieldButton.hxx> +#include <edtwin.hxx> +#include <basegfx/color/bcolortools.hxx> +#include <viewopt.hxx> +#include <bookmrk.hxx> +#include <vcl/floatwin.hxx> +#include <vcl/event.hxx> +#include <vcl/lstbox.hxx> +#include <xmloff/odffields.hxx> +#include <IMark.hxx> +#include <view.hxx> +#include <docsh.hxx> +#include <strings.hrc> +#include <svtools/calendar.hxx> +#include <tools/date.hxx> + +class SwDatePickerDialog : public FloatingWindow +{ +private: + VclPtr<Calendar> m_pCalendar; + sw::mark::IFieldmark* m_pFieldmark; + + DECL_LINK(ImplSelectHdl, Calendar*, void); + +public: + SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* pFieldmark); + virtual ~SwDatePickerDialog() override; + virtual void dispose() override; +}; + +SwDatePickerDialog::SwDatePickerDialog(SwEditWin* parent, sw::mark::IFieldmark* pFieldmark) + : FloatingWindow(parent, WB_BORDER | WB_SYSTEMWINDOW | WB_NOSHADOW) + , m_pCalendar(VclPtr<Calendar>::Create(this, WB_TABSTOP)) + , m_pFieldmark(pFieldmark) +{ + if (m_pFieldmark != nullptr) + { + sw::mark::IFieldmark::parameter_map_t* pParameters = m_pFieldmark->GetParameters(); + auto pResult = pParameters->find(ODF_FORMDATE_CURRENTDATE); + if (pResult != pParameters->end()) + { + sal_Int32 nCurrentDate = 0; + pResult->second >>= nCurrentDate; + m_pCalendar->SetCurDate(Date(nCurrentDate)); + } + } + m_pCalendar->SetSelectHdl(LINK(this, SwDatePickerDialog, ImplSelectHdl)); + m_pCalendar->SetOutputSizePixel(m_pCalendar->CalcWindowSizePixel()); + m_pCalendar->Show(); + SetOutputSizePixel(m_pCalendar->GetSizePixel()); +} + +SwDatePickerDialog::~SwDatePickerDialog() { disposeOnce(); } + +void SwDatePickerDialog::dispose() +{ + m_pCalendar.disposeAndClear(); + FloatingWindow::dispose(); +} + +IMPL_LINK(SwDatePickerDialog, ImplSelectHdl, Calendar*, pCalendar, void) +{ + if (!pCalendar->IsTravelSelect()) + { + if (m_pFieldmark != nullptr) + { + sw::mark::IFieldmark::parameter_map_t* pParameters = m_pFieldmark->GetParameters(); + (*pParameters)[ODF_FORMDATE_CURRENTDATE] + <<= pCalendar->GetFirstSelectedDate().GetDate(); + } + EndPopupMode(); + } +} + +DateFormFieldButton::DateFormFieldButton(SwEditWin* pEditWin, sw::mark::DateFieldmark& rFieldmark) + : FormFieldButton(pEditWin, rFieldmark) +{ +} + +DateFormFieldButton::~DateFormFieldButton() { disposeOnce(); } + +void DateFormFieldButton::InitPopup() +{ + m_pFieldPopup + = VclPtr<SwDatePickerDialog>::Create(static_cast<SwEditWin*>(GetParent()), &m_rFieldmark); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx index fea8530426cd..d8467b4ce0c3 100644 --- a/sw/source/core/crsr/bookmrk.cxx +++ b/sw/source/core/crsr/bookmrk.cxx @@ -37,6 +37,8 @@ #include <comphelper/random.hxx> #include <comphelper/anytostring.hxx> #include <edtwin.hxx> +#include <DateFormFieldButton.hxx> +#include <DropDownFormFieldButton.hxx> using namespace ::sw::mark; using namespace ::com::sun::star; @@ -485,18 +487,18 @@ namespace sw { namespace mark return bResult; } - DropDownFieldmark::DropDownFieldmark(const SwPaM& rPaM) + FieldmarkWithDropDownButton::FieldmarkWithDropDownButton(const SwPaM& rPaM) : NonTextFieldmark(rPaM) , m_pButton(nullptr) { } - DropDownFieldmark::~DropDownFieldmark() + FieldmarkWithDropDownButton::~FieldmarkWithDropDownButton() { m_pButton.disposeAndClear(); } - void DropDownFieldmark::SetPortionPaintArea(const SwRect& rPortionPaintArea) + void FieldmarkWithDropDownButton::SetPortionPaintArea(const SwRect& rPortionPaintArea) { if(m_aPortionPaintArea == rPortionPaintArea && m_pButton && m_pButton->IsVisible()) @@ -511,81 +513,56 @@ namespace sw { namespace mark } } - void DropDownFieldmark::ShowButton(SwEditWin* pEditWin) - { - if(pEditWin) - { - if(!m_pButton) - m_pButton = VclPtr<DropDownFormFieldButton>::Create(pEditWin, *this); - m_pButton->CalcPosAndSize(m_aPortionPaintArea); - m_pButton->Show(); - } - } - - void DropDownFieldmark::HideButton() + void FieldmarkWithDropDownButton::HideButton() { if(m_pButton) m_pButton->Show(false); } - void DropDownFieldmark::RemoveButton() + void FieldmarkWithDropDownButton::RemoveButton() { if(m_pButton) m_pButton.disposeAndClear(); } - DateFieldmark::DateFieldmark(const SwPaM& rPaM) - : NonTextFieldmark(rPaM) - //, m_pButton(nullptr) + DropDownFieldmark::DropDownFieldmark(const SwPaM& rPaM) + : FieldmarkWithDropDownButton(rPaM) { } - DateFieldmark::~DateFieldmark() + DropDownFieldmark::~DropDownFieldmark() { - //m_pButton.disposeAndClear(); - (void)m_pButton; } - void DateFieldmark::SetPortionPaintArea(const SwRect& /*rPortionPaintArea*/) + void DropDownFieldmark::ShowButton(SwEditWin* pEditWin) { - /*if(m_aPortionPaintArea == rPortionPaintArea && - m_pButton && m_pButton->IsVisible()) - return; - - m_aPortionPaintArea = rPortionPaintArea; - if(m_pButton) + if(pEditWin) { - m_pButton->Show(); + if(!m_pButton) + m_pButton = VclPtr<DropDownFormFieldButton>::Create(pEditWin, *this); m_pButton->CalcPosAndSize(m_aPortionPaintArea); - m_pButton->Invalidate(); - }*/ - (void)m_pButton; + m_pButton->Show(); + } } - void DateFieldmark::ShowButton(SwEditWin* pEditWin) + DateFieldmark::DateFieldmark(const SwPaM& rPaM) + : FieldmarkWithDropDownButton(rPaM) { - if(pEditWin) - { - //if(!m_pButton) - // m_pButton = VclPtr<DropDownFormFieldButton>::Create(pEditWin, *this); - //m_pButton->CalcPosAndSize(m_aPortionPaintArea); - //m_pButton->Show(); - } - (void)m_pButton; } - void DateFieldmark::HideButton() + DateFieldmark::~DateFieldmark() { - //if(m_pButton) - //m_pButton->Show(false); - (void)m_pButton; } - void DateFieldmark::RemoveButton() + void DateFieldmark::ShowButton(SwEditWin* pEditWin) { - //if(m_pButton) - //m_pButton.disposeAndClear(); - (void)m_pButton; + if(pEditWin) + { + if(!m_pButton) + m_pButton = VclPtr<DateFormFieldButton>::Create(pEditWin, *this); + m_pButton->CalcPosAndSize(m_aPortionPaintArea); + m_pButton->Show(); + } } }} diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx index a49af25432d3..5b74a410bf79 100644 --- a/sw/source/core/doc/docbm.cxx +++ b/sw/source/core/doc/docbm.cxx @@ -1167,21 +1167,22 @@ namespace sw { namespace mark SwEditWin& rEditWin = pSwView->GetEditWin(); SwPosition aPos(*rCursorShell.GetCursor()->GetPoint()); IFieldmark* pFieldBM = getFieldmarkFor(aPos); - DropDownFieldmark* pNewActiveFieldmark = nullptr; - if ((!pFieldBM || pFieldBM->GetFieldname() != ODF_FORMDROPDOWN) + FieldmarkWithDropDownButton* pNewActiveFieldmark = nullptr; + if ((!pFieldBM || (pFieldBM->GetFieldname() != ODF_FORMDROPDOWN && pFieldBM->GetFieldname() != ODF_FORMDATE)) && aPos.nContent.GetIndex() > 0 ) { --aPos.nContent; pFieldBM = getFieldmarkFor(aPos); } - if ( pFieldBM && pFieldBM->GetFieldname() == ODF_FORMDROPDOWN ) + if ( pFieldBM && (pFieldBM->GetFieldname() == ODF_FORMDROPDOWN || + pFieldBM->GetFieldname() == ODF_FORMDATE)) { if (m_pLastActiveFieldmark != pFieldBM) { - DropDownFieldmark* pDropDownFm = dynamic_cast<DropDownFieldmark*>(pFieldBM); - pDropDownFm->ShowButton(&rEditWin); - pNewActiveFieldmark = pDropDownFm; + auto pFormField = dynamic_cast<FieldmarkWithDropDownButton*>(pFieldBM); + pFormField->ShowButton(&rEditWin); + pNewActiveFieldmark = pFormField; } else { diff --git a/sw/source/core/inc/DateFormFieldButton.hxx b/sw/source/core/inc/DateFormFieldButton.hxx new file mode 100644 index 000000000000..ff677b610b3d --- /dev/null +++ b/sw/source/core/inc/DateFormFieldButton.hxx @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#ifndef INCLUDED_SW_SOURCE_CORE_TEXT_DATEFORMEFIELDBUTTO_HXX +#define INCLUDED_SW_SOURCE_CORE_TEXT_DATEFORMEFIELDBUTTO_HXX + +#include <vcl/menubtn.hxx> +#include <swrect.hxx> +#include "FormFieldButton.hxx" + +class SwEditWin; +class FloatingWindow; +namespace sw +{ +namespace mark +{ +class DateFieldmark; +} +} // namespace sw + +/** + * This button is shown when the cursor is on a date form field. + * The user can select a date from a date picker while filling in a form. + */ +class DateFormFieldButton : public FormFieldButton +{ +public: + DateFormFieldButton(SwEditWin* pEditWin, sw::mark::DateFieldmark& rFieldMark); + virtual ~DateFormFieldButton() override; + + virtual void InitPopup() override; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx index 6ca604a29976..6e05a171ce34 100644 --- a/sw/source/core/inc/MarkManager.hxx +++ b/sw/source/core/inc/MarkManager.hxx @@ -32,7 +32,7 @@ namespace sw { namespace mark { typedef std::unordered_map<OUString, sal_Int32> MarkBasenameMapUniqueOffset_t; - class DropDownFieldmark; + class FieldmarkWithDropDownButton; class MarkManager : virtual public IDocumentMarkAccess @@ -135,7 +135,7 @@ namespace sw { SwDoc * const m_pDoc; - sw::mark::DropDownFieldmark* m_pLastActiveFieldmark; + sw::mark::FieldmarkWithDropDownButton* m_pLastActiveFieldmark; }; } // namespace mark } diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx index 75968a5d01e1..0c7d7f8fda7d 100644 --- a/sw/source/core/inc/bookmrk.hxx +++ b/sw/source/core/inc/bookmrk.hxx @@ -29,7 +29,7 @@ #include <IMark.hxx> #include <swserv.hxx> #include <swrect.hxx> -#include "DropDownFormFieldButton.hxx" +#include "FormFieldButton.hxx" namespace com { namespace sun { @@ -258,44 +258,46 @@ namespace sw { void SetChecked(bool checked) override; }; - /// Fieldmark representing a drop-down form field. - class DropDownFieldmark + /// Fieldmark with a drop down button (e.g. this button opens the date picker for a date field) + class FieldmarkWithDropDownButton : public NonTextFieldmark { public: - DropDownFieldmark(const SwPaM& rPaM); - virtual ~DropDownFieldmark() override; + FieldmarkWithDropDownButton(const SwPaM& rPaM); + virtual ~FieldmarkWithDropDownButton() override; // This method should be called only by the portion so we can now the portion's painting area void SetPortionPaintArea(const SwRect& rPortionPaintArea); - void ShowButton(SwEditWin* pEditWin); + virtual void ShowButton(SwEditWin* pEditWin) = 0; void HideButton(); void RemoveButton(); - private: + protected: SwRect m_aPortionPaintArea; - VclPtr<DropDownFormFieldButton> m_pButton; + VclPtr<FormFieldButton> m_pButton; + }; + + /// Fieldmark representing a drop-down form field. + class DropDownFieldmark + : public FieldmarkWithDropDownButton + { + public: + DropDownFieldmark(const SwPaM& rPaM); + virtual ~DropDownFieldmark() override; + + virtual void ShowButton(SwEditWin* pEditWin) override; }; /// Fieldmark representing a date form field. class DateFieldmark - : public NonTextFieldmark + : public FieldmarkWithDropDownButton { public: DateFieldmark(const SwPaM& rPaM); virtual ~DateFieldmark() override; - // This method should be called only by the portion so we can now the portion's painting area - void SetPortionPaintArea(const SwRect& rPortionPaintArea); - - void ShowButton(SwEditWin* pEditWin); - void HideButton(); - void RemoveButton(); - - private: - SwRect m_aPortionPaintArea; - VclPtr<MenuButton> m_pButton; + virtual void ShowButton(SwEditWin* pEditWin) override; }; } } commit 36891a53581853fcadb5383fa0bd29e478721b1d Author: Tamás Zolnai <[email protected]> AuthorDate: Fri Jun 7 17:46:58 2019 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Jul 14 00:15:43 2019 +0200 MSForms: Generalize some parts of the drop-down form field's popup button We'll need a similar button for the new text-based date field. Reviewed-on: https://gerrit.libreoffice.org/75442 Reviewed-by: Tamás Zolnai <[email protected]> Tested-by: Tamás Zolnai <[email protected]> (cherry picked from commit 1d2fdd443b0d9cb6721400ab97a2073092be724b) Change-Id: I9cf69f98dae3d761d9cddfbaed138d6453af887d Reviewed-on: https://gerrit.libreoffice.org/75535 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Andras Timar <[email protected]> diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk index 492ccaf7c8a1..0a4bbe9ede39 100644 --- a/sw/Library_sw.mk +++ b/sw/Library_sw.mk @@ -154,6 +154,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\ sw/source/core/crsr/findcoll \ sw/source/core/crsr/findfmt \ sw/source/core/crsr/findtxt \ + sw/source/core/crsr/FormFieldButton \ sw/source/core/crsr/pam \ sw/source/core/crsr/paminit \ sw/source/core/crsr/swcrsr \ diff --git a/sw/source/core/crsr/DropDownFormFieldButton.cxx b/sw/source/core/crsr/DropDownFormFieldButton.cxx index 7f9b568eaabb..ad039c4779c2 100644 --- a/sw/source/core/crsr/DropDownFormFieldButton.cxx +++ b/sw/source/core/crsr/DropDownFormFieldButton.cxx @@ -8,8 +8,6 @@ */ #include <DropDownFormFieldButton.hxx> -#include <vcl/svapp.hxx> -#include <vcl/settings.hxx> #include <edtwin.hxx> #include <basegfx/color/bcolortools.hxx> #include <viewopt.hxx> @@ -124,133 +122,16 @@ IMPL_LINK(SwFieldDialog, MyListBoxHandler, ListBox&, rBox, void) DropDownFormFieldButton::DropDownFormFieldButton(SwEditWin* pEditWin, sw::mark::DropDownFieldmark& rFieldmark) - : MenuButton(pEditWin, WB_DIALOGCONTROL) - , m_rFieldmark(rFieldmark) + : FormFieldButton(pEditWin, rFieldmark) { - assert(GetParent()); - assert(dynamic_cast<SwEditWin*>(GetParent())); } DropDownFormFieldButton::~DropDownFormFieldButton() { disposeOnce(); } -void DropDownFormFieldButton::dispose() +void DropDownFormFieldButton::InitPopup() { - m_pFieldPopup.disposeAndClear(); - MenuButton::dispose(); -} - -void DropDownFormFieldButton::CalcPosAndSize(const SwRect& rPortionPaintArea) -{ - assert(GetParent()); - - Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos()); - Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize()); - - // First calculate the size of the frame around the field - int nPadding = aBoxSize.Height() / 4; - aBoxPos.MoveX(-nPadding); - aBoxPos.MoveY(-nPadding); - aBoxSize.AdjustWidth(2 * nPadding); - aBoxSize.AdjustHeight(2 * nPadding); - - m_aFieldFramePixel = tools::Rectangle(aBoxPos, aBoxSize); - - // Then extend the size with the button area - aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height()); - - SetPosSizePixel(aBoxPos, aBoxSize); -} - -void DropDownFormFieldButton::MouseButtonUp(const MouseEvent&) -{ - assert(GetParent()); - - Point aPixPos = GetPosPixel(); - aPixPos.MoveY(GetSizePixel().Height()); - m_pFieldPopup = VclPtr<SwFieldDialog>::Create(static_cast<SwEditWin*>(GetParent()), &m_rFieldmark, GetSizePixel().Width()); - m_pFieldPopup->SetPopupModeEndHdl(LINK(this, DropDownFormFieldButton, FieldPopupModeEndHdl)); - - tools::Rectangle aRect(GetParent()->OutputToScreenPixel(aPixPos), Size(0, 0)); - m_pFieldPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus); - Invalidate(); -} - -IMPL_LINK_NOARG(DropDownFormFieldButton, FieldPopupModeEndHdl, FloatingWindow*, void) -{ - m_pFieldPopup.disposeAndClear(); - m_rFieldmark.Invalidate(); - // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen - Show(false); - Invalidate(); -} - -static basegfx::BColor lcl_GetFillColor(const basegfx::BColor& rLineColor, double aLuminance) -{ - basegfx::BColor aHslLine = basegfx::utils::rgb2hsl(rLineColor); - aHslLine.setZ(aLuminance); - return basegfx::utils::hsl2rgb(aHslLine); -} - -void DropDownFormFieldButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) -{ - SetMapMode(MapMode(MapUnit::MapPixel)); - - //const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); - Color aLineColor = COL_BLACK; - Color aFillColor - = Color(lcl_GetFillColor(aLineColor.getBColor(), (m_pFieldPopup ? 0.5 : 0.75))); - - // Draw the frame around the field - // GTK3 backend cuts down the frame's top and left border, to avoid that add a padding around the frame - int nPadding = 1; - Point aPos(nPadding, nPadding); - Size aSize(m_aFieldFramePixel.GetSize().Width() - nPadding, - m_aFieldFramePixel.GetSize().Height() - nPadding); - const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize)); - rRenderContext.SetLineColor(aLineColor); - rRenderContext.SetFillColor(COL_TRANSPARENT); - rRenderContext.DrawRect(aFrameRect); - - // Draw the button next to the frame - Point aButtonPos(aFrameRect.TopLeft()); - aButtonPos.MoveX(aFrameRect.GetSize().getWidth() - 1); - Size aButtonSize(aFrameRect.GetSize()); - aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getWidth() - nPadding); - const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize)); - - // Background & border - rRenderContext.SetLineColor(aLineColor); - rRenderContext.SetFillColor(aFillColor); - rRenderContext.DrawRect(aButtonRect); - - // the arrowhead - rRenderContext.SetLineColor(aLineColor); - rRenderContext.SetFillColor(aLineColor); - - Point aCenter(aButtonPos.X() + (aButtonSize.Width() / 2), - aButtonPos.Y() + (aButtonSize.Height() / 2)); - Size aArrowSize(aButtonSize.Width() / 4, aButtonSize.Height() / 10); - - tools::Polygon aPoly(3); - aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0); - aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1); - aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2); - rRenderContext.DrawPolygon(aPoly); -} - -WindowHitTest DropDownFormFieldButton::ImplHitTest(const Point& rFramePos) -{ - // We need to check whether the position hits the button (the frame should be mouse transparent) - WindowHitTest aResult = MenuButton::ImplHitTest(rFramePos); - if (aResult != WindowHitTest::Inside) - return aResult; - else - { - return rFramePos.X() >= m_aFieldFramePixel.Right() ? WindowHitTest::Inside - : WindowHitTest::Transparent; - } } /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/core/crsr/FormFieldButton.cxx b/sw/source/core/crsr/FormFieldButton.cxx new file mode 100644 index 000000000000..7e6be08fe7bd --- /dev/null +++ b/sw/source/core/crsr/FormFieldButton.cxx @@ -0,0 +1,155 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#include <DropDownFormFieldButton.hxx> +#include <vcl/svapp.hxx> +#include <vcl/settings.hxx> +#include <edtwin.hxx> +#include <basegfx/color/bcolortools.hxx> +#include <viewopt.hxx> +#include <bookmrk.hxx> +#include <vcl/floatwin.hxx> +#include <vcl/event.hxx> +#include <vcl/lstbox.hxx> +#include <IMark.hxx> +#include <view.hxx> +#include <docsh.hxx> +#include <strings.hrc> + +FormFieldButton::FormFieldButton(SwEditWin* pEditWin, sw::mark::Fieldmark& rFieldmark) + : MenuButton(pEditWin, WB_DIALOGCONTROL) + , m_rFieldmark(rFieldmark) +{ + assert(GetParent()); + assert(dynamic_cast<SwEditWin*>(GetParent())); +} + +FormFieldButton::~FormFieldButton() { disposeOnce(); } + +void FormFieldButton::dispose() +{ + m_pFieldPopup.disposeAndClear(); + MenuButton::dispose(); +} + +void FormFieldButton::CalcPosAndSize(const SwRect& rPortionPaintArea) +{ + assert(GetParent()); + + Point aBoxPos = GetParent()->LogicToPixel(rPortionPaintArea.Pos()); + Size aBoxSize = GetParent()->LogicToPixel(rPortionPaintArea.SSize()); + + // First calculate the size of the frame around the field + int nPadding = aBoxSize.Height() / 4; + aBoxPos.MoveX(-nPadding); + aBoxPos.MoveY(-nPadding); + aBoxSize.AdjustWidth(2 * nPadding); + aBoxSize.AdjustHeight(2 * nPadding); + + m_aFieldFramePixel = tools::Rectangle(aBoxPos, aBoxSize); + + // Then extend the size with the button area + aBoxSize.AdjustWidth(GetParent()->LogicToPixel(rPortionPaintArea.SSize()).Height()); + + SetPosSizePixel(aBoxPos, aBoxSize); +} + +void FormFieldButton::MouseButtonUp(const MouseEvent&) +{ + assert(GetParent()); + + Point aPixPos = GetPosPixel(); + aPixPos.MoveY(GetSizePixel().Height()); + + // sets m_pFieldPopup + InitPopup(); + + m_pFieldPopup->SetPopupModeEndHdl(LINK(this, DropDownFormFieldButton, FieldPopupModeEndHdl)); + + tools::Rectangle aRect(GetParent()->OutputToScreenPixel(aPixPos), Size(0, 0)); + m_pFieldPopup->StartPopupMode(aRect, FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus); + Invalidate(); +} + +IMPL_LINK_NOARG(FormFieldButton, FieldPopupModeEndHdl, FloatingWindow*, void) +{ + m_pFieldPopup.disposeAndClear(); + m_rFieldmark.Invalidate(); + // Hide the button here and make it visible later, to make transparent background work with SAL_USE_VCLPLUGIN=gen + Show(false); + Invalidate(); +} + +static basegfx::BColor lcl_GetFillColor(const basegfx::BColor& rLineColor, double aLuminance) +{ + basegfx::BColor aHslLine = basegfx::utils::rgb2hsl(rLineColor); + aHslLine.setZ(aLuminance); + return basegfx::utils::hsl2rgb(aHslLine); +} + +void FormFieldButton::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle&) +{ + SetMapMode(MapMode(MapUnit::MapPixel)); + + //const StyleSettings& rSettings = Application::GetSettings().GetStyleSettings(); + Color aLineColor = COL_BLACK; + Color aFillColor(lcl_GetFillColor(aLineColor.getBColor(), (m_pFieldPopup ? 0.5 : 0.75))); + + // Draw the frame around the field + // GTK3 backend cuts down the frame's top and left border, to avoid that add a padding around the frame + int nPadding = 1; + Point aPos(nPadding, nPadding); + Size aSize(m_aFieldFramePixel.GetSize().Width() - nPadding, + m_aFieldFramePixel.GetSize().Height() - nPadding); + const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize)); + rRenderContext.SetLineColor(aLineColor); + rRenderContext.SetFillColor(COL_TRANSPARENT); + rRenderContext.DrawRect(aFrameRect); + + // Draw the button next to the frame + Point aButtonPos(aFrameRect.TopLeft()); + aButtonPos.MoveX(aFrameRect.GetSize().getWidth() - 1); + Size aButtonSize(aFrameRect.GetSize()); + aButtonSize.setWidth(GetSizePixel().getWidth() - aFrameRect.getWidth() - nPadding); + const tools::Rectangle aButtonRect(tools::Rectangle(aButtonPos, aButtonSize)); + + // Background & border + rRenderContext.SetLineColor(aLineColor); + rRenderContext.SetFillColor(aFillColor); + rRenderContext.DrawRect(aButtonRect); + + // the arrowhead + rRenderContext.SetLineColor(aLineColor); + rRenderContext.SetFillColor(aLineColor); + + Point aCenter(aButtonPos.X() + (aButtonSize.Width() / 2), + aButtonPos.Y() + (aButtonSize.Height() / 2)); + Size aArrowSize(aButtonSize.Width() / 4, aButtonSize.Height() / 10); + + tools::Polygon aPoly(3); + aPoly.SetPoint(Point(aCenter.X() - aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 0); + aPoly.SetPoint(Point(aCenter.X() + aArrowSize.Width(), aCenter.Y() - aArrowSize.Height()), 1); + aPoly.SetPoint(Point(aCenter.X(), aCenter.Y() + aArrowSize.Height()), 2); + rRenderContext.DrawPolygon(aPoly); +} + +WindowHitTest FormFieldButton::ImplHitTest(const Point& rFramePos) +{ + // We need to check whether the position hits the button (the frame should be mouse transparent) + WindowHitTest aResult = MenuButton::ImplHitTest(rFramePos); + if (aResult != WindowHitTest::Inside) + return aResult; + else + { + return rFramePos.X() >= m_aFieldFramePixel.Right() ? WindowHitTest::Inside + : WindowHitTest::Transparent; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/sw/source/core/inc/DropDownFormFieldButton.hxx b/sw/source/core/inc/DropDownFormFieldButton.hxx index 1013ef177580..482e49f8b542 100644 --- a/sw/source/core/inc/DropDownFormFieldButton.hxx +++ b/sw/source/core/inc/DropDownFormFieldButton.hxx @@ -12,6 +12,7 @@ #include <vcl/menubtn.hxx> #include <swrect.hxx> +#include "FormFieldButton.hxx" class SwFieldFormDropDownPortion; class SwEditWin; @@ -25,28 +26,16 @@ class DropDownFieldmark; } // namespace sw /** - * This button is shown when the cursor is in a drop-down form field. + * This button is shown when the cursor is on a drop-down form field. * The user can select an item of the field using this button while filling in a form. */ -class DropDownFormFieldButton : public MenuButton +class DropDownFormFieldButton : public FormFieldButton { public: DropDownFormFieldButton(SwEditWin* pEditWin, sw::mark::DropDownFieldmark& rFieldMark); virtual ~DropDownFormFieldButton() override; - virtual void dispose() override; - void CalcPosAndSize(const SwRect& rPortionPaintArea); - - virtual void MouseButtonUp(const MouseEvent& rMEvt) override; - DECL_LINK(FieldPopupModeEndHdl, FloatingWindow*, void); - - virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; - virtual WindowHitTest ImplHitTest(const Point& rFramePos) override; - -private: - tools::Rectangle m_aFieldFramePixel; - sw::mark::DropDownFieldmark& m_rFieldmark; - VclPtr<FloatingWindow> m_pFieldPopup; + virtual void InitPopup() override; }; #endif diff --git a/sw/source/core/inc/FormFieldButton.hxx b/sw/source/core/inc/FormFieldButton.hxx new file mode 100644 index 000000000000..987d86d15d70 --- /dev/null +++ b/sw/source/core/inc/FormFieldButton.hxx @@ -0,0 +1,56 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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/. + */ + +#ifndef INCLUDED_SW_SOURCE_CORE_TEXT_FORMEFIELDBUTTO_HXX +#define INCLUDED_SW_SOURCE_CORE_TEXT_FORMEFIELDBUTTO_HXX + +#include <vcl/menubtn.hxx> +#include <swrect.hxx> + +class SwEditWin; +class FloatingWindow; +namespace sw +{ +namespace mark +{ +class Fieldmark; +} +} // namespace sw + +/** + * This button is shown when the cursor is on a form field with drop-down capability. + */ +class FormFieldButton : public MenuButton +{ +public: + FormFieldButton(SwEditWin* pEditWin, sw::mark::Fieldmark& rFieldMark); + virtual ~FormFieldButton() override; + virtual void dispose() override; + + void CalcPosAndSize(const SwRect& rPortionPaintArea); + + virtual void MouseButtonUp(const MouseEvent& rMEvt) override; + DECL_LINK(FieldPopupModeEndHdl, FloatingWindow*, void); + + virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override; + virtual WindowHitTest ImplHitTest(const Point& rFramePos) override; + + virtual void InitPopup() = 0; + +private: + tools::Rectangle m_aFieldFramePixel; + +protected: + sw::mark::Fieldmark& m_rFieldmark; + VclPtr<FloatingWindow> m_pFieldPopup; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ commit e1ee967defea0371d5013d75d193cffa6f6acdb9 Author: Tamás Zolnai <[email protected]> AuthorDate: Fri Jun 7 17:18:52 2019 +0200 Commit: Andras Timar <[email protected]> CommitDate: Sun Jul 14 00:15:33 2019 +0200 MSForms: Better rendering of drop-down form field's button Change-Id: If5ab1b2a9dd8d68cc89b4c6ba8f3b32d7f006c1c Reviewed-on: https://gerrit.libreoffice.org/75441 Tested-by: Jenkins Reviewed-by: Tamás Zolnai <[email protected]> (cherry picked from commit a9ce5e5fc5188a0c776ba4cff9d5ac84a2bcd7a5) Reviewed-on: https://gerrit.libreoffice.org/75534 Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Andras Timar <[email protected]> diff --git a/sw/source/core/crsr/DropDownFormFieldButton.cxx b/sw/source/core/crsr/DropDownFormFieldButton.cxx index 17bdbc5ab07c..7f9b568eaabb 100644 --- a/sw/source/core/crsr/DropDownFormFieldButton.cxx +++ b/sw/source/core/crsr/DropDownFormFieldButton.cxx @@ -207,7 +207,7 @@ void DropDownFormFieldButton::Paint(vcl::RenderContext& rRenderContext, const to int nPadding = 1; Point aPos(nPadding, nPadding); Size aSize(m_aFieldFramePixel.GetSize().Width() - nPadding, - m_aFieldFramePixel.GetSize().Height() - 2 * nPadding); + m_aFieldFramePixel.GetSize().Height() - nPadding); const tools::Rectangle aFrameRect(tools::Rectangle(aPos, aSize)); rRenderContext.SetLineColor(aLineColor); rRenderContext.SetFillColor(COL_TRANSPARENT); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
