/************************************************************** * * 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 // HACK: prevent conflict between STLPORT and Workshop headers #include #include #include #include #include #include #define TMP_STR_BEGIN '[' #define TMP_STR_END ']' #include "svx/drawitem.hxx" #include "svx/xattr.hxx" #include #include #include #include #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(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