| /************************************************************** |
| * |
| * 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 |