merge the formfield patch from ooo-build
[ooovba.git] / svx / source / svdraw / svdetc.cxx
blobb01caa73f8646a275ccee926171b03834f3df921
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdetc.cxx,v $
10 * $Revision: 1.35.18.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include "forbiddencharacterstable.hxx"
34 #include <com/sun/star/embed/XEmbeddedObject.hpp>
35 #include <com/sun/star/embed/EmbedStates.hpp>
36 #include <svx/svdetc.hxx>
37 #include "svditext.hxx"
38 #include <svx/svdmodel.hxx>
39 #include <svx/svdtrans.hxx>
40 #include "svdglob.hxx"
41 #include "svdstr.hrc"
42 #include "svdviter.hxx"
43 #include <svx/svdview.hxx>
44 #include <svx/svdoutl.hxx>
45 #include <vcl/bmpacc.hxx>
46 #include <svx/eeitem.hxx>
47 #include <svtools/itemset.hxx>
48 #include <tools/config.hxx>
49 #include <svtools/cacheoptions.hxx>
50 #include <svtools/whiter.hxx>
51 #include <tools/bigint.hxx>
52 #include "fontitem.hxx"
53 #include <svx/colritem.hxx>
54 #include <svx/fhgtitem.hxx>
55 #include <svx/xgrad.hxx>
56 #include <svx/xfillit0.hxx>
57 #include <svx/xflclit.hxx>
58 #include <svx/xflhtit.hxx>
59 #include <svx/xbtmpit.hxx>
60 #include <svx/xflgrit.hxx>
61 #include <svx/svdoole2.hxx>
62 #include <svtools/itempool.hxx>
63 #include <unotools/localedatawrapper.hxx>
64 #include <com/sun/star/lang/Locale.hpp>
65 #include <comphelper/processfactory.hxx>
66 #include <i18npool/lang.h>
67 #include <unotools/charclass.hxx>
68 #include <svtools/syslocale.hxx>
69 #include <svx/xflbckit.hxx>
70 #include <svx/extrusionbar.hxx>
71 #include <svx/fontworkbar.hxx>
72 #include <vcl/svapp.hxx> //add CHINA001
73 #include <svx/sdr/contact/viewcontact.hxx>
74 #include <svx/svdpage.hxx>
75 #include <svx/svdotable.hxx>
76 #include <svx/sdrhittesthelper.hxx>
78 using namespace ::com::sun::star;
80 /******************************************************************************
81 * Globale Daten der DrawingEngine
82 ******************************************************************************/
84 SdrGlobalData::SdrGlobalData() :
85 pSysLocale(NULL),
86 pCharClass(NULL),
87 pLocaleData(NULL),
88 pOutliner(NULL),
89 pDefaults(NULL),
90 pResMgr(NULL),
91 nExchangeFormat(0)
93 //pSysLocale = new SvtSysLocale;
94 //pCharClass = pSysLocale->GetCharClassPtr();
95 //pLocaleData = pSysLocale->GetLocaleDataPtr();
97 svx::ExtrusionBar::RegisterInterface();
98 svx::FontworkBar::RegisterInterface();
101 SdrGlobalData::~SdrGlobalData()
103 delete pOutliner;
104 delete pDefaults;
105 delete pResMgr;
106 //! do NOT delete pCharClass and pLocaleData
107 delete pSysLocale;
109 const SvtSysLocale* SdrGlobalData::GetSysLocale()
111 if ( !pSysLocale )
112 pSysLocale = new SvtSysLocale;
113 return pSysLocale;
115 const CharClass* SdrGlobalData::GetCharClass()
117 if ( !pCharClass )
118 pCharClass = GetSysLocale()->GetCharClassPtr();
119 return pCharClass;
121 const LocaleDataWrapper* SdrGlobalData::GetLocaleData()
123 if ( !pLocaleData )
124 pLocaleData = GetSysLocale()->GetLocaleDataPtr();
125 return pLocaleData;
127 ////////////////////////////////////////////////////////////////////////////////////////////////////
129 OLEObjCache::OLEObjCache()
130 : Container( 0 )
132 SvtCacheOptions aCacheOptions;
134 nSize = aCacheOptions.GetDrawingEngineOLE_Objects();
135 pTimer = new AutoTimer();
136 Link aLink = LINK(this, OLEObjCache, UnloadCheckHdl);
138 pTimer->SetTimeoutHdl(aLink);
139 pTimer->SetTimeout(20000);
140 pTimer->Start();
142 aLink.Call(pTimer);
145 OLEObjCache::~OLEObjCache()
147 pTimer->Stop();
148 delete pTimer;
151 void OLEObjCache::UnloadOnDemand()
153 if ( nSize < Count() )
155 // more objects than configured cache size try to remove objects
156 // of course not the freshly inserted one at nIndex=0
157 ULONG nCount2 = Count();
158 ULONG nIndex = nCount2-1;
159 while( nIndex && nCount2 > nSize )
161 SdrOle2Obj* pUnloadObj = (SdrOle2Obj*) GetObject(nIndex--);
162 if ( pUnloadObj )
166 // it is important to get object without reinitialization to avoid reentrance
167 uno::Reference< embed::XEmbeddedObject > xUnloadObj = pUnloadObj->GetObjRef_NoInit();
169 sal_Bool bUnload = SdrOle2Obj::CanUnloadRunningObj( xUnloadObj, pUnloadObj->GetAspect() );
171 // check whether the object can be unloaded before looking for the parent objects
172 if ( xUnloadObj.is() && bUnload )
174 uno::Reference< frame::XModel > xUnloadModel( xUnloadObj->getComponent(), uno::UNO_QUERY );
175 if ( xUnloadModel.is() )
177 for ( ULONG nCheckInd = 0; nCheckInd < Count(); nCheckInd++ )
179 SdrOle2Obj* pCacheObj = (SdrOle2Obj*) GetObject(nCheckInd);
180 if ( pCacheObj && pCacheObj != pUnloadObj )
182 uno::Reference< frame::XModel > xParentModel = pCacheObj->GetParentXModel();
183 if ( xUnloadModel == xParentModel )
184 bUnload = sal_False; // the object has running embedded objects
190 if ( bUnload && UnloadObj(pUnloadObj) )
191 // object was successfully unloaded
192 nCount2--;
194 catch( uno::Exception& )
201 void OLEObjCache::SetSize(ULONG nNewSize)
203 nSize = nNewSize;
206 void OLEObjCache::InsertObj(SdrOle2Obj* pObj)
208 if ( Count() )
210 SdrOle2Obj* pExistingObj = (SdrOle2Obj*)GetObject( 0 );
211 if ( pObj == pExistingObj )
212 // the object is already on the top, nothing has to be changed
213 return;
216 // get the old position of the object to know whether it is already in container
217 ULONG nOldPos = GetPos( pObj );
219 // insert object into first position
220 Remove( nOldPos );
221 Insert(pObj, (ULONG) 0L);
223 if ( nOldPos == CONTAINER_ENTRY_NOTFOUND )
225 // a new object was inserted, recalculate the cache
226 UnloadOnDemand();
230 void OLEObjCache::RemoveObj(SdrOle2Obj* pObj)
232 Remove(pObj);
235 BOOL OLEObjCache::UnloadObj(SdrOle2Obj* pObj)
237 BOOL bUnloaded = FALSE;
238 if (pObj)
240 //#i80528# The old mechanism is completely useless, only taking into account if
241 // in all views the GrafDraft feature is used. This will nearly never have been the
242 // case since no one ever used this option.
244 // A much better (and working) criteria would be the VOC contact count.
245 // The quesion is what will happen whe i make it work now suddenly? I
246 // will try it for 2.4.
247 const sdr::contact::ViewContact& rViewContact = pObj->GetViewContact();
248 const bool bVisible(rViewContact.HasViewObjectContacts(true));
250 if(!bVisible)
252 bUnloaded = pObj->Unload();
256 return bUnloaded;
259 IMPL_LINK(OLEObjCache, UnloadCheckHdl, AutoTimer*, /*pTim*/)
261 UnloadOnDemand();
262 return 0;
265 void ContainerSorter::DoSort(ULONG a, ULONG b) const
267 ULONG nAnz=rCont.Count();
268 if (b>nAnz) b=nAnz;
269 if (b>0) b--;
270 if (a<b) ImpSubSort(a,b);
273 void ContainerSorter::Is1stLessThan2nd(const void* /*pElem1*/, const void* /*pElem2*/) const
277 void ContainerSorter::ImpSubSort(long nL, long nR) const
279 long i,j;
280 const void* pX;
281 void* pI;
282 void* pJ;
283 i=nL;
284 j=nR;
285 pX=rCont.GetObject((nL+nR)/2);
286 do {
287 pI=rCont.Seek(i);
288 while (pI!=pX && Compare(pI,pX)<0) { i++; pI=rCont.Next(); }
289 pJ=rCont.Seek(j);
290 while (pJ!=pX && Compare(pX,pJ)<0) { j--; pJ=rCont.Prev(); }
291 if (i<=j) {
292 rCont.Replace(pJ,i);
293 rCont.Replace(pI,j);
294 i++;
295 j--;
297 } while (i<=j);
298 if (nL<j) ImpSubSort(nL,j);
299 if (i<nR) ImpSubSort(i,nR);
302 ////////////////////////////////////////////////////////////////////////////////////////////////////
304 class ImpUShortContainerSorter: public ContainerSorter {
305 public:
306 ImpUShortContainerSorter(Container& rNewCont): ContainerSorter(rNewCont) {}
307 virtual int Compare(const void* pElem1, const void* pElem2) const;
310 int ImpUShortContainerSorter::Compare(const void* pElem1, const void* pElem2) const
312 USHORT n1=USHORT(ULONG(pElem1));
313 USHORT n2=USHORT(ULONG(pElem2));
314 return n1<n2 ? -1 : n1>n2 ? 1 : 0;
317 void UShortCont::Sort()
319 ImpUShortContainerSorter aSorter(aArr);
320 aSorter.DoSort();
323 ////////////////////////////////////////////////////////////////////////////////////////////////////
325 class ImpClipMerk {
326 Region aClip;
327 FASTBOOL bClip;
328 public:
329 ImpClipMerk(const OutputDevice& rOut): aClip(rOut.GetClipRegion()),bClip(rOut.IsClipRegion()) {}
330 void Restore(OutputDevice& rOut)
332 // Kein Clipping in die Metafileaufzeichnung
333 GDIMetaFile* pMtf=rOut.GetConnectMetaFile();
334 if (pMtf!=NULL && (!pMtf->IsRecord() || pMtf->IsPause())) pMtf=NULL;
335 if (pMtf!=NULL) pMtf->Pause(TRUE);
336 if (bClip) rOut.SetClipRegion(aClip);
337 else rOut.SetClipRegion();
338 if (pMtf!=NULL) pMtf->Pause(FALSE);
342 class ImpColorMerk {
343 Color aLineColor;
344 Color aFillColor;
345 Color aBckgrdColor;
346 Font aFont;
347 public:
348 ImpColorMerk(const OutputDevice& rOut):
349 aLineColor( rOut.GetLineColor() ),
350 aFillColor( rOut.GetFillColor() ),
351 aBckgrdColor( rOut.GetBackground().GetColor() ),
352 aFont (rOut.GetFont()) {}
354 ImpColorMerk(const OutputDevice& rOut, USHORT nMode)
356 if ( (nMode & SDRHDC_SAVEPEN) == SDRHDC_SAVEPEN )
357 aLineColor = rOut.GetLineColor();
359 if ( (nMode & SDRHDC_SAVEBRUSH) == SDRHDC_SAVEBRUSH)
361 aFillColor = rOut.GetFillColor();
362 aBckgrdColor = rOut.GetBackground().GetColor();
365 if ( (nMode & SDRHDC_SAVEFONT) == SDRHDC_SAVEFONT)
366 aFont=rOut.GetFont();
369 void Restore(OutputDevice& rOut, USHORT nMode=SDRHDC_SAVEPENANDBRUSHANDFONT)
371 if ( (nMode & SDRHDC_SAVEPEN) == SDRHDC_SAVEPEN)
372 rOut.SetLineColor( aLineColor );
374 if ( (nMode & SDRHDC_SAVEBRUSH) == SDRHDC_SAVEBRUSH)
376 rOut.SetFillColor( aFillColor );
377 rOut.SetBackground( Wallpaper( aBckgrdColor ) );
379 if ((nMode & SDRHDC_SAVEFONT) ==SDRHDC_SAVEFONT)
381 if (!rOut.GetFont().IsSameInstance(aFont))
383 rOut.SetFont(aFont);
388 const Color& GetLineColor() const { return aLineColor; }
391 ImpSdrHdcMerk::ImpSdrHdcMerk(const OutputDevice& rOut, USHORT nNewMode, FASTBOOL bAutoMerk):
392 pFarbMerk(NULL),
393 pClipMerk(NULL),
394 pLineColorMerk(NULL),
395 nMode(nNewMode)
397 if (bAutoMerk) Save(rOut);
400 ImpSdrHdcMerk::~ImpSdrHdcMerk()
402 if (pFarbMerk!=NULL) delete pFarbMerk;
403 if (pClipMerk!=NULL) delete pClipMerk;
404 if (pLineColorMerk !=NULL) delete pLineColorMerk;
407 void ImpSdrHdcMerk::Save(const OutputDevice& rOut)
409 if (pFarbMerk!=NULL)
411 delete pFarbMerk;
412 pFarbMerk=NULL;
414 if (pClipMerk!=NULL)
416 delete pClipMerk;
417 pClipMerk=NULL;
419 if (pLineColorMerk !=NULL)
421 delete pLineColorMerk ;
422 pLineColorMerk =NULL;
424 if ((nMode & SDRHDC_SAVECLIPPING) ==SDRHDC_SAVECLIPPING)
425 pClipMerk=new ImpClipMerk(rOut);
427 USHORT nCol=nMode & SDRHDC_SAVEPENANDBRUSHANDFONT;
429 if (nCol==SDRHDC_SAVEPEN)
430 pLineColorMerk=new Color( rOut.GetLineColor() );
431 else if (nCol==SDRHDC_SAVEPENANDBRUSHANDFONT)
432 pFarbMerk=new ImpColorMerk(rOut);
433 else if (nCol!=0)
434 pFarbMerk=new ImpColorMerk(rOut,nCol);
437 void ImpSdrHdcMerk::Restore(OutputDevice& rOut, USHORT nMask) const
439 nMask&=nMode; // nur restaurieren, was auch gesichert wurde
441 if ((nMask & SDRHDC_SAVECLIPPING) ==SDRHDC_SAVECLIPPING && pClipMerk!=NULL)
442 pClipMerk->Restore(rOut);
444 USHORT nCol=nMask & SDRHDC_SAVEPENANDBRUSHANDFONT;
446 if (nCol==SDRHDC_SAVEPEN)
448 if (pLineColorMerk!=NULL)
449 rOut.SetLineColor(*pLineColorMerk);
450 else if (pFarbMerk!=NULL)
451 rOut.SetLineColor( pFarbMerk->GetLineColor() );
452 } else if (nCol!=0 && pFarbMerk!=NULL)
453 pFarbMerk->Restore(rOut,nCol);
456 ////////////////////////////////////////////////////////////////////////////////////////////////////
458 void SdrLinkList::Clear()
460 unsigned nAnz=GetLinkCount();
461 for (unsigned i=0; i<nAnz; i++) {
462 delete (Link*)aList.GetObject(i);
464 aList.Clear();
467 unsigned SdrLinkList::FindEntry(const Link& rLink) const
469 unsigned nAnz=GetLinkCount();
470 for (unsigned i=0; i<nAnz; i++) {
471 if (GetLink(i)==rLink) return i;
473 return 0xFFFF;
476 void SdrLinkList::InsertLink(const Link& rLink, unsigned nPos)
478 unsigned nFnd=FindEntry(rLink);
479 if (nFnd==0xFFFF) {
480 if (rLink.IsSet()) {
481 aList.Insert(new Link(rLink),nPos);
482 } else {
483 DBG_ERROR("SdrLinkList::InsertLink(): Versuch, einen nicht gesetzten Link einzufuegen");
485 } else {
486 DBG_ERROR("SdrLinkList::InsertLink(): Link schon vorhanden");
490 void SdrLinkList::RemoveLink(const Link& rLink)
492 unsigned nFnd=FindEntry(rLink);
493 if (nFnd!=0xFFFF) {
494 Link* pLink=(Link*)aList.Remove(nFnd);
495 delete pLink;
496 } else {
497 DBG_ERROR("SdrLinkList::RemoveLink(): Link nicht gefunden");
501 ////////////////////////////////////////////////////////////////////////////////////////////////////
502 // #98988# Re-implement GetDraftFillColor(...)
504 FASTBOOL GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
506 XFillStyle eFill=((XFillStyleItem&)rSet.Get(XATTR_FILLSTYLE)).GetValue();
507 FASTBOOL bRetval(FALSE);
509 switch(eFill)
511 case XFILL_SOLID:
513 rCol = ((XFillColorItem&)rSet.Get(XATTR_FILLCOLOR)).GetColorValue();
514 bRetval = TRUE;
516 break;
518 case XFILL_HATCH:
520 Color aCol1(((XFillHatchItem&)rSet.Get(XATTR_FILLHATCH)).GetHatchValue().GetColor());
521 Color aCol2(COL_WHITE);
523 // #97870# when hatch background is activated, use object fill color as hatch color
524 sal_Bool bFillHatchBackground = ((const XFillBackgroundItem&)(rSet.Get(XATTR_FILLBACKGROUND))).GetValue();
525 if(bFillHatchBackground)
527 aCol2 = ((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue();
530 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
531 rCol = Color(aAverageColor);
532 bRetval = TRUE;
534 break;
536 case XFILL_GRADIENT: {
537 const XGradient& rGrad=((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
538 Color aCol1(rGrad.GetStartColor());
539 Color aCol2(rGrad.GetEndColor());
540 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
541 rCol = Color(aAverageColor);
542 bRetval = TRUE;
544 break;
546 case XFILL_BITMAP:
548 const Bitmap& rBitmap = ((XFillBitmapItem&)rSet.Get(XATTR_FILLBITMAP)).GetBitmapValue().GetBitmap();
549 const Size aSize(rBitmap.GetSizePixel());
550 const sal_uInt32 nWidth = aSize.Width();
551 const sal_uInt32 nHeight = aSize.Height();
552 Bitmap aBitmap(rBitmap);
553 BitmapReadAccess* pAccess = aBitmap.AcquireReadAccess();
555 if(pAccess && nWidth > 0 && nHeight > 0)
557 sal_uInt32 nRt(0L);
558 sal_uInt32 nGn(0L);
559 sal_uInt32 nBl(0L);
560 const sal_uInt32 nMaxSteps(8L);
561 const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1L);
562 const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1L);
563 sal_uInt32 nAnz(0L);
565 for(sal_uInt32 nY(0L); nY < nHeight; nY += nYStep)
567 for(sal_uInt32 nX(0L); nX < nWidth; nX += nXStep)
569 const BitmapColor& rCol2 = (pAccess->HasPalette())
570 ? pAccess->GetPaletteColor((BYTE)pAccess->GetPixel(nY, nX))
571 : pAccess->GetPixel(nY, nX);
573 nRt += rCol2.GetRed();
574 nGn += rCol2.GetGreen();
575 nBl += rCol2.GetBlue();
576 nAnz++;
580 nRt /= nAnz;
581 nGn /= nAnz;
582 nBl /= nAnz;
584 rCol = Color(UINT8(nRt), UINT8(nGn), UINT8(nBl));
586 bRetval = TRUE;
589 if(pAccess)
591 aBitmap.ReleaseAccess(pAccess);
594 break;
596 default: break;
599 return bRetval;
602 ////////////////////////////////////////////////////////////////////////////////////////////////////
604 SdrEngineDefaults::SdrEngineDefaults():
605 aFontName( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ).GetName() ),
606 eFontFamily(FAMILY_ROMAN),
607 aFontColor(COL_AUTO),
608 nFontHeight(847), // 847/100mm = ca. 24 Point
609 eMapUnit(MAP_100TH_MM),
610 aMapFraction(1,1)
614 SdrEngineDefaults& SdrEngineDefaults::GetDefaults()
616 SdrGlobalData& rGlobalData=GetSdrGlobalData();
617 if (rGlobalData.pDefaults==NULL) {
618 rGlobalData.pDefaults=new SdrEngineDefaults;
620 return *rGlobalData.pDefaults;
623 ////////////////////////////////////////////////////////////////////////////////////////////////////
625 void SdrEngineDefaults::LanguageHasChanged()
627 SdrGlobalData& rGlobalData=GetSdrGlobalData();
628 if (rGlobalData.pResMgr!=NULL) {
629 delete rGlobalData.pResMgr;
630 rGlobalData.pResMgr=NULL;
634 ////////////////////////////////////////////////////////////////////////////////////////////////////
636 SdrOutliner* SdrMakeOutliner( USHORT nOutlinerMode, SdrModel* pModel )
638 //SdrEngineDefaults& rDefaults = SdrEngineDefaults::GetDefaults();
640 SfxItemPool* pPool = &pModel->GetItemPool();
641 SdrOutliner* pOutl = new SdrOutliner( pPool, nOutlinerMode );
642 pOutl->SetEditTextObjectPool( pPool );
643 pOutl->SetStyleSheetPool( (SfxStyleSheetPool*) pModel->GetStyleSheetPool() );
644 pOutl->SetDefTab( pModel->GetDefaultTabulator() );
645 pOutl->SetForbiddenCharsTable( pModel->GetForbiddenCharsTable() );
646 pOutl->SetAsianCompressionMode( pModel->GetCharCompressType() );
647 pOutl->SetKernAsianPunctuation( pModel->IsKernAsianPunctuation() );
648 pOutl->SetAddExtLeading( pModel->IsAddExtLeading() );
650 return pOutl;
653 ////////////////////////////////////////////////////////////////////////////////////////////////////
656 SdrLinkList& ImpGetUserMakeObjHdl()
658 SdrGlobalData& rGlobalData=GetSdrGlobalData();
659 return rGlobalData.aUserMakeObjHdl;
662 SdrLinkList& ImpGetUserMakeObjUserDataHdl()
664 SdrGlobalData& rGlobalData=GetSdrGlobalData();
665 return rGlobalData.aUserMakeObjUserDataHdl;
668 ////////////////////////////////////////////////////////////////////////////////////////////////////
670 ResMgr* ImpGetResMgr()
672 SdrGlobalData& rGlobalData = GetSdrGlobalData();
674 if(!rGlobalData.pResMgr)
676 ByteString aName("svx");
677 rGlobalData.pResMgr =
678 ResMgr::CreateResMgr( aName.GetBuffer(), Application::GetSettings().GetUILocale() );
681 return rGlobalData.pResMgr;
684 ////////////////////////////////////////////////////////////////////////////////////////////////////
686 String ImpGetResStr(sal_uInt16 nResID)
688 return String(ResId(nResID, *ImpGetResMgr()));
691 ////////////////////////////////////////////////////////////////////////////////////////////////////
693 namespace sdr
695 String GetResourceString(sal_uInt16 nResID)
697 return ImpGetResStr( nResID );
701 ////////////////////////////////////////////////////////////////////////////////////////////////////
703 BOOL SearchOutlinerItems(const SfxItemSet& rSet, BOOL bInklDefaults, BOOL* pbOnlyEE)
705 BOOL bHas=FALSE;
706 BOOL bOnly=TRUE;
707 BOOL bLookOnly=pbOnlyEE!=NULL;
708 SfxWhichIter aIter(rSet);
709 USHORT nWhich=aIter.FirstWhich();
710 while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) {
711 // bei bInklDefaults ist der gesamte Which-Range
712 // ausschlaggebend, ansonsten nur die gesetzten Items
713 // Disabled und DontCare wird als Loch im Which-Range betrachtet
714 SfxItemState eState=rSet.GetItemState(nWhich);
715 if ((eState==SFX_ITEM_DEFAULT && bInklDefaults) || eState==SFX_ITEM_SET) {
716 if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=FALSE;
717 else bHas=TRUE;
719 nWhich=aIter.NextWhich();
721 if (!bHas) bOnly=FALSE;
722 if (pbOnlyEE!=NULL) *pbOnlyEE=bOnly;
723 return bHas;
726 USHORT* RemoveWhichRange(const USHORT* pOldWhichTable, USHORT nRangeBeg, USHORT nRangeEnd)
728 // insgesamt sind 6 Faelle moeglich (je Range):
729 // [Beg..End] zu entfernender Range
730 // [b..e] [b..e] [b..e] Fall 1,3,2: egal, ganz weg, egal + Ranges
731 // [b........e] [b........e] Fall 4,5 : Bereich verkleinern | in
732 // [b......................e] Fall 6 : Splitting + pOldWhichTable
733 USHORT nAnz=0;
734 while (pOldWhichTable[nAnz]!=0) nAnz++;
735 nAnz++; // nAnz muesste nun in jedem Fall eine ungerade Zahl sein (0 am Ende des Arrays)
736 DBG_ASSERT((nAnz&1)==1,"Joe: RemoveWhichRange: WhichTable hat keine ungerade Anzahl von Eintraegen");
737 USHORT nAlloc=nAnz;
738 // benoetigte Groesse des neuen Arrays ermitteln
739 USHORT nNum=nAnz-1;
740 while (nNum!=0) {
741 nNum-=2;
742 USHORT nBeg=pOldWhichTable[nNum];
743 USHORT nEnd=pOldWhichTable[nNum+1];
744 if (nEnd<nRangeBeg) /*nCase=1*/ ;
745 else if (nBeg>nRangeEnd) /* nCase=2 */ ;
746 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2;
747 else if (nEnd<=nRangeEnd) /* nCase=4 */;
748 else if (nBeg>=nRangeBeg) /* nCase=5*/ ;
749 else /* nCase=6 */ nAlloc+=2;
752 USHORT* pNewWhichTable=new USHORT[nAlloc];
753 memcpy(pNewWhichTable,pOldWhichTable,nAlloc*sizeof(USHORT));
754 pNewWhichTable[nAlloc-1]=0; // im Falle 3 fehlt die 0 am Ende
755 // nun die unerwuenschten Ranges entfernen
756 nNum=nAlloc-1;
757 while (nNum!=0) {
758 nNum-=2;
759 USHORT nBeg=pNewWhichTable[nNum];
760 USHORT nEnd=pNewWhichTable[nNum+1];
761 unsigned nCase=0;
762 if (nEnd<nRangeBeg) nCase=1;
763 else if (nBeg>nRangeEnd) nCase=2;
764 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3;
765 else if (nEnd<=nRangeEnd) nCase=4;
766 else if (nBeg>=nRangeBeg) nCase=5;
767 else nCase=6;
768 switch (nCase) {
769 case 3: {
770 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(USHORT);
771 memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes);
772 nAnz-=2; // Merken: Array hat sich verkleinert
773 } break;
774 case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break;
775 case 5: pNewWhichTable[nNum]=nRangeEnd+1; break;
776 case 6: {
777 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(USHORT);
778 memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes);
779 nAnz+=2; // Merken: Array hat sich vergroessert
780 pNewWhichTable[nNum+2]=nRangeEnd+1;
781 pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1];
782 pNewWhichTable[nNum+1]=nRangeBeg-1;
783 } break;
784 } // switch
786 return pNewWhichTable;
789 ////////////////////////////////////////////////////////////////////////////////////////////////////
791 SvdProgressInfo::SvdProgressInfo( Link *_pLink )
793 DBG_ASSERT(_pLink!=NULL,"SvdProgressInfo(): Kein Link angegeben!!");
795 pLink = _pLink;
796 nSumActionCount = 0;
797 nSumCurAction = 0;
799 nObjCount = 0;
800 nCurObj = 0;
802 nActionCount = 0;
803 nCurAction = 0;
805 nInsertCount = 0;
806 nCurInsert = 0;
809 void SvdProgressInfo::Init( ULONG _nSumActionCount, ULONG _nObjCount )
811 nSumActionCount = _nSumActionCount;
812 nObjCount = _nObjCount;
815 BOOL SvdProgressInfo::ReportActions( ULONG nAnzActions )
817 nSumCurAction += nAnzActions;
818 nCurAction += nAnzActions;
819 if(nCurAction > nActionCount)
820 nCurAction = nActionCount;
822 return pLink->Call(NULL) == 1L;
825 BOOL SvdProgressInfo::ReportInserts( ULONG nAnzInserts )
827 nSumCurAction += nAnzInserts;
828 nCurInsert += nAnzInserts;
830 return pLink->Call(NULL) == 1L;
833 BOOL SvdProgressInfo::ReportRescales( ULONG nAnzRescales )
835 nSumCurAction += nAnzRescales;
836 return pLink->Call(NULL) == 1L;
839 void SvdProgressInfo::SetActionCount( ULONG _nActionCount )
841 nActionCount = _nActionCount;
844 void SvdProgressInfo::SetInsertCount( ULONG _nInsertCount )
846 nInsertCount = _nInsertCount;
849 BOOL SvdProgressInfo::SetNextObject()
851 nActionCount = 0;
852 nCurAction = 0;
854 nInsertCount = 0;
855 nCurInsert = 0;
857 nCurObj++;
858 return ReportActions(0);
861 void SvdProgressInfo::ReportError()
863 pLink->Call((void *)1L);
866 ////////////////////////////////////////////////////////////////////////////////////////////////////
867 // #i101872# isolate GetTextEditBackgroundColor to tooling; it woll anyways only be used as long
868 // as text edit is not running on overlay
870 namespace
872 bool impGetSdrObjListFillColor(
873 const SdrObjList& rList,
874 const Point& rPnt,
875 const SdrPageView& rTextEditPV,
876 const SetOfByte& rVisLayers,
877 Color& rCol)
879 if(!rList.GetModel())
880 return false;
882 bool bRet(false);
883 bool bMaster(rList.GetPage() ? rList.GetPage()->IsMasterPage() : false);
885 for(ULONG no(rList.GetObjCount()); !bRet && no > 0; )
887 no--;
888 SdrObject* pObj = rList.GetObj(no);
889 SdrObjList* pOL = pObj->GetSubList();
891 if(pOL)
893 // group object
894 bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol);
896 else
898 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj);
900 // #108867# Exclude zero master page object (i.e. background shape) from color query
901 if(pText
902 && pObj->IsClosedObj()
903 && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
904 && pObj->GetCurrentBoundRect().IsInside(rPnt)
905 && !pText->IsHideContour()
906 && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
908 bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
913 return bRet;
916 bool impGetSdrPageFillColor(
917 const SdrPage& rPage,
918 const Point& rPnt,
919 const SdrPageView& rTextEditPV,
920 const SetOfByte& rVisLayers,
921 Color& rCol,
922 bool bSkipBackgroundShape)
924 if(!rPage.GetModel())
925 return false;
927 bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol));
929 if(!bRet && !rPage.IsMasterPage())
931 if(rPage.TRG_HasMasterPage())
933 SetOfByte aSet(rVisLayers);
934 aSet &= rPage.TRG_GetMasterPageVisibleLayers();
935 SdrPage& rMasterPage = rPage.TRG_GetMasterPage();
937 // #108867# Don't fall back to background shape on
938 // master pages. This is later handled by
939 // GetBackgroundColor, and is necessary to cater for
940 // the silly ordering: 1. shapes, 2. master page
941 // shapes, 3. page background, 4. master page
942 // background.
943 bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true);
947 // #108867# Only now determine background color from background shapes
948 if(!bRet && !bSkipBackgroundShape)
950 rCol = rPage.GetPageBackgroundColor();
951 return true;
954 return bRet;
957 Color impCalcBackgroundColor(
958 const Rectangle& rArea,
959 const SdrPageView& rTextEditPV,
960 const SdrPage& rPage)
962 svtools::ColorConfig aColorConfig;
963 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
964 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
966 if(!rStyleSettings.GetHighContrastMode())
968 // search in page
969 const USHORT SPOTCOUNT(5);
970 Point aSpotPos[SPOTCOUNT];
971 Color aSpotColor[SPOTCOUNT];
972 ULONG nHeight( rArea.GetSize().Height() );
973 ULONG nWidth( rArea.GetSize().Width() );
974 ULONG nWidth14 = nWidth / 4;
975 ULONG nHeight14 = nHeight / 4;
976 ULONG nWidth34 = ( 3 * nWidth ) / 4;
977 ULONG nHeight34 = ( 3 * nHeight ) / 4;
979 USHORT i;
980 for ( i = 0; i < SPOTCOUNT; i++ )
982 // five spots are used
983 switch ( i )
985 case 0 :
987 // Center-Spot
988 aSpotPos[i] = rArea.Center();
990 break;
992 case 1 :
994 // TopLeft-Spot
995 aSpotPos[i] = rArea.TopLeft();
996 aSpotPos[i].X() += nWidth14;
997 aSpotPos[i].Y() += nHeight14;
999 break;
1001 case 2 :
1003 // TopRight-Spot
1004 aSpotPos[i] = rArea.TopLeft();
1005 aSpotPos[i].X() += nWidth34;
1006 aSpotPos[i].Y() += nHeight14;
1008 break;
1010 case 3 :
1012 // BottomLeft-Spot
1013 aSpotPos[i] = rArea.TopLeft();
1014 aSpotPos[i].X() += nWidth14;
1015 aSpotPos[i].Y() += nHeight34;
1017 break;
1019 case 4 :
1021 // BottomRight-Spot
1022 aSpotPos[i] = rArea.TopLeft();
1023 aSpotPos[i].X() += nWidth34;
1024 aSpotPos[i].Y() += nHeight34;
1026 break;
1030 aSpotColor[i] = Color( COL_WHITE );
1031 impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false);
1034 USHORT aMatch[SPOTCOUNT];
1036 for ( i = 0; i < SPOTCOUNT; i++ )
1038 // were same spot colors found?
1039 aMatch[i] = 0;
1041 for ( USHORT j = 0; j < SPOTCOUNT; j++ )
1043 if( j != i )
1045 if( aSpotColor[i] == aSpotColor[j] )
1047 aMatch[i]++;
1053 // highest weight to center spot
1054 aBackground = aSpotColor[0];
1056 for ( USHORT nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- )
1058 // which spot color was found most?
1059 for ( i = 0; i < SPOTCOUNT; i++ )
1061 if( aMatch[i] == nMatchCount )
1063 aBackground = aSpotColor[i];
1064 nMatchCount = 1; // break outer for-loop
1065 break;
1071 return aBackground;
1073 } // end of anonymous namespace
1075 Color GetTextEditBackgroundColor(const SdrObjEditView& rView)
1077 svtools::ColorConfig aColorConfig;
1078 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
1079 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1081 if(!rStyleSettings.GetHighContrastMode())
1083 bool bFound(false);
1084 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(rView.GetTextEditObject());
1086 if(pText && pText->IsClosedObj())
1088 ::sdr::table::SdrTableObj* pTable = dynamic_cast< ::sdr::table::SdrTableObj * >( pText );
1090 if( pTable )
1091 bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground );
1093 if( !bFound )
1094 bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground);
1097 if(!bFound && pText)
1099 SdrPageView* pTextEditPV = rView.GetTextEditPageView();
1101 if(pTextEditPV)
1103 Point aPvOfs(pText->GetTextEditOffset());
1104 const SdrPage* pPg = pTextEditPV->GetPage();
1106 if(pPg)
1108 Rectangle aSnapRect( pText->GetSnapRect() );
1109 aSnapRect.Move(aPvOfs.X(), aPvOfs.Y());
1111 return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg);
1117 return aBackground;
1120 ////////////////////////////////////////////////////////////////////////////////////////////////////
1121 // eof