blob: 452749143cfbc4358086ff84cba50ccdceb0decd [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svx.hxx"
#include <string> // HACK: prevent conflict between STLPORT and Workshop headers
#include <sfx2/app.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/objsh.hxx>
#include <sfx2/viewsh.hxx>
#include <rtl/ustring.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"
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::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(XFILL_NONE),
mbUpdate(false)
{
addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FillColor" )));
addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FillGradient" )));
addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FillHatch" )));
addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:FillBitmap" )));
addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:ColorTableState" )));
addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:GradientListState" )));
addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".uno:HatchListState" )));
addStatusListener( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ".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)
{
bool bEnableControls(false);
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)
{
// slot available state
if(nSID == SID_ATTR_FILL_STYLE)
{
delete mpStyleItem;
mpStyleItem = static_cast< XFillStyleItem* >(pState->Clone());
mpFillTypeLB->Enable();
}
else if(mpStyleItem)
{
const XFillStyle eXFS(static_cast< XFillStyle >(mpStyleItem->GetValue()));
if(nSID == SID_ATTR_FILL_COLOR)
{
delete mpColorItem;
mpColorItem = static_cast< XFillColorItem* >(pState->Clone());
if(eXFS == XFILL_SOLID)
{
bEnableControls = true;
}
}
else if(nSID == SID_ATTR_FILL_GRADIENT)
{
delete mpGradientItem;
mpGradientItem = static_cast< XFillGradientItem* >(pState->Clone());
if(eXFS == XFILL_GRADIENT)
{
bEnableControls = true;
}
}
else if(nSID == SID_ATTR_FILL_HATCH)
{
delete mpHatchItem;
mpHatchItem = static_cast< XFillHatchItem* >(pState->Clone());
if(eXFS == XFILL_HATCH)
{
bEnableControls = true;
}
}
else if(nSID == SID_ATTR_FILL_BITMAP)
{
delete mpBitmapItem;
mpBitmapItem = static_cast< XFillBitmapItem* >(pState->Clone());
if(eXFS == XFILL_BITMAP)
{
bEnableControls = true;
}
}
}
if(mpStyleItem)
{
// ensure that the correct entry is selected in mpFillTypeLB
XFillStyle eXFS(static_cast< XFillStyle >(mpStyleItem->GetValue()));
const bool bFillTypeChangedByUser(mpFillControl->mbFillTypeChanged);
if(bFillTypeChangedByUser)
{
meLastXFS = static_cast< XFillStyle >(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
{
XFillStyle eXFS(XFILL_NONE);
if(mpStyleItem)
{
eXFS = static_cast< XFillStyle >(mpStyleItem->GetValue());
}
if(!mpStyleItem ||
(nSID == SID_ATTR_FILL_COLOR && eXFS == XFILL_SOLID) ||
(nSID == SID_ATTR_FILL_GRADIENT && eXFS == XFILL_GRADIENT) ||
(nSID == SID_ATTR_FILL_HATCH && eXFS == XFILL_HATCH) ||
(nSID == SID_ATTR_FILL_BITMAP && eXFS == XFILL_BITMAP))
{
mpFillAttrLB->SetNoSelection();
}
}
}
}
//========================================================================
void SvxFillToolBoxControl::Update(const SfxPoolItem* pState)
{
if(mpStyleItem && pState && mbUpdate)
{
mbUpdate = false;
const XFillStyle eXFS(static_cast< XFillStyle >(mpStyleItem->GetValue()));
// Pruefen, ob Fuellstil schon vorher aktiv war
if(meLastXFS != eXFS)
{
// update mnLastFillTypeControlSelectEntryPos and fill style list
mpFillControl->updateLastFillTypeControlSelectEntryPos();
mpFillControl->InitializeFillStyleAccordingToGivenFillType(eXFS);
meLastXFS = eXFS;
}
switch(eXFS)
{
case XFILL_NONE:
{
break;
}
case XFILL_SOLID:
{
if(mpColorItem)
{
String aString(mpColorItem->GetName());
::Color aColor = mpColorItem->GetColorValue();
mpFillAttrLB->SelectEntry(aString);
if(mpFillAttrLB->GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND || mpFillAttrLB->GetSelectEntryColor() != aColor)
{
mpFillAttrLB->SelectEntry(aColor);
}
// Pruefen, ob Eintrag nicht in der Liste ist
if(mpFillAttrLB->GetSelectEntryPos() == LISTBOX_ENTRY_NOTFOUND || mpFillAttrLB->GetSelectEntryColor() != aColor)
{
sal_uInt16 nCount = mpFillAttrLB->GetEntryCount();
String aTmpStr;
if(nCount > 0)
{
//Letzter Eintrag wird auf temporaere Farbe geprueft
aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
if(aTmpStr.GetChar(0) == TMP_STR_BEGIN && aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
{
mpFillAttrLB->RemoveEntry(nCount - 1);
}
}
aTmpStr = TMP_STR_BEGIN;
aTmpStr += aString;
aTmpStr += TMP_STR_END;
sal_uInt16 nPos = mpFillAttrLB->InsertEntry(aColor,aTmpStr);
mpFillAttrLB->SelectEntryPos(nPos);
}
}
else
{
mpFillAttrLB->SetNoSelection();
}
break;
}
case XFILL_GRADIENT:
{
if(mpGradientItem)
{
String aString(mpGradientItem->GetName());
mpFillAttrLB->SelectEntry(aString);
// Pruefen, ob Eintrag nicht in der Liste ist
if(mpFillAttrLB->GetSelectEntry() != aString)
{
sal_uInt16 nCount = mpFillAttrLB->GetEntryCount();
String aTmpStr;
if(nCount > 0)
{
//Letzter Eintrag wird auf temporaeren Eintrag geprueft
aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
if(aTmpStr.GetChar(0) == TMP_STR_BEGIN && aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
{
mpFillAttrLB->RemoveEntry(nCount - 1);
}
}
aTmpStr = TMP_STR_BEGIN;
aTmpStr += aString;
aTmpStr += TMP_STR_END;
XGradientEntry* pEntry = new XGradientEntry(mpGradientItem->GetGradientValue(),aTmpStr);
XGradientListSharedPtr aGradientList(XPropertyListFactory::CreateSharedXGradientList(String::CreateFromAscii("TmpList")));
aGradientList->Insert(pEntry);
aGradientList->SetDirty(false);
const Bitmap aBmp = aGradientList->GetUiBitmap(0);
if(!aBmp.IsEmpty())
{
((ListBox*)mpFillAttrLB)->InsertEntry(pEntry->GetName(),aBmp);
mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
}
}
}
else
{
mpFillAttrLB->SetNoSelection();
}
break;
}
case XFILL_HATCH:
{
if(mpHatchItem)
{
String aString(mpHatchItem->GetName());
mpFillAttrLB->SelectEntry(aString);
// Pruefen, ob Eintrag nicht in der Liste ist
if(mpFillAttrLB->GetSelectEntry() != aString)
{
sal_uInt16 nCount = mpFillAttrLB->GetEntryCount();
String aTmpStr;
if(nCount > 0)
{
//Letzter Eintrag wird auf temporaeren Eintrag geprueft
aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
if(aTmpStr.GetChar(0) == TMP_STR_BEGIN &&
aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
{
mpFillAttrLB->RemoveEntry(nCount - 1);
}
}
aTmpStr = TMP_STR_BEGIN;
aTmpStr += aString;
aTmpStr += TMP_STR_END;
XHatchEntry* pEntry = new XHatchEntry(mpHatchItem->GetHatchValue(),aTmpStr);
XHatchListSharedPtr aHatchList(XPropertyListFactory::CreateSharedXHatchList(String::CreateFromAscii("TmpList")));
aHatchList->Insert(pEntry);
aHatchList->SetDirty(sal_False);
const Bitmap aBmp = aHatchList->GetUiBitmap(0);
if(!aBmp.IsEmpty())
{
((ListBox*)mpFillAttrLB)->InsertEntry(pEntry->GetName(),aBmp);
mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
}
}
}
else
{
mpFillAttrLB->SetNoSelection();
}
break;
}
case XFILL_BITMAP:
{
if(mpBitmapItem)
{
String aString(mpBitmapItem->GetName());
mpFillAttrLB->SelectEntry(aString);
// Pruefen, ob Eintrag nicht in der Liste ist
if(mpFillAttrLB->GetSelectEntry() != aString)
{
sal_uInt16 nCount = mpFillAttrLB->GetEntryCount();
String aTmpStr;
if(nCount > 0)
{
//Letzter Eintrag wird auf temporaeren Eintrag geprueft
aTmpStr = mpFillAttrLB->GetEntry(nCount - 1);
if(aTmpStr.GetChar(0) == TMP_STR_BEGIN && aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
{
mpFillAttrLB->RemoveEntry(nCount - 1);
}
}
aTmpStr = TMP_STR_BEGIN;
aTmpStr += aString;
aTmpStr += TMP_STR_END;
XBitmapListSharedPtr aNew(XPropertyListFactory::CreateSharedXBitmapList(String::CreateFromAscii("TmpList")));
aNew->Insert(new XBitmapEntry(mpBitmapItem->GetGraphicObject(),aTmpStr));
aNew->SetDirty(false);
mpFillAttrLB->Fill(aNew);
mpFillAttrLB->SelectEntryPos(mpFillAttrLB->GetEntryCount() - 1);
}
}
else
{
mpFillAttrLB->SetNoSelection();
}
break;
}
default:
{
DBG_ERROR("Nicht unterstuetzter Flaechentyp");
break;
}
}
// update mnLastFillAttrControlSelectEntryPos
mpFillControl->updateLastFillAttrControlSelectEntryPos();
}
if(pState && mpStyleItem)
{
XFillStyle eXFS = static_cast< XFillStyle >(mpStyleItem->GetValue());
// Die Listen haben sich geaendert ?
switch(eXFS)
{
case XFILL_SOLID:
{
const SvxColorTableItem* pItem = dynamic_cast< const SvxColorTableItem* >(pState);
if(pItem)
{
::Color aTmpColor(mpFillAttrLB->GetSelectEntryColor());
mpFillAttrLB->Clear();
mpFillAttrLB->Fill(pItem->GetColorTable());
mpFillAttrLB->SelectEntry(aTmpColor);
}
break;
}
case XFILL_GRADIENT:
{
const SvxGradientListItem* pItem = dynamic_cast< const SvxGradientListItem* >(pState);
if(pItem)
{
String aString(mpFillAttrLB->GetSelectEntry());
mpFillAttrLB->Clear();
mpFillAttrLB->Fill(pItem->GetGradientList());
mpFillAttrLB->SelectEntry(aString);
}
break;
}
case XFILL_HATCH:
{
const SvxHatchListItem* pItem = dynamic_cast< const SvxHatchListItem* >(pState);
if(pItem)
{
String aString(mpFillAttrLB->GetSelectEntry());
mpFillAttrLB->Clear();
mpFillAttrLB->Fill(pItem->GetHatchList());
mpFillAttrLB->SelectEntry(aString);
}
break;
}
case XFILL_BITMAP:
{
const SvxBitmapListItem* pItem = dynamic_cast< const SvxBitmapListItem* >(pState);
if(pItem)
{
String aString(mpFillAttrLB->GetSelectEntry());
mpFillAttrLB->Clear();
mpFillAttrLB->Fill(pItem->GetBitmapList());
mpFillAttrLB->SelectEntry(aString);
}
break;
}
default: // XFILL_NONE
{
break;
}
}
}
}
//========================================================================
Window* SvxFillToolBoxControl::CreateItemWindow(Window *pParent)
{
if(GetSlotId() == SID_ATTR_FILL_STYLE)
{
mpFillControl = new FillControl(pParent);
// Damit dem FillControl das SvxFillToolBoxControl bekannt ist
// (und um kompatibel zu bleiben)
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
// XFILL_NONE do the trick
mpStyleItem = new XFillStyleItem(XFILL_SOLID);
}
return mpFillControl;
}
return NULL;
}
/*************************************************************************
|*
|* FillControl
|*
\************************************************************************/
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(),
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(XFillStyle 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 XFILL_SOLID:
{
if(pSh->GetItem(SID_COLOR_TABLE))
{
const SvxColorTableItem* pItem = static_cast< const SvxColorTableItem* >(pSh->GetItem(SID_COLOR_TABLE));
mpLbFillAttr->Enable();
mpLbFillAttr->Fill(pItem->GetColorTable());
bDone = true;
}
break;
}
case XFILL_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 XFILL_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 XFILL_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: // XFILL_NONE
{
// accept disable (no styles for XFILL_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();
XFillStyle eXFS = static_cast< XFillStyle >(mpLbFillType->GetSelectEntryPos());
if(bAction && XFILL_NONE != eXFS)
{
mbFillTypeChanged = true;
}
// update list of FillStyles in any case
InitializeFillStyleAccordingToGivenFillType(eXFS);
// for XFILL_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(XFILL_NONE == eXFS && bAction)
{
// for XFILL_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);
::rtl::OUString aFillAttrCommand;
XFillStyle eXFS(static_cast< XFillStyle >(mpLbFillType->GetSelectEntryPos()));
switch(eXFS)
{
case XFILL_NONE:
{
// handled in SelectFillTypeHdl, nothing to do here
break;
}
case XFILL_SOLID:
{
//Eintrag wird auf temporaere Farbe geprueft
String aTmpStr = mpLbFillAttr->GetSelectEntry();
if(aTmpStr.GetChar(0) == TMP_STR_BEGIN && aTmpStr.GetChar(aTmpStr.Len() - 1) == TMP_STR_END)
{
aTmpStr.Erase(aTmpStr.Len() - 1,1);
aTmpStr.Erase(0,1);
}
XFillColorItem aXFillColorItem(aTmpStr,mpLbFillAttr->GetSelectEntryColor());
aArgsFillAttr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillColor"));
aXFillColorItem.QueryValue(a);
aArgsFillAttr[0].Value = a;
aFillAttrCommand = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillColor"));
break;
}
case XFILL_GRADIENT:
{
sal_uInt16 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()) // kein temp. Eintrag ?
{
XGradient aGradient = pItem->GetGradientList()->GetGradient(nPos)->GetGradient();
XFillGradientItem aXFillGradientItem(mpLbFillAttr->GetSelectEntry(),aGradient);
aArgsFillAttr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillGradient"));
aXFillGradientItem.QueryValue(a);
aArgsFillAttr[0].Value = a;
aFillAttrCommand = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillGradient"));
}
}
break;
}
case XFILL_HATCH:
{
sal_uInt16 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()) // kein temp. Eintrag ?
{
XHatch aHatch = pItem->GetHatchList()->GetHatch(nPos)->GetHatch();
XFillHatchItem aXFillHatchItem(mpLbFillAttr->GetSelectEntry(),aHatch);
aArgsFillAttr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillHatch"));
aXFillHatchItem.QueryValue(a);
aArgsFillAttr[0].Value = a;
aFillAttrCommand = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".uno:FillHatch"));
}
}
break;
}
case XFILL_BITMAP:
{
sal_uInt16 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()) // kein temp. Eintrag ?
{
const XBitmapEntry* pXBitmapEntry = pItem->GetBitmapList()->GetBitmap(nPos);
const XFillBitmapItem aXFillBitmapItem(mpLbFillAttr->GetSelectEntry(),pXBitmapEntry->GetGraphicObject());
aArgsFillAttr[0].Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillBitmap"));
aXFillBitmapItem.QueryValue(a);
aArgsFillAttr[0].Value = a;
aFillAttrCommand = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".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()
{
// Breite der beiden ListBoxen nicht 1/2 : 1/2, sondern 2/5 : 3/5
long nW = GetOutputSizePixel().Width() / 5;
long nH = 180;
long nSep = 0; // war vorher 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(),
Max(aAttrSize.Height(),aTypeSize.Height())));
}
Window::DataChanged(rDCEvt);
}
//------------------------------------------------------------------------
//eof