summaryrefslogtreecommitdiffstats
path: root/svx/source/tbxctrls/fillctrl.cxx
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--svx/source/tbxctrls/fillctrl.cxx1087
1 files changed, 1087 insertions, 0 deletions
diff --git a/svx/source/tbxctrls/fillctrl.cxx b/svx/source/tbxctrls/fillctrl.cxx
new file mode 100644
index 000000000..cfb7583be
--- /dev/null
+++ b/svx/source/tbxctrls/fillctrl.cxx
@@ -0,0 +1,1087 @@
+/* -*- 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 <sfx2/dispatch.hxx>
+#include <sfx2/objsh.hxx>
+#include <sfx2/viewsh.hxx>
+#include <rtl/ustring.hxx>
+#include <vcl/event.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/toolbox.hxx>
+#include <vcl/virdev.hxx>
+#include <svx/svxids.hrc>
+#include <tools/json_writer.hxx>
+
+constexpr OUStringLiteral TMP_STR_BEGIN = u"[";
+constexpr OUStringLiteral TMP_STR_END = u"]";
+
+#include <svx/drawitem.hxx>
+#include <svx/xfillit0.hxx>
+#include <svx/xtable.hxx>
+#include <svx/fillctrl.hxx>
+#include <svx/itemwin.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xflgrit.hxx>
+#include <svx/xflhtit.hxx>
+#include <svx/xbtmpit.hxx>
+#include <memory>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::util;
+using namespace ::com::sun::star::beans;
+using namespace ::com::sun::star::lang;
+
+namespace {
+
+enum eFillStyle
+{
+ NONE,
+ SOLID,
+ GRADIENT,
+ HATCH,
+ BITMAP,
+ PATTERN
+};
+
+drawing::FillStyle toCssFillStyle( eFillStyle eXFS )
+{
+ if (eXFS == PATTERN)
+ {
+ return drawing::FillStyle_BITMAP;
+ }
+
+ return static_cast<drawing::FillStyle>(eXFS);
+}
+
+}
+
+SFX_IMPL_TOOLBOX_CONTROL( SvxFillToolBoxControl, XFillStyleItem );
+
+SvxFillToolBoxControl::SvxFillToolBoxControl(
+ sal_uInt16 nSlotId,
+ ToolBoxItemId nId,
+ ToolBox& rTbx )
+ : SfxToolBoxControl( nSlotId, nId, rTbx )
+ , mxFillControl(nullptr)
+ , mpLbFillType(nullptr)
+ , mpToolBoxColor(nullptr)
+ , mpLbFillAttr(nullptr)
+ , mnLastXFS(-1)
+ , mnLastPosGradient(0)
+ , mnLastPosHatch(0)
+ , mnLastPosBitmap(0)
+ , mnLastPosPattern(0)
+{
+ addStatusListener( ".uno:FillColor");
+ addStatusListener( ".uno:FillGradient");
+ addStatusListener( ".uno:FillHatch");
+ addStatusListener( ".uno:FillBitmap");
+ addStatusListener( ".uno:ColorTableState");
+ addStatusListener( ".uno:GradientListState");
+ addStatusListener( ".uno:HatchListState");
+ addStatusListener( ".uno:BitmapListState");
+}
+
+SvxFillToolBoxControl::~SvxFillToolBoxControl()
+{
+}
+
+void SvxFillToolBoxControl::StateChangedAtToolBoxControl(
+ sal_uInt16 nSID,
+ SfxItemState eState,
+ const SfxPoolItem* pState)
+{
+ const bool bDisabled(SfxItemState::DISABLED == eState);
+
+ switch(nSID)
+ {
+ case SID_ATTR_FILL_STYLE:
+ {
+ if(bDisabled)
+ {
+ mpLbFillType->set_sensitive(false);
+ mpLbFillType->set_active(-1);
+ mpLbFillAttr->show();
+ mpLbFillAttr->set_sensitive(false);
+ mpLbFillAttr->set_active(-1);
+ mpToolBoxColor->hide();
+ mnLastXFS = -1;
+ mpStyleItem.reset();
+ }
+
+ if(eState >= SfxItemState::DEFAULT)
+ {
+ const XFillStyleItem* pItem = dynamic_cast< const XFillStyleItem* >(pState);
+
+ if(pItem)
+ {
+ mpStyleItem.reset(pItem->Clone());
+ mpLbFillType->set_sensitive(true);
+ drawing::FillStyle eXFS = mpStyleItem->GetValue();
+ mnLastXFS = sal::static_int_cast< sal_Int32 >(eXFS);
+ mpLbFillType->set_active(mnLastXFS);
+
+ if(drawing::FillStyle_NONE == eXFS)
+ {
+ mpLbFillAttr->set_active(-1);
+ mpLbFillAttr->set_sensitive(false);
+ }
+
+ Update();
+ break;
+ }
+ }
+
+ mpLbFillType->set_active(-1);
+ mpLbFillAttr->show();
+ mpLbFillAttr->set_sensitive(false);
+ mpLbFillAttr->set_active(-1);
+ mpToolBoxColor->hide();
+ mnLastXFS = -1;
+ mpStyleItem.reset();
+ mxFillControl->Resize();
+ break;
+ }
+ case SID_ATTR_FILL_COLOR:
+ {
+ if(SfxItemState::DEFAULT == eState)
+ {
+ mpColorItem.reset(pState ? static_cast<XFillColorItem*>(pState->Clone()) : nullptr);
+ }
+
+ if(mpStyleItem && drawing::FillStyle_SOLID == mpStyleItem->GetValue())
+ {
+ mpLbFillAttr->hide();
+ mpToolBoxColor->show();
+ mxFillControl->Resize();
+
+ Update();
+ }
+ break;
+ }
+ case SID_ATTR_FILL_GRADIENT:
+ {
+ if(SfxItemState::DEFAULT == eState)
+ {
+ mpFillGradientItem.reset(pState ? static_cast<XFillGradientItem*>(pState->Clone()) : nullptr);
+ }
+
+ if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+ mxFillControl->Resize();
+
+ if(SfxItemState::DEFAULT == eState)
+ {
+ mpLbFillAttr->set_sensitive(true);
+ Update();
+ }
+ else if(SfxItemState::DISABLED == eState )
+ {
+ mpLbFillAttr->set_sensitive(false);
+ mpLbFillAttr->set_active(-1);
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ }
+ break;
+ }
+ case SID_ATTR_FILL_HATCH:
+ {
+ if(SfxItemState::DEFAULT == eState)
+ {
+ mpHatchItem.reset(pState ? static_cast<XFillHatchItem*>(pState->Clone()) : nullptr);
+ }
+
+ if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+ mxFillControl->Resize();
+
+ if(SfxItemState::DEFAULT == eState)
+ {
+ mpLbFillAttr->set_sensitive(true);
+ Update();
+ }
+ else if(SfxItemState::DISABLED == eState )
+ {
+ mpLbFillAttr->set_sensitive(false);
+ mpLbFillAttr->set_active(-1);
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ }
+ break;
+ }
+ case SID_ATTR_FILL_BITMAP:
+ {
+ if(SfxItemState::DEFAULT == eState)
+ {
+ mpBitmapItem.reset(pState ? static_cast<XFillBitmapItem*>(pState->Clone()) : nullptr);
+ }
+
+ if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+ mxFillControl->Resize();
+
+ if(SfxItemState::DEFAULT == eState)
+ {
+ mpLbFillAttr->set_sensitive(true);
+ Update();
+ }
+ else if(SfxItemState::DISABLED == eState )
+ {
+ mpLbFillAttr->set_sensitive(false);
+ mpLbFillAttr->set_active(-1);
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ }
+ break;
+ }
+ case SID_GRADIENT_LIST:
+ {
+ if(SfxItemState::DEFAULT == eState)
+ {
+ if(mpStyleItem && drawing::FillStyle_GRADIENT == mpStyleItem->GetValue())
+ {
+ if(mpFillGradientItem)
+ {
+ const OUString aString( mpFillGradientItem->GetName() );
+ mpLbFillAttr->clear();
+ if (const SfxObjectShell* pSh = SfxObjectShell::Current())
+ {
+ mpLbFillAttr->set_sensitive(true);
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
+ }
+ mpLbFillAttr->set_active_text(aString);
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ }
+ }
+ break;
+ }
+ case SID_HATCH_LIST:
+ {
+ if(SfxItemState::DEFAULT == eState)
+ {
+ if(mpStyleItem && drawing::FillStyle_HATCH == mpStyleItem->GetValue())
+ {
+ if(mpHatchItem)
+ {
+ const OUString aString( mpHatchItem->GetName() );
+ mpLbFillAttr->clear();
+ if (const SfxObjectShell* pSh = SfxObjectShell::Current())
+ {
+ mpLbFillAttr->set_sensitive(true);
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
+ }
+ mpLbFillAttr->set_active_text(aString);
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ }
+ }
+ break;
+ }
+ case SID_BITMAP_LIST:
+ {
+ if(SfxItemState::DEFAULT == eState)
+ {
+ if(mpStyleItem && drawing::FillStyle_BITMAP == mpStyleItem->GetValue())
+ {
+ if(mpBitmapItem)
+ {
+ const OUString aString( mpBitmapItem->GetName() );
+ mpLbFillAttr->clear();
+ if (const SfxObjectShell* pSh = SfxObjectShell::Current())
+ {
+ mpLbFillAttr->set_sensitive(true);
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
+ }
+ mpLbFillAttr->set_active_text(aString);
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+void SvxFillToolBoxControl::Update()
+{
+ if(!mpStyleItem)
+ return;
+
+ const drawing::FillStyle eXFS = mpStyleItem->GetValue();
+ SfxObjectShell* pSh = SfxObjectShell::Current();
+
+ switch( eXFS )
+ {
+ case drawing::FillStyle_NONE:
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+ mxFillControl->Resize();
+ break;
+ }
+ case drawing::FillStyle_SOLID:
+ {
+ if(mpColorItem)
+ {
+ mpLbFillAttr->hide();
+ mpToolBoxColor->show();
+ mxFillControl->Resize();
+ }
+ break;
+ }
+ case drawing::FillStyle_GRADIENT:
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+ mxFillControl->Resize();
+
+ if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
+ {
+ mpLbFillAttr->set_sensitive(true);
+ mpLbFillAttr->clear();
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
+
+ if(mpFillGradientItem)
+ {
+ const OUString aString(mpFillGradientItem->GetName());
+
+ mpLbFillAttr->set_active_text(aString);
+
+ // Check if the entry is not in the list
+ if (mpLbFillAttr->get_active_text() != aString)
+ {
+ sal_Int32 nCount = mpLbFillAttr->get_count();
+ OUString aTmpStr;
+ if( nCount > 0 )
+ {
+ // Last entry gets tested against temporary entry
+ aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
+ if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
+ aTmpStr.endsWith(TMP_STR_END) )
+ {
+ mpLbFillAttr->remove(nCount - 1);
+ }
+ }
+ aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
+
+ rtl::Reference<XGradientList> xGradientList = new XGradientList( "", ""/*TODO?*/ );
+ xGradientList->Insert(std::make_unique<XGradientEntry>(mpFillGradientItem->GetGradientValue(), aTmpStr));
+ xGradientList->SetDirty( false );
+ const BitmapEx aBmp = xGradientList->GetUiBitmap( 0 );
+
+ if (!aBmp.IsEmpty())
+ {
+ ScopedVclPtrInstance< VirtualDevice > pVD;
+ const Size aBmpSize(aBmp.GetSizePixel());
+ pVD->SetOutputSizePixel(aBmpSize, false);
+ pVD->DrawBitmapEx(Point(), aBmp);
+ mpLbFillAttr->append("", xGradientList->Get(0)->GetName(), *pVD);
+ mpLbFillAttr->set_active(mpLbFillAttr->get_count() - 1);
+ }
+ }
+
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ break;
+ }
+ case drawing::FillStyle_HATCH:
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+ mxFillControl->Resize();
+
+ if(pSh && pSh->GetItem(SID_HATCH_LIST))
+ {
+ mpLbFillAttr->set_sensitive(true);
+ mpLbFillAttr->clear();
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
+
+ if(mpHatchItem)
+ {
+ const OUString aString(mpHatchItem->GetName());
+
+ mpLbFillAttr->set_active_text( aString );
+
+ // Check if the entry is not in the list
+ if( mpLbFillAttr->get_active_text() != aString )
+ {
+ const sal_Int32 nCount = mpLbFillAttr->get_count();
+ OUString aTmpStr;
+ if( nCount > 0 )
+ {
+ // Last entry gets tested against temporary entry
+ aTmpStr = mpLbFillAttr->get_text( nCount - 1 );
+ if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
+ aTmpStr.endsWith(TMP_STR_END) )
+ {
+ mpLbFillAttr->remove( nCount - 1 );
+ }
+ }
+ aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
+
+ rtl::Reference<XHatchList> xHatchList = new XHatchList( "", ""/*TODO?*/ );
+ xHatchList->Insert(std::make_unique<XHatchEntry>(mpHatchItem->GetHatchValue(), aTmpStr));
+ xHatchList->SetDirty( false );
+ const BitmapEx & aBmp = xHatchList->GetUiBitmap( 0 );
+
+ if( !aBmp.IsEmpty() )
+ {
+ ScopedVclPtrInstance< VirtualDevice > pVD;
+ const Size aBmpSize(aBmp.GetSizePixel());
+ pVD->SetOutputSizePixel(aBmpSize, false);
+ pVD->DrawBitmapEx(Point(), aBmp);
+ mpLbFillAttr->append("", xHatchList->GetHatch(0)->GetName(), *pVD);
+ mpLbFillAttr->set_active(mpLbFillAttr->get_count() - 1);
+ }
+ }
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ break;
+ }
+ case drawing::FillStyle_BITMAP:
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+ mxFillControl->Resize();
+
+ if(pSh)
+ {
+ mpLbFillAttr->set_sensitive(true);
+ mpLbFillAttr->clear();
+
+ if(mpBitmapItem && !mpBitmapItem->isPattern() && pSh->GetItem(SID_BITMAP_LIST))
+ {
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
+
+ const OUString aString(mpBitmapItem->GetName());
+
+ mpLbFillAttr->set_active_text(aString);
+
+ // Check if the entry is not in the list
+ if (mpLbFillAttr->get_active_text() != aString)
+ {
+ sal_Int32 nCount = mpLbFillAttr->get_count();
+ OUString aTmpStr;
+ if( nCount > 0 )
+ {
+ // Last entry gets tested against temporary entry
+ aTmpStr = mpLbFillAttr->get_text(nCount - 1);
+ if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
+ aTmpStr.endsWith(TMP_STR_END) )
+ {
+ mpLbFillAttr->remove(nCount - 1);
+ }
+ }
+ aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
+
+ XBitmapListRef xBitmapList =
+ XPropertyList::AsBitmapList(
+ XPropertyList::CreatePropertyList(
+ XPropertyListType::Bitmap, "TmpList", ""/*TODO?*/));
+ xBitmapList->Insert(std::make_unique<XBitmapEntry>(mpBitmapItem->GetGraphicObject(), aTmpStr));
+ xBitmapList->SetDirty( false );
+ SvxFillAttrBox::Fill(*mpLbFillAttr, xBitmapList);
+ mpLbFillAttr->set_active(mpLbFillAttr->get_count() - 1);
+ }
+
+ }
+ else if (mpBitmapItem && mpBitmapItem->isPattern() && pSh->GetItem(SID_PATTERN_LIST))
+ {
+ mnLastXFS = sal::static_int_cast<sal_Int32>(PATTERN);
+ mpLbFillType->set_active(mnLastXFS);
+
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList());
+ const OUString aString(mpBitmapItem->GetName());
+
+ mpLbFillAttr->set_active_text(aString);
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ }
+ else
+ {
+ mpLbFillAttr->set_active(-1);
+ }
+ break;
+ }
+ default:
+ OSL_ENSURE(false, "Non supported FillType (!)");
+ break;
+ }
+
+}
+
+VclPtr<InterimItemWindow> SvxFillToolBoxControl::CreateItemWindow(vcl::Window *pParent)
+{
+ if(GetSlotId() == SID_ATTR_FILL_STYLE)
+ {
+ mxFillControl.reset(VclPtr<FillControl>::Create(pParent, m_xFrame));
+
+ mpLbFillType = mxFillControl->mxLbFillType.get();
+ mpLbFillAttr = mxFillControl->mxLbFillAttr.get();
+ mpToolBoxColor = mxFillControl->mxToolBoxColor.get();
+
+ mpLbFillType->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillTypeHdl));
+ mpLbFillAttr->connect_changed(LINK(this,SvxFillToolBoxControl,SelectFillAttrHdl));
+
+
+ return mxFillControl;
+ }
+ return VclPtr<InterimItemWindow>();
+}
+
+FillControl::FillControl(vcl::Window* pParent, const css::uno::Reference<css::frame::XFrame>& rFrame)
+ : InterimItemWindow(pParent, "svx/ui/fillctrlbox.ui", "FillCtrlBox")
+ , mxLbFillType(m_xBuilder->weld_combo_box("type"))
+ , mxToolBoxColor(m_xBuilder->weld_toolbar("color"))
+ , mxColorDispatch(new ToolbarUnoDispatcher(*mxToolBoxColor, *m_xBuilder, rFrame))
+ , mxLbFillAttr(m_xBuilder->weld_combo_box("attr"))
+ , mnTypeCurPos(0)
+ , mnAttrCurPos(0)
+{
+ InitControlBase(mxLbFillType.get());
+
+ mxLbFillAttr->connect_key_press(LINK(this, FillControl, AttrKeyInputHdl));
+ mxLbFillType->connect_key_press(LINK(this, FillControl, TypeKeyInputHdl));
+ mxToolBoxColor->connect_key_press(LINK(this, FillControl, ColorKeyInputHdl));
+
+ mxLbFillType->connect_get_property_tree(LINK(this, FillControl, DumpAsPropertyTreeHdl));
+
+ mxLbFillType->connect_focus_in(LINK(this, FillControl, TypeFocusHdl));
+ mxLbFillAttr->connect_focus_in(LINK(this, FillControl, AttrFocusHdl));
+
+ SvxFillTypeBox::Fill(*mxLbFillType);
+
+ SetOptimalSize();
+}
+
+IMPL_STATIC_LINK(FillControl, DumpAsPropertyTreeHdl, tools::JsonWriter&, rJsonWriter, void)
+{
+ rJsonWriter.put("command", ".uno:FillStyle");
+}
+
+void FillControl::ReleaseFocus_Impl()
+{
+ SfxViewShell* pCurSh = SfxViewShell::Current();
+ if (pCurSh)
+ {
+ vcl::Window* pShellWnd = pCurSh->GetWindow();
+ if (pShellWnd)
+ pShellWnd->GrabFocus();
+ }
+}
+
+IMPL_LINK(FillControl, TypeKeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ sal_uInt16 nCode = rKeyCode.GetCode();
+
+ if (nCode == KEY_ESCAPE)
+ {
+ mxLbFillType->set_active(mnTypeCurPos);
+ ReleaseFocus_Impl();
+ return true;
+ }
+
+ if (nCode != KEY_TAB)
+ return false;
+ if (rKeyCode.IsShift())
+ return ChildKeyInput(rKEvt);
+ if (mxLbFillAttr->get_visible() && !mxLbFillAttr->get_sensitive())
+ return ChildKeyInput(rKEvt);
+ return false;
+}
+
+IMPL_LINK_NOARG(FillControl, TypeFocusHdl, weld::Widget&, void)
+{
+ mnTypeCurPos = mxLbFillType->get_active();
+}
+
+IMPL_LINK_NOARG(FillControl, AttrFocusHdl, weld::Widget&, void)
+{
+ mnAttrCurPos = mxLbFillAttr->get_active();
+}
+
+IMPL_LINK(FillControl, AttrKeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ sal_uInt16 nCode = rKeyCode.GetCode();
+
+ if (nCode == KEY_ESCAPE)
+ {
+ mxLbFillAttr->set_active(mnAttrCurPos);
+ ReleaseFocus_Impl();
+ return true;
+ }
+
+ return ChildKeyInput(rKEvt);
+}
+
+IMPL_LINK(FillControl, ColorKeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ return ChildKeyInput(rKEvt);
+}
+
+FillControl::~FillControl()
+{
+ disposeOnce();
+}
+
+void FillControl::dispose()
+{
+ mxLbFillAttr.reset();
+ mxColorDispatch.reset();
+ mxToolBoxColor.reset();
+ mxLbFillType.reset();
+ InterimItemWindow::dispose();
+}
+
+IMPL_LINK_NOARG(SvxFillToolBoxControl, SelectFillTypeHdl, weld::ComboBox&, void)
+{
+ sal_Int32 nXFS = mpLbFillType->get_active();
+
+ if(mnLastXFS == nXFS)
+ return;
+
+ eFillStyle eXFS = static_cast<eFillStyle>(nXFS);
+ mpLbFillAttr->clear();
+ SfxObjectShell* pSh = SfxObjectShell::Current();
+ const XFillStyleItem aXFillStyleItem(toCssFillStyle(eXFS));
+
+ // #i122676# Do no longer trigger two Execute calls, one for SID_ATTR_FILL_STYLE
+ // and one for setting the fill attribute itself, but add two SfxPoolItems to the
+ // call to get just one action at the SdrObject and to create only one Undo action, too.
+ // Checked that this works in all apps.
+ switch( eXFS )
+ {
+ default:
+ case NONE:
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+ mpLbFillAttr->set_sensitive(false);
+ if (pSh)
+ {
+ // #i122676# need to call a single SID_ATTR_FILL_STYLE change
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
+ { &aXFillStyleItem });
+ }
+ break;
+ }
+ case SOLID:
+ {
+ mpLbFillAttr->hide();
+ mpToolBoxColor->show();
+ if (pSh)
+ {
+ const ::Color aColor = mpColorItem ? mpColorItem->GetColorValue() : COL_AUTO;
+ const XFillColorItem aXFillColorItem( "", aColor );
+
+ // #i122676# change FillStyle and Color in one call
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_COLOR, SfxCallMode::RECORD,
+ { &aXFillColorItem, &aXFillStyleItem });
+ }
+ break;
+ }
+ case GRADIENT:
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+
+ if(pSh && pSh->GetItem(SID_GRADIENT_LIST))
+ {
+ if(!mpLbFillAttr->get_count())
+ {
+ mpLbFillAttr->set_sensitive(true);
+ mpLbFillAttr->clear();
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_GRADIENT_LIST)->GetGradientList());
+ }
+
+ if (mnLastPosGradient != -1)
+ {
+ const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
+
+ if(mnLastPosGradient < pItem->GetGradientList()->Count())
+ {
+ const XGradient aGradient = pItem->GetGradientList()->GetGradient(mnLastPosGradient)->GetGradient();
+ const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_text(mnLastPosGradient), aGradient);
+
+ // #i122676# change FillStyle and Gradient in one call
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
+ { &aXFillGradientItem, &aXFillStyleItem });
+ mpLbFillAttr->set_active(mnLastPosGradient);
+ }
+ }
+ }
+ else
+ {
+ mpLbFillAttr->set_sensitive(false);
+ }
+ break;
+ }
+ case HATCH:
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+
+ if(pSh && pSh->GetItem(SID_HATCH_LIST))
+ {
+ if(!mpLbFillAttr->get_count())
+ {
+ mpLbFillAttr->set_sensitive(true);
+ mpLbFillAttr->clear();
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_HATCH_LIST)->GetHatchList());
+ }
+
+ if (mnLastPosHatch != -1)
+ {
+ const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
+
+ if(mnLastPosHatch < pItem->GetHatchList()->Count())
+ {
+ const XHatch aHatch = pItem->GetHatchList()->GetHatch(mnLastPosHatch)->GetHatch();
+ const XFillHatchItem aXFillHatchItem(mpLbFillAttr->get_active_text(), aHatch);
+
+ // #i122676# change FillStyle and Hatch in one call
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
+ { &aXFillHatchItem, &aXFillStyleItem });
+ mpLbFillAttr->set_active(mnLastPosHatch);
+ }
+ }
+ }
+ else
+ {
+ mpLbFillAttr->set_sensitive(false);
+ }
+ break;
+ }
+ case BITMAP:
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+
+ if(pSh && pSh->GetItem(SID_BITMAP_LIST))
+ {
+ if(!mpLbFillAttr->get_count())
+ {
+ mpLbFillAttr->set_sensitive(true);
+ mpLbFillAttr->clear();
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_BITMAP_LIST)->GetBitmapList());
+ }
+
+ if (mnLastPosBitmap != -1)
+ {
+ const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
+
+ if(mnLastPosBitmap < pItem->GetBitmapList()->Count())
+ {
+ const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(mnLastPosBitmap);
+ const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
+
+ // #i122676# change FillStyle and Bitmap in one call
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
+ { &aXFillBitmapItem, &aXFillStyleItem });
+ mpLbFillAttr->set_active(mnLastPosBitmap);
+ }
+ }
+ }
+ else
+ {
+ mpLbFillAttr->set_sensitive(false);
+ }
+ break;
+ }
+ case PATTERN:
+ {
+ mpLbFillAttr->show();
+ mpToolBoxColor->hide();
+
+ if(pSh && pSh->GetItem(SID_PATTERN_LIST))
+ {
+ if(!mpLbFillAttr->get_count())
+ {
+ mpLbFillAttr->set_sensitive(true);
+ mpLbFillAttr->clear();
+ SvxFillAttrBox::Fill(*mpLbFillAttr, pSh->GetItem(SID_PATTERN_LIST)->GetPatternList());
+ }
+
+ if (mnLastPosPattern != -1)
+ {
+ const SvxPatternListItem * pItem = pSh->GetItem(SID_PATTERN_LIST);
+
+ if(mnLastPosPattern < pItem->GetPatternList()->Count())
+ {
+ const XBitmapEntry* pXBitmapEntry = pItem->GetPatternList()->GetBitmap(mnLastPosPattern);
+ const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
+
+ // #i122676# change FillStyle and Bitmap in one call
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
+ { &aXFillBitmapItem, &aXFillStyleItem });
+ mpLbFillAttr->set_active(mnLastPosPattern);
+ }
+ }
+ }
+ else
+ {
+ mpLbFillAttr->set_sensitive(false);
+ }
+ break;
+ }
+
+ }
+
+ mnLastXFS = nXFS;
+
+ mxFillControl->Resize();
+}
+
+IMPL_LINK_NOARG(SvxFillToolBoxControl, SelectFillAttrHdl, weld::ComboBox&, void)
+{
+ sal_Int32 nXFS = mpLbFillType->get_active();
+ eFillStyle eXFS = static_cast<eFillStyle>(nXFS);
+
+ const XFillStyleItem aXFillStyleItem(toCssFillStyle(eXFS));
+ SfxObjectShell* pSh = SfxObjectShell::Current();
+
+ // #i122676# dependent from bFillStyleChange, do execute a single or two
+ // changes in one Execute call
+ const bool bFillStyleChange(mnLastXFS != nXFS);
+
+ switch (eXFS)
+ {
+ case SOLID:
+ {
+ if (bFillStyleChange && pSh)
+ {
+ // #i122676# Single FillStyle change call needed here
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_STYLE, SfxCallMode::RECORD,
+ { &aXFillStyleItem });
+ }
+ break;
+ }
+ case GRADIENT:
+ {
+ sal_Int32 nPos = mpLbFillAttr->get_active();
+
+ if (nPos == -1)
+ {
+ nPos = mnLastPosGradient;
+ }
+
+ if (nPos != -1 && pSh && pSh->GetItem(SID_GRADIENT_LIST))
+ {
+ const SvxGradientListItem * pItem = pSh->GetItem(SID_GRADIENT_LIST);
+
+ if(nPos < pItem->GetGradientList()->Count())
+ {
+ const XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
+ const XFillGradientItem aXFillGradientItem(mpLbFillAttr->get_active_text(), aGradient);
+
+ // #i122676# Change FillStyle and Gradient in one call
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_GRADIENT, SfxCallMode::RECORD,
+ bFillStyleChange
+ ? std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem, &aXFillStyleItem }
+ : std::initializer_list<SfxPoolItem const*>{ &aXFillGradientItem });
+ }
+ }
+
+ if (nPos != -1)
+ {
+ mnLastPosGradient = nPos;
+ }
+ break;
+ }
+ case HATCH:
+ {
+ sal_Int32 nPos = mpLbFillAttr->get_active();
+
+ if (nPos == -1)
+ {
+ nPos = mnLastPosHatch;
+ }
+
+ if (nPos != -1 && pSh && pSh->GetItem(SID_HATCH_LIST))
+ {
+ const SvxHatchListItem * pItem = pSh->GetItem(SID_HATCH_LIST);
+
+ if(nPos < pItem->GetHatchList()->Count())
+ {
+ const XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
+ const XFillHatchItem aXFillHatchItem( mpLbFillAttr->get_active_text(), aHatch);
+
+ // #i122676# Change FillStyle and Hatch in one call
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_HATCH, SfxCallMode::RECORD,
+ bFillStyleChange
+ ? std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem, &aXFillStyleItem }
+ : std::initializer_list<SfxPoolItem const*>{ &aXFillHatchItem });
+ }
+ }
+
+ if (nPos != -1)
+ {
+ mnLastPosHatch = nPos;
+ }
+ break;
+ }
+ case BITMAP:
+ {
+ sal_Int32 nPos = mpLbFillAttr->get_active();
+
+ if (nPos == -1)
+ {
+ nPos = mnLastPosBitmap;
+ }
+
+ if (nPos != -1 && pSh && pSh->GetItem(SID_BITMAP_LIST))
+ {
+ const SvxBitmapListItem * pItem = pSh->GetItem(SID_BITMAP_LIST);
+
+ if(nPos < pItem->GetBitmapList()->Count())
+ {
+ const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
+ const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
+
+ // #i122676# Change FillStyle and Bitmap in one call
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
+ bFillStyleChange
+ ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
+ : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
+ }
+ }
+
+ if (nPos != -1)
+ {
+ mnLastPosBitmap = nPos;
+ }
+ break;
+ }
+ case PATTERN:
+ {
+ sal_Int32 nPos = mpLbFillAttr->get_active();
+
+ if (nPos == -1)
+ {
+ nPos = mnLastPosPattern;
+ }
+
+ if (nPos != -1 && pSh && pSh->GetItem(SID_PATTERN_LIST))
+ {
+ const SvxPatternListItem * pItem = pSh->GetItem(SID_PATTERN_LIST);
+
+ if(nPos < pItem->GetPatternList()->Count())
+ {
+ const XBitmapEntry* pXBitmapEntry = pItem->GetPatternList()->GetBitmap(nPos);
+ const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->get_active_text(), pXBitmapEntry->GetGraphicObject());
+
+ // #i122676# Change FillStyle and Bitmap in one call
+ pSh->GetDispatcher()->ExecuteList(
+ SID_ATTR_FILL_BITMAP, SfxCallMode::RECORD,
+ bFillStyleChange
+ ? std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem, &aXFillStyleItem }
+ : std::initializer_list<SfxPoolItem const*>{ &aXFillBitmapItem });
+ }
+ }
+
+ if (nPos != -1)
+ {
+ mnLastPosPattern = nPos;
+ }
+ break;
+ }
+
+ default: break;
+ }
+}
+
+void FillControl::SetOptimalSize()
+{
+ Size aSize(mxLbFillType->get_preferred_size());
+ Size aFirstSize(mxToolBoxColor->get_preferred_size());
+ auto nWidth = std::max(aFirstSize.Width(), LogicToPixel(Size(55, 0), MapMode(MapUnit::MapAppFont)).Width());
+ auto nHeight = std::max(aSize.Height(), aFirstSize.Height());
+ mxToolBoxColor->set_size_request(nWidth, -1);
+ mxLbFillAttr->set_size_request(42, -1); //something narrow so the toolbar sets the overall size of this column
+ SetSizePixel(Size(m_xContainer->get_preferred_size().Width(), nHeight));
+}
+
+void FillControl::DataChanged(const DataChangedEvent& rDCEvt)
+{
+ if((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
+ (rDCEvt.GetFlags() & AllSettingsFlags::STYLE))
+ {
+ SetOptimalSize();
+ }
+ InterimItemWindow::DataChanged(rDCEvt);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */