Files
loongoffice/svx/source/tbxctrls/fillctrl.cxx
Stephan Bergmann 9cd55a26c2 Avoid incomplete type in fn sig to keep ubsan's RTTI-based checks happy
Change-Id: I4823e2d28ebc3aabaa1cb47e4f7f15bfc8c234a5
2014-08-28 18:01:54 +02:00

904 lines
32 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 <string>
#include <sfx2/app.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/viewsh.hxx>
#include <rtl/ustring.hxx>
#include <vcl/settings.hxx>
#include <vcl/toolbox.hxx>
#include <svx/dialogs.hrc>
#define TMP_STR_BEGIN "["
#define TMP_STR_END "]"
#include "svx/drawitem.hxx"
#include "svx/xattr.hxx"
#include <svx/xtable.hxx>
#include <svx/fillctrl.hxx>
#include <svx/itemwin.hxx>
#include <svx/dialmgr.hxx>
#include "helpid.hrc"
#include <boost/scoped_ptr.hpp>
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::frame;
using namespace ::com::sun::star::lang;
SFX_IMPL_TOOLBOX_CONTROL( SvxFillToolBoxControl, XFillStyleItem );
SvxFillToolBoxControl::SvxFillToolBoxControl(
sal_uInt16 nSlotId,
sal_uInt16 nId,
ToolBox& rTbx )
: SfxToolBoxControl( nSlotId, nId, rTbx )
, mpStyleItem(0)
, mpColorItem(0)
, mpGradientItem(0)
, mpHatchItem(0)
, mpBitmapItem(0)
, mpFillControl(0)
, mpFillTypeLB(0)
, mpFillAttrLB(0)
, meLastXFS(drawing::FillStyle_NONE)
, mbUpdate(false)
{
addStatusListener( OUString( ".uno:FillColor" ));
addStatusListener( OUString( ".uno:FillGradient" ));
addStatusListener( OUString( ".uno:FillHatch" ));
addStatusListener( OUString( ".uno:FillBitmap" ));
addStatusListener( OUString( ".uno:ColorTableState" ));
addStatusListener( OUString( ".uno:GradientListState" ));
addStatusListener( OUString( ".uno:HatchListState" ));
addStatusListener( OUString( ".uno:BitmapListState" ));
}
SvxFillToolBoxControl::~SvxFillToolBoxControl()
{
delete mpStyleItem;
delete mpColorItem;
delete mpGradientItem;
delete mpHatchItem;
delete mpBitmapItem;
}
void SvxFillToolBoxControl::StateChanged(
sal_uInt16 nSID,
SfxItemState eState,
const SfxPoolItem* pState)
{
if(eState == SFX_ITEM_DISABLED)
{
// slot disable state
if(nSID == SID_ATTR_FILL_STYLE)
{
mpFillTypeLB->Disable();
mpFillTypeLB->SetNoSelection();
}
mpFillAttrLB->Disable();
mpFillAttrLB->SetNoSelection();
}
else if(SFX_ITEM_AVAILABLE == eState)
{
bool bEnableControls(false);
// slot available state
if(nSID == SID_ATTR_FILL_STYLE)
{
delete mpStyleItem;
mpStyleItem = static_cast< XFillStyleItem* >(pState->Clone());
mpFillTypeLB->Enable();
}
else if(mpStyleItem)
{
const drawing::FillStyle eXFS(static_cast< drawing::FillStyle >(mpStyleItem->GetValue()));
if(nSID == SID_ATTR_FILL_COLOR)
{
delete mpColorItem;
mpColorItem = static_cast< XFillColorItem* >(pState->Clone());
if(eXFS == drawing::FillStyle_SOLID)
{
bEnableControls = true;
}
}
else if(nSID == SID_ATTR_FILL_GRADIENT)
{
delete mpGradientItem;
mpGradientItem = static_cast< XFillGradientItem* >(pState->Clone());
if(eXFS == drawing::FillStyle_GRADIENT)
{
bEnableControls = true;
}
}
else if(nSID == SID_ATTR_FILL_HATCH)
{
delete mpHatchItem;
mpHatchItem = static_cast< XFillHatchItem* >(pState->Clone());
if(eXFS == drawing::FillStyle_HATCH)
{
bEnableControls = true;
}
}
else if(nSID == SID_ATTR_FILL_BITMAP)
{
delete mpBitmapItem;
mpBitmapItem = static_cast< XFillBitmapItem* >(pState->Clone());
if(eXFS == drawing::FillStyle_BITMAP)
{
bEnableControls = true;
}
}
}
if(mpStyleItem)
{
// ensure that the correct entry is selected in mpFillTypeLB
drawing::FillStyle eXFS(static_cast< drawing::FillStyle >(mpStyleItem->GetValue()));
const bool bFillTypeChangedByUser(mpFillControl->mbFillTypeChanged);
if(bFillTypeChangedByUser)
{
meLastXFS = static_cast< drawing::FillStyle >(mpFillControl->mnLastFillTypeControlSelectEntryPos);
mpFillControl->mbFillTypeChanged = false;
}
if(meLastXFS != eXFS)
{
mbUpdate = true;
mpFillTypeLB->SelectEntryPos(sal::static_int_cast<sal_uInt16>(eXFS));
}
mpFillAttrLB->Enable();
}
if(bEnableControls)
{
mpFillAttrLB->Enable();
mbUpdate = true;
}
Update(pState);
}
else
{
// slot empty or ambigous
if(nSID == SID_ATTR_FILL_STYLE)
{
mpFillTypeLB->SetNoSelection();
mpFillAttrLB->Disable();
mpFillAttrLB->SetNoSelection();
delete mpStyleItem;
mpStyleItem = 0;
mbUpdate = false;
}
else
{
drawing::FillStyle eXFS(drawing::FillStyle_NONE);
if(mpStyleItem)
{
eXFS = static_cast< drawing::FillStyle >(mpStyleItem->GetValue());
}
if(!mpStyleItem ||
(nSID == SID_ATTR_FILL_COLOR && eXFS == drawing::FillStyle_SOLID) ||
(nSID == SID_ATTR_FILL_GRADIENT && eXFS == drawing::FillStyle_GRADIENT) ||
(nSID == SID_ATTR_FILL_HATCH && eXFS == drawing::FillStyle_HATCH) ||
(nSID == SID_ATTR_FILL_BITMAP && eXFS == drawing::FillStyle_BITMAP))
{
mpFillAttrLB->SetNoSelection();
}
}
}
}
void SvxFillToolBoxControl::Update(const SfxPoolItem* pState)
{
if(mpStyleItem && pState && mbUpdate)
{
mbUpdate = false;
const drawing::FillStyle eXFS(static_cast< drawing::FillStyle >(mpStyleItem->GetValue()));
// Check if the fill style was already active
if(meLastXFS != eXFS)
{
// update mnLastFillTypeControlSelectEntryPos and fill style list
mpFillControl->updateLastFillTypeControlSelectEntryPos();
mpFillControl->InitializeFillStyleAccordingToGivenFillType(eXFS);
meLastXFS = eXFS;
}
switch(eXFS)
{
case drawing::FillStyle_NONE:
{
break;
}
case drawing::FillStyle_SOLID:
{
if(mpColorItem)
{
OUString aString(mpColorItem->GetName());
::Color aColor = mpColorItem->GetColorValue();
mpFillAttrLB->SelectEntry(aString);
if(mpFillAttrLB->GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND || mpFillAttrLB->GetSelectEntryColor() != aColor)
{
mpFillAttrLB->SelectEntry(aColor);
}
// Check if the entry is not in the list
if( mpFillAttrLB->GetSelectEntryPos() ==
LISTBOX_ENTRY_NOTFOUND ||
mpFillAttrLB->GetSelectEntryColor() != aColor )
{
sal_Int32 nCount = mpFillAttrLB->GetEntryCount();
OUString aTmpStr;
if( nCount > 0 )
{
// Last entry gets tested against temporary color
aTmpStr = mpFillAttrLB->GetEntry( nCount - 1 );
if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
aTmpStr.endsWith(TMP_STR_END) )
{
mpFillAttrLB->RemoveEntry(nCount - 1);
}
}
aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
sal_Int32 nPos = mpFillAttrLB->InsertEntry(aColor, aTmpStr);
mpFillAttrLB->SelectEntryPos(nPos);
}
}
else
{
mpFillAttrLB->SetNoSelection();
}
break;
}
case drawing::FillStyle_GRADIENT:
{
if(mpGradientItem)
{
OUString aString(mpGradientItem->GetName());
mpFillAttrLB->SelectEntry( aString );
// Check if the entry is not in the list
if (mpFillAttrLB->GetSelectEntry() != aString)
{
sal_Int32 nCount = mpFillAttrLB->GetEntryCount();
OUString aTmpStr;
if( nCount > 0 )
{
// Last entry gets tested against temporary entry
aTmpStr = mpFillAttrLB->GetEntry( nCount - 1 );
if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
aTmpStr.endsWith(TMP_STR_END) )
{
mpFillAttrLB->RemoveEntry(nCount - 1);
}
}
aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
boost::scoped_ptr<XGradientEntry> pEntry(new XGradientEntry(mpGradientItem->GetGradientValue(), aTmpStr));
XGradientList aGradientList( "", ""/*TODO?*/ );
aGradientList.Insert( pEntry.get() );
aGradientList.SetDirty( false );
const Bitmap aBmp = aGradientList.GetUiBitmap( 0 );
if(!aBmp.IsEmpty())
{
mpFillAttrLB->InsertEntry(pEntry->GetName(), Image(aBmp));
mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
}
aGradientList.Remove( 0 );
}
}
else
{
mpFillAttrLB->SetNoSelection();
}
break;
}
case drawing::FillStyle_HATCH:
{
if(mpHatchItem)
{
OUString aString(mpHatchItem->GetName());
mpFillAttrLB->SelectEntry( aString );
// Check if the entry is not in the list
if (mpFillAttrLB->GetSelectEntry() != aString)
{
sal_Int32 nCount = mpFillAttrLB->GetEntryCount();
OUString aTmpStr;
if( nCount > 0 )
{
// Last entry gets tested against temporary entry
aTmpStr = mpFillAttrLB->GetEntry( nCount - 1 );
if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
aTmpStr.endsWith(TMP_STR_END) )
{
mpFillAttrLB->RemoveEntry(nCount - 1);
}
}
aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
boost::scoped_ptr<XHatchEntry> pEntry(new XHatchEntry(mpHatchItem->GetHatchValue(), aTmpStr));
XHatchList aHatchList( "", ""/*TODO?*/ );
aHatchList.Insert( pEntry.get() );
aHatchList.SetDirty( false );
const Bitmap aBmp = aHatchList.GetUiBitmap( 0 );
if(!aBmp.IsEmpty())
{
mpFillAttrLB->InsertEntry(pEntry->GetName(), Image(aBmp));
mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
}
aHatchList.Remove( 0 );
}
}
else
{
mpFillAttrLB->SetNoSelection();
}
break;
}
case drawing::FillStyle_BITMAP:
{
if(mpBitmapItem)
{
OUString aString(mpBitmapItem->GetName());
mpFillAttrLB->SelectEntry( aString );
// Check if the entry is not in the list
if (mpFillAttrLB->GetSelectEntry() != aString)
{
sal_Int32 nCount = mpFillAttrLB->GetEntryCount();
OUString aTmpStr;
if( nCount > 0 )
{
// Last entry gets tested against temporary entry
aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
if( aTmpStr.startsWith(TMP_STR_BEGIN) &&
aTmpStr.endsWith(TMP_STR_END) )
{
mpFillAttrLB->RemoveEntry(nCount - 1);
}
}
aTmpStr = TMP_STR_BEGIN + aString + TMP_STR_END;
boost::scoped_ptr<XBitmapEntry> pEntry(new XBitmapEntry(mpBitmapItem->GetGraphicObject(), aTmpStr));
XBitmapListRef xBitmapList =
XPropertyList::AsBitmapList(
XPropertyList::CreatePropertyList(
XBITMAP_LIST, "TmpList", ""/*TODO?*/));
xBitmapList->Insert( pEntry.get() );
xBitmapList->SetDirty( false );
mpFillAttrLB->Fill( xBitmapList );
mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
xBitmapList->Remove( 0 );
}
}
else
{
mpFillAttrLB->SetNoSelection();
}
break;
}
default:
{
OSL_FAIL( "Unsupported fill type" );
break;
}
}
// update mnLastFillAttrControlSelectEntryPos
mpFillControl->updateLastFillAttrControlSelectEntryPos();
}
if(pState && mpStyleItem)
{
drawing::FillStyle eXFS = static_cast< drawing::FillStyle >(mpStyleItem->GetValue());
// Does the lists have changed?
switch(eXFS)
{
case drawing::FillStyle_SOLID:
{
const SvxColorListItem* pItem = dynamic_cast< const SvxColorListItem* >(pState);
if(pItem)
{
::Color aTmpColor(mpFillAttrLB->GetSelectEntryColor());
mpFillAttrLB->Clear();
mpFillAttrLB->Fill(pItem->GetColorList());
mpFillAttrLB->SelectEntry(aTmpColor);
}
break;
}
case drawing::FillStyle_GRADIENT:
{
const SvxGradientListItem* pItem = dynamic_cast< const SvxGradientListItem* >(pState);
if(pItem)
{
OUString aString(mpFillAttrLB->GetSelectEntry());
mpFillAttrLB->Clear();
mpFillAttrLB->Fill(pItem->GetGradientList());
mpFillAttrLB->SelectEntry(aString);
}
break;
}
case drawing::FillStyle_HATCH:
{
const SvxHatchListItem* pItem = dynamic_cast< const SvxHatchListItem* >(pState);
if(pItem)
{
OUString aString(mpFillAttrLB->GetSelectEntry());
mpFillAttrLB->Clear();
mpFillAttrLB->Fill(pItem->GetHatchList());
mpFillAttrLB->SelectEntry(aString);
}
break;
}
case drawing::FillStyle_BITMAP:
{
const SvxBitmapListItem* pItem = dynamic_cast< const SvxBitmapListItem* >(pState);
if(pItem)
{
OUString aString(mpFillAttrLB->GetSelectEntry());
mpFillAttrLB->Clear();
mpFillAttrLB->Fill(pItem->GetBitmapList());
mpFillAttrLB->SelectEntry(aString);
}
break;
}
default: // drawing::FillStyle_NONE
{
break;
}
}
}
}
Window* SvxFillToolBoxControl::CreateItemWindow(Window *pParent)
{
if(GetSlotId() == SID_ATTR_FILL_STYLE)
{
mpFillControl = new FillControl(pParent);
// Thus the FillControl is known by SvxFillToolBoxControl
// (and in order to remain compatible)
mpFillControl->SetData(this);
mpFillAttrLB = (SvxFillAttrBox*)mpFillControl->mpLbFillAttr;
mpFillTypeLB = (SvxFillTypeBox*)mpFillControl->mpLbFillType;
mpFillAttrLB->SetUniqueId(HID_FILL_ATTR_LISTBOX);
mpFillTypeLB->SetUniqueId(HID_FILL_TYPE_LISTBOX);
if(!mpStyleItem)
{
// for Writer and Calc it's not the same instance of
// SvxFillToolBoxControl which gets used after deselecting
// and selecting a DrawObject, thhus a useful initialization is
// needed to get the FillType and the FillStyle List inited
// correctly. This in combination with meLastXFS inited to
// drawing::FillStyle_NONE do the trick
mpStyleItem = new XFillStyleItem(drawing::FillStyle_SOLID);
}
return mpFillControl;
}
return NULL;
}
FillControl::FillControl(Window* pParent,WinBits nStyle)
: Window(pParent,nStyle | WB_DIALOGCONTROL),
mpLbFillType(new SvxFillTypeBox(this)),
mpLbFillAttr(new SvxFillAttrBox(this)),
maLogicalFillSize(40,80),
maLogicalAttrSize(50,80),
mnLastFillTypeControlSelectEntryPos(mpLbFillType->GetSelectEntryPos()),
mnLastFillAttrControlSelectEntryPos(mpLbFillAttr->GetSelectEntryPos()),
mbFillTypeChanged(false)
{
Size aTypeSize(LogicToPixel(maLogicalFillSize,MAP_APPFONT));
Size aAttrSize(LogicToPixel(maLogicalAttrSize,MAP_APPFONT));
mpLbFillType->SetSizePixel(aTypeSize);
mpLbFillAttr->SetSizePixel(aAttrSize);
//to get the base height
aTypeSize = mpLbFillType->GetSizePixel();
aAttrSize = mpLbFillAttr->GetSizePixel();
Point aAttrPnt = mpLbFillAttr->GetPosPixel();
SetSizePixel(
Size(aAttrPnt.X() + aAttrSize.Width(),
std::max(aAttrSize.Height(),aTypeSize.Height())));
mpLbFillType->SetSelectHdl(LINK(this,FillControl,SelectFillTypeHdl));
mpLbFillAttr->SetSelectHdl(LINK(this,FillControl,SelectFillAttrHdl));
}
FillControl::~FillControl()
{
delete mpLbFillType;
delete mpLbFillAttr;
}
void FillControl::InitializeFillStyleAccordingToGivenFillType(drawing::FillStyle aFillStyle)
{
SfxObjectShell* pSh = SfxObjectShell::Current();
bool bDone(false);
if(pSh)
{
// clear in all cases, else we would risk a mix of FillStyles in the Style list
mpLbFillAttr->Clear();
switch (aFillStyle)
{
case drawing::FillStyle_SOLID:
{
if(pSh->GetItem(SID_COLOR_TABLE))
{
const SvxColorListItem* pItem = static_cast<const SvxColorListItem*>(pSh->GetItem(SID_COLOR_TABLE));
mpLbFillAttr->Enable();
mpLbFillAttr->Fill(pItem->GetColorList());
bDone = true;
}
break;
}
case drawing::FillStyle_GRADIENT:
{
if(pSh->GetItem(SID_GRADIENT_LIST))
{
const SvxGradientListItem* pItem = static_cast< const SvxGradientListItem* >(pSh->GetItem(SID_GRADIENT_LIST));
mpLbFillAttr->Enable();
mpLbFillAttr->Fill(pItem->GetGradientList());
bDone = true;
}
break;
}
case drawing::FillStyle_HATCH:
{
if(pSh->GetItem(SID_HATCH_LIST))
{
const SvxHatchListItem* pItem = static_cast< const SvxHatchListItem* >(pSh->GetItem(SID_HATCH_LIST));
mpLbFillAttr->Enable();
mpLbFillAttr->Fill(pItem->GetHatchList());
bDone = true;
}
break;
}
case drawing::FillStyle_BITMAP:
{
if(pSh->GetItem(SID_BITMAP_LIST))
{
const SvxBitmapListItem* pItem = static_cast< const SvxBitmapListItem* >(pSh->GetItem(SID_BITMAP_LIST));
mpLbFillAttr->Enable();
mpLbFillAttr->Fill(pItem->GetBitmapList());
bDone = true;
}
break;
}
default: // drawing::FillStyle_NONE
{
// accept disable (no styles for drawing::FillStyle_NONE)
break;
}
}
}
if (!bDone)
{
mpLbFillAttr->Disable();
}
}
void FillControl::updateLastFillTypeControlSelectEntryPos()
{
mnLastFillTypeControlSelectEntryPos = mpLbFillType->GetSelectEntryPos();
}
IMPL_LINK(FillControl,SelectFillTypeHdl,ListBox *,pBox)
{
if(!pBox) // only work with real calls from ListBox, do not accept direct calls with zeros here
{
return 0;
}
const bool bAction(
!mpLbFillType->IsTravelSelect() // keep TravelSelect, this means keyboard up/down in the list
&& mpLbFillType->GetSelectEntryCount()
&& mpLbFillType->GetSelectEntryPos() != mnLastFillTypeControlSelectEntryPos);
updateLastFillTypeControlSelectEntryPos();
drawing::FillStyle eXFS = static_cast< drawing::FillStyle >(mpLbFillType->GetSelectEntryPos());
if(bAction && drawing::FillStyle_NONE != eXFS)
{
mbFillTypeChanged = true;
}
// update list of FillStyles in any case
InitializeFillStyleAccordingToGivenFillType(eXFS);
// for drawing::FillStyle_NONE do no longer call SelectFillAttrHdl (as done before),
// trigger needed actions directly. This is the only action this handler
// can trigger directly as the user action is finished in this case
if(drawing::FillStyle_NONE == eXFS && bAction)
{
// for drawing::FillStyle_NONE do no longer call SelectFillAttrHdl,
// trigger needed actions directly
Any a;
Sequence< PropertyValue > aArgsFillStyle(1);
XFillStyleItem aXFillStyleItem(eXFS);
aArgsFillStyle[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"));
aXFillStyleItem.QueryValue(a);
aArgsFillStyle[0].Value = a;
((SvxFillToolBoxControl*)GetData())->Dispatch(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillStyle")), aArgsFillStyle);
}
mpLbFillType->Selected();
// release focus. Needed to get focus automatically back to EditView
if(mpLbFillType->IsRelease())
{
SfxViewShell* pViewShell = SfxViewShell::Current();
if(pViewShell && pViewShell->GetWindow())
{
pViewShell->GetWindow()->GrabFocus();
}
}
return 0;
}
void FillControl::updateLastFillAttrControlSelectEntryPos()
{
mnLastFillAttrControlSelectEntryPos = mpLbFillAttr->GetSelectEntryPos();
}
IMPL_LINK(FillControl, SelectFillAttrHdl, ListBox *, pBox)
{
if(!pBox) // only work with real calls from ListBox, do not accept direct calls with zeros here
{
return 0;
}
const bool bAction(
!mpLbFillAttr->IsTravelSelect() // keep TravelSelect, this means keyboard up/down in the list
&& mpLbFillAttr->GetSelectEntryCount()
&& mpLbFillAttr->GetSelectEntryPos() != mnLastFillAttrControlSelectEntryPos);
updateLastFillAttrControlSelectEntryPos();
if(bAction)
{
SfxObjectShell* pSh = SfxObjectShell::Current();
// Need to prepare the PropertyValue for the FillStyle dispatch action early,
// else the call for FillType to Dispatch(".uno:FillStyle") will already destroy the current state
// of selection in mpLbFillAttr again by calls to StateChanged which *will* set to no
// selection again (e.g. when two objects, same fill style, but different fill attributes)
Any a;
Sequence< PropertyValue > aArgsFillAttr(1);
OUString aFillAttrCommand;
drawing::FillStyle eXFS(static_cast< drawing::FillStyle >(mpLbFillType->GetSelectEntryPos()));
switch(eXFS)
{
default:
case drawing::FillStyle_NONE:
{
// handled in SelectFillTypeHdl, nothing to do here
break;
}
case drawing::FillStyle_SOLID:
{
// Entry gets tested against temporary color
OUString aTmpStr = mpLbFillAttr->GetSelectEntry();
if( aTmpStr.startsWith(TMP_STR_BEGIN) && aTmpStr.endsWith(TMP_STR_END) )
{
aTmpStr = aTmpStr.copy(1, aTmpStr.getLength()-2);
}
XFillColorItem aXFillColorItem(aTmpStr, mpLbFillAttr->GetSelectEntryColor());
aArgsFillAttr[0].Name = "FillColor";
aXFillColorItem.QueryValue(a);
aArgsFillAttr[0].Value = a;
aFillAttrCommand = ".uno:FillColor";
break;
}
case drawing::FillStyle_GRADIENT:
{
sal_Int32 nPos = mpLbFillAttr->GetSelectEntryPos();
if (nPos != LISTBOX_ENTRY_NOTFOUND && pSh && pSh->GetItem(SID_GRADIENT_LIST))
{
const SvxGradientListItem* pItem = static_cast< const SvxGradientListItem* >(pSh->GetItem(SID_GRADIENT_LIST));
if (nPos < pItem->GetGradientList()->Count()) // no temporary entry?
{
XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
XFillGradientItem aXFillGradientItem(mpLbFillAttr->GetSelectEntry(),aGradient);
aArgsFillAttr[0].Name = "FillGradient";
aXFillGradientItem.QueryValue(a);
aArgsFillAttr[0].Value = a;
aFillAttrCommand = ".uno:FillGradient";
}
}
break;
}
case drawing::FillStyle_HATCH:
{
sal_Int32 nPos = mpLbFillAttr->GetSelectEntryPos();
if (nPos != LISTBOX_ENTRY_NOTFOUND && pSh && pSh->GetItem(SID_HATCH_LIST))
{
const SvxHatchListItem* pItem = static_cast< const SvxHatchListItem* >(pSh->GetItem(SID_HATCH_LIST));
if (nPos < pItem->GetHatchList()->Count()) // no temporary entry?
{
XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
XFillHatchItem aXFillHatchItem(mpLbFillAttr->GetSelectEntry(), aHatch);
aArgsFillAttr[0].Name = "FillHatch";
aXFillHatchItem.QueryValue(a);
aArgsFillAttr[0].Value = a;
aFillAttrCommand = ".uno:FillHatch";
}
}
break;
}
case drawing::FillStyle_BITMAP:
{
sal_Int32 nPos = mpLbFillAttr->GetSelectEntryPos();
if (nPos != LISTBOX_ENTRY_NOTFOUND && pSh && pSh->GetItem(SID_BITMAP_LIST))
{
const SvxBitmapListItem* pItem = static_cast< const SvxBitmapListItem* >(pSh->GetItem(SID_BITMAP_LIST));
if (nPos < pItem->GetBitmapList()->Count()) // no temporary entry?
{
const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->GetSelectEntry(),pXBitmapEntry->GetGraphicObject());
aArgsFillAttr[0].Name = "FillBitmap";
aXFillBitmapItem.QueryValue(a);
aArgsFillAttr[0].Value = a;
aFillAttrCommand = ".uno:FillBitmap";
}
}
break;
}
}
// this is the place where evtl. a new slot action may be introduced to avoid the
// two undo entries. Reason for this is that indeed two actions are executed, the fill style
// and the fill attribute change. The sidebar already handles both separately, so
// changing the fill style already changes the object and adds a default fill attribute for
// the newly choosen fill style.
// This control uses the older user's two-step action to select a fill style and a fill attribute. In
// this case a lot of things may go wrong (e.g. the user stops that action and does something
// different), thus the solution of the sidebar should be preferred from my POV in the future
// first set the fill style if changed
if(mbFillTypeChanged)
{
Sequence< PropertyValue > aArgsFillStyle(1);
XFillStyleItem aXFillStyleItem(eXFS);
aArgsFillStyle[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"));
aXFillStyleItem.QueryValue(a);
aArgsFillStyle[0].Value = a;
((SvxFillToolBoxControl*)GetData())->Dispatch(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillStyle")), aArgsFillStyle);
mbFillTypeChanged = false;
}
// second set fill attribute when a change was detected and prepared
if(aFillAttrCommand.getLength())
{
((SvxFillToolBoxControl*)GetData())->Dispatch(aFillAttrCommand, aArgsFillAttr);
}
// release focus. Needed to get focus automatically back to EditView
if(mpLbFillAttr->IsRelease() && pBox)
{
SfxViewShell* pViewShell = SfxViewShell::Current();
if(pViewShell && pViewShell->GetWindow())
{
pViewShell->GetWindow()->GrabFocus();
}
}
}
return 0;
}
void FillControl::Resize()
{
// Width of the two list boxes not 1/2 : 1/2, but 2/5 : 3/5
long nW = GetOutputSizePixel().Width() / 5;
long nH = 180;
long nSep = 0; // was previously 4
mpLbFillType->SetSizePixel(Size(nW * 2 - nSep,nH));
mpLbFillAttr->SetPosSizePixel(Point(nW * 2 + nSep,0),Size(nW * 3 - nSep,nH));
}
void FillControl::DataChanged(const DataChangedEvent& rDCEvt)
{
if((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
(rDCEvt.GetFlags() & SETTINGS_STYLE))
{
Size aTypeSize(LogicToPixel(maLogicalFillSize,MAP_APPFONT));
Size aAttrSize(LogicToPixel(maLogicalAttrSize,MAP_APPFONT));
mpLbFillType->SetSizePixel(aTypeSize);
mpLbFillAttr->SetSizePixel(aAttrSize);
//to get the base height
aTypeSize = mpLbFillType->GetSizePixel();
aAttrSize = mpLbFillAttr->GetSizePixel();
Point aAttrPnt = mpLbFillAttr->GetPosPixel();
SetSizePixel(
Size(aAttrPnt.X() + aAttrSize.Width(),
std::max(aAttrSize.Height(), aTypeSize.Height())));
}
Window::DataChanged(rDCEvt);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */