Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / svx / source / svdraw / svdetc.cxx
blobc561e82f5895b93034161b47cd3d2ae671f38e83
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "sal/config.h"
31 #include "editeng/forbiddencharacterstable.hxx"
32 #include <com/sun/star/embed/XEmbeddedObject.hpp>
33 #include <com/sun/star/embed/EmbedStates.hpp>
34 #include "officecfg/Office/Common.hxx"
35 #include <svx/svdetc.hxx>
36 #include "svx/svditext.hxx"
37 #include <svx/svdmodel.hxx>
38 #include <svx/svdtrans.hxx>
39 #include "svx/svdglob.hxx"
40 #include "svx/svdstr.hrc"
41 #include "svx/svdviter.hxx"
42 #include <svx/svdview.hxx>
43 #include <svx/svdoutl.hxx>
44 #include <vcl/bmpacc.hxx>
45 #include <editeng/eeitem.hxx>
46 #include <svl/itemset.hxx>
47 #include <svl/whiter.hxx>
48 #include "editeng/fontitem.hxx"
49 #include <editeng/colritem.hxx>
50 #include <editeng/fhgtitem.hxx>
51 #include <svx/xgrad.hxx>
52 #include <svx/xfillit0.hxx>
53 #include <svx/xflclit.hxx>
54 #include <svx/xflhtit.hxx>
55 #include <svx/xbtmpit.hxx>
56 #include <svx/xflgrit.hxx>
57 #include <svx/svdoole2.hxx>
58 #include <svl/itempool.hxx>
59 #include <unotools/localedatawrapper.hxx>
60 #include <com/sun/star/lang/Locale.hpp>
61 #include <i18npool/lang.h>
62 #include <unotools/charclass.hxx>
63 #include <unotools/syslocale.hxx>
64 #include <svx/xflbckit.hxx>
65 #include <svx/extrusionbar.hxx>
66 #include <svx/fontworkbar.hxx>
67 #include <vcl/svapp.hxx>
68 #include <svx/sdr/contact/viewcontact.hxx>
69 #include <svx/svdpage.hxx>
70 #include <svx/svdotable.hxx>
71 #include <svx/sdrhittesthelper.hxx>
73 using namespace ::com::sun::star;
75 /******************************************************************************
76 * Global data of the DrawingEngine
77 ******************************************************************************/
79 SdrGlobalData::SdrGlobalData() :
80 pSysLocale(NULL),
81 pCharClass(NULL),
82 pLocaleData(NULL),
83 pOutliner(NULL),
84 pDefaults(NULL),
85 pResMgr(NULL),
86 nExchangeFormat(0)
89 svx::ExtrusionBar::RegisterInterface();
90 svx::FontworkBar::RegisterInterface();
93 const SvtSysLocale* SdrGlobalData::GetSysLocale()
95 if ( !pSysLocale )
96 pSysLocale = new SvtSysLocale;
97 return pSysLocale;
99 const LocaleDataWrapper* SdrGlobalData::GetLocaleData()
101 if ( !pLocaleData )
102 pLocaleData = GetSysLocale()->GetLocaleDataPtr();
103 return pLocaleData;
105 ////////////////////////////////////////////////////////////////////////////////////////////////////
107 OLEObjCache::OLEObjCache()
108 : Container( 0 )
110 nSize = officecfg::Office::Common::Cache::DrawingEngine::OLE_Objects::get();
111 pTimer = new AutoTimer();
112 Link aLink = LINK(this, OLEObjCache, UnloadCheckHdl);
114 pTimer->SetTimeoutHdl(aLink);
115 pTimer->SetTimeout(20000);
116 pTimer->Start();
118 aLink.Call(pTimer);
121 OLEObjCache::~OLEObjCache()
123 pTimer->Stop();
124 delete pTimer;
127 void OLEObjCache::UnloadOnDemand()
129 if ( nSize < Count() )
131 // more objects than configured cache size try to remove objects
132 // of course not the freshly inserted one at nIndex=0
133 sal_uIntPtr nCount2 = Count();
134 sal_uIntPtr nIndex = nCount2-1;
135 while( nIndex && nCount2 > nSize )
137 SdrOle2Obj* pUnloadObj = (SdrOle2Obj*) GetObject(nIndex--);
138 if ( pUnloadObj )
142 // it is important to get object without reinitialization to avoid reentrance
143 uno::Reference< embed::XEmbeddedObject > xUnloadObj = pUnloadObj->GetObjRef_NoInit();
145 sal_Bool bUnload = SdrOle2Obj::CanUnloadRunningObj( xUnloadObj, pUnloadObj->GetAspect() );
147 // check whether the object can be unloaded before looking for the parent objects
148 if ( xUnloadObj.is() && bUnload )
150 uno::Reference< frame::XModel > xUnloadModel( xUnloadObj->getComponent(), uno::UNO_QUERY );
151 if ( xUnloadModel.is() )
153 for ( sal_uIntPtr nCheckInd = 0; nCheckInd < Count(); nCheckInd++ )
155 SdrOle2Obj* pCacheObj = (SdrOle2Obj*) GetObject(nCheckInd);
156 if ( pCacheObj && pCacheObj != pUnloadObj )
158 uno::Reference< frame::XModel > xParentModel = pCacheObj->GetParentXModel();
159 if ( xUnloadModel == xParentModel )
160 bUnload = sal_False; // the object has running embedded objects
166 if ( bUnload && UnloadObj(pUnloadObj) )
167 // object was successfully unloaded
168 nCount2--;
170 catch( uno::Exception& )
177 void OLEObjCache::InsertObj(SdrOle2Obj* pObj)
179 if ( Count() )
181 SdrOle2Obj* pExistingObj = (SdrOle2Obj*)GetObject( 0 );
182 if ( pObj == pExistingObj )
183 // the object is already on the top, nothing has to be changed
184 return;
187 // get the old position of the object to know whether it is already in container
188 sal_uIntPtr nOldPos = GetPos( pObj );
190 // insert object into first position
191 Remove( nOldPos );
192 Insert(pObj, (sal_uIntPtr) 0L);
194 if ( nOldPos == CONTAINER_ENTRY_NOTFOUND )
196 // a new object was inserted, recalculate the cache
197 UnloadOnDemand();
201 void OLEObjCache::RemoveObj(SdrOle2Obj* pObj)
203 Remove(pObj);
206 sal_Bool OLEObjCache::UnloadObj(SdrOle2Obj* pObj)
208 sal_Bool bUnloaded = sal_False;
209 if (pObj)
211 //#i80528# The old mechanism is completely useless, only taking into account if
212 // in all views the GrafDraft feature is used. This will nearly never have been the
213 // case since no one ever used this option.
215 // A much better (and working) criteria would be the VOC contact count.
216 // The question is what will happen when i make it work now suddenly? I
217 // will try it for 2.4.
218 const sdr::contact::ViewContact& rViewContact = pObj->GetViewContact();
219 const bool bVisible(rViewContact.HasViewObjectContacts(true));
221 if(!bVisible)
223 bUnloaded = pObj->Unload();
227 return bUnloaded;
230 IMPL_LINK(OLEObjCache, UnloadCheckHdl, AutoTimer*, /*pTim*/)
232 UnloadOnDemand();
233 return 0;
236 void ContainerSorter::DoSort(sal_uIntPtr a, sal_uIntPtr b) const
238 sal_uIntPtr nAnz=rCont.Count();
239 if (b>nAnz) b=nAnz;
240 if (b>0) b--;
241 if (a<b) ImpSubSort(a,b);
244 void ContainerSorter::Is1stLessThan2nd(const void* /*pElem1*/, const void* /*pElem2*/) const
248 void ContainerSorter::ImpSubSort(long nL, long nR) const
250 long i,j;
251 const void* pX;
252 void* pI;
253 void* pJ;
254 i=nL;
255 j=nR;
256 pX=rCont.GetObject((nL+nR)/2);
257 do {
258 pI=rCont.Seek(i);
259 while (pI!=pX && Compare(pI,pX)<0) { i++; pI=rCont.Next(); }
260 pJ=rCont.Seek(j);
261 while (pJ!=pX && Compare(pX,pJ)<0) { j--; pJ=rCont.Prev(); }
262 if (i<=j) {
263 rCont.Replace(pJ,i);
264 rCont.Replace(pI,j);
265 i++;
266 j--;
268 } while (i<=j);
269 if (nL<j) ImpSubSort(nL,j);
270 if (i<nR) ImpSubSort(i,nR);
273 ////////////////////////////////////////////////////////////////////////////////////////////////////
275 class ImpUShortContainerSorter: public ContainerSorter {
276 public:
277 ImpUShortContainerSorter(Container& rNewCont): ContainerSorter(rNewCont) {}
278 virtual ~ImpUShortContainerSorter() {}
279 virtual int Compare(const void* pElem1, const void* pElem2) const;
282 int ImpUShortContainerSorter::Compare(const void* pElem1, const void* pElem2) const
284 sal_uInt16 n1=sal_uInt16(sal_uIntPtr(pElem1));
285 sal_uInt16 n2=sal_uInt16(sal_uIntPtr(pElem2));
286 return n1<n2 ? -1 : n1>n2 ? 1 : 0;
289 ////////////////////////////////////////////////////////////////////////////////////////////////////
291 void SdrLinkList::Clear()
293 unsigned nAnz=GetLinkCount();
294 for (unsigned i=0; i<nAnz; i++) {
295 delete (Link*)aList.GetObject(i);
297 aList.Clear();
300 unsigned SdrLinkList::FindEntry(const Link& rLink) const
302 unsigned nAnz=GetLinkCount();
303 for (unsigned i=0; i<nAnz; i++) {
304 if (GetLink(i)==rLink) return i;
306 return 0xFFFF;
309 void SdrLinkList::InsertLink(const Link& rLink, unsigned nPos)
311 unsigned nFnd=FindEntry(rLink);
312 if (nFnd==0xFFFF) {
313 if (rLink.IsSet()) {
314 aList.Insert(new Link(rLink),nPos);
315 } else {
316 OSL_FAIL("SdrLinkList::InsertLink(): Tried to insert a link that was not set already.");
318 } else {
319 OSL_FAIL("SdrLinkList::InsertLink(): Link already in place.");
323 void SdrLinkList::RemoveLink(const Link& rLink)
325 unsigned nFnd=FindEntry(rLink);
326 if (nFnd!=0xFFFF) {
327 Link* pLink=(Link*)aList.Remove(nFnd);
328 delete pLink;
329 } else {
330 OSL_FAIL("SdrLinkList::RemoveLink(): Link not found.");
334 ////////////////////////////////////////////////////////////////////////////////////////////////////
336 bool GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
338 XFillStyle eFill=((XFillStyleItem&)rSet.Get(XATTR_FILLSTYLE)).GetValue();
339 bool bRetval = false;
341 switch(eFill)
343 case XFILL_SOLID:
345 rCol = ((XFillColorItem&)rSet.Get(XATTR_FILLCOLOR)).GetColorValue();
346 bRetval = true;
348 break;
350 case XFILL_HATCH:
352 Color aCol1(((XFillHatchItem&)rSet.Get(XATTR_FILLHATCH)).GetHatchValue().GetColor());
353 Color aCol2(COL_WHITE);
355 // when hatched background is activated, use object fill color as hatch color
356 sal_Bool bFillHatchBackground = ((const XFillBackgroundItem&)(rSet.Get(XATTR_FILLBACKGROUND))).GetValue();
357 if(bFillHatchBackground)
359 aCol2 = ((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue();
362 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
363 rCol = Color(aAverageColor);
364 bRetval = true;
366 break;
368 case XFILL_GRADIENT: {
369 const XGradient& rGrad=((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
370 Color aCol1(rGrad.GetStartColor());
371 Color aCol2(rGrad.GetEndColor());
372 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
373 rCol = Color(aAverageColor);
374 bRetval = true;
376 break;
378 case XFILL_BITMAP:
380 const Bitmap& rBitmap = ((XFillBitmapItem&)rSet.Get(XATTR_FILLBITMAP)).GetBitmapValue().GetBitmap();
381 const Size aSize(rBitmap.GetSizePixel());
382 const sal_uInt32 nWidth = aSize.Width();
383 const sal_uInt32 nHeight = aSize.Height();
384 Bitmap aBitmap(rBitmap);
385 BitmapReadAccess* pAccess = aBitmap.AcquireReadAccess();
387 if(pAccess && nWidth > 0 && nHeight > 0)
389 sal_uInt32 nRt(0L);
390 sal_uInt32 nGn(0L);
391 sal_uInt32 nBl(0L);
392 const sal_uInt32 nMaxSteps(8L);
393 const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1L);
394 const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1L);
395 sal_uInt32 nAnz(0L);
397 for(sal_uInt32 nY(0L); nY < nHeight; nY += nYStep)
399 for(sal_uInt32 nX(0L); nX < nWidth; nX += nXStep)
401 const BitmapColor& rCol2 = (pAccess->HasPalette())
402 ? pAccess->GetPaletteColor((sal_uInt8)pAccess->GetPixel(nY, nX))
403 : pAccess->GetPixel(nY, nX);
405 nRt += rCol2.GetRed();
406 nGn += rCol2.GetGreen();
407 nBl += rCol2.GetBlue();
408 nAnz++;
412 nRt /= nAnz;
413 nGn /= nAnz;
414 nBl /= nAnz;
416 rCol = Color(sal_uInt8(nRt), sal_uInt8(nGn), sal_uInt8(nBl));
418 bRetval = true;
421 if(pAccess)
423 aBitmap.ReleaseAccess(pAccess);
426 break;
428 default: break;
431 return bRetval;
434 ////////////////////////////////////////////////////////////////////////////////////////////////////
436 SdrEngineDefaults::SdrEngineDefaults():
437 aFontName( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ).GetName() ),
438 eFontFamily(FAMILY_ROMAN),
439 aFontColor(COL_AUTO),
440 nFontHeight(847), // 847/100mm = ca. 24 Point
441 eMapUnit(MAP_100TH_MM),
442 aMapFraction(1,1)
446 SdrEngineDefaults& SdrEngineDefaults::GetDefaults()
448 SdrGlobalData& rGlobalData=GetSdrGlobalData();
449 if (rGlobalData.pDefaults==NULL) {
450 rGlobalData.pDefaults=new SdrEngineDefaults;
452 return *rGlobalData.pDefaults;
455 ////////////////////////////////////////////////////////////////////////////////////////////////////
457 SdrOutliner* SdrMakeOutliner( sal_uInt16 nOutlinerMode, SdrModel* pModel )
459 SfxItemPool* pPool = &pModel->GetItemPool();
460 SdrOutliner* pOutl = new SdrOutliner( pPool, nOutlinerMode );
461 pOutl->SetEditTextObjectPool( pPool );
462 pOutl->SetStyleSheetPool( (SfxStyleSheetPool*) pModel->GetStyleSheetPool() );
463 pOutl->SetDefTab( pModel->GetDefaultTabulator() );
464 pOutl->SetForbiddenCharsTable( pModel->GetForbiddenCharsTable() );
465 pOutl->SetAsianCompressionMode( pModel->GetCharCompressType() );
466 pOutl->SetKernAsianPunctuation( pModel->IsKernAsianPunctuation() );
467 pOutl->SetAddExtLeading( pModel->IsAddExtLeading() );
469 return pOutl;
472 ////////////////////////////////////////////////////////////////////////////////////////////////////
475 SdrLinkList& ImpGetUserMakeObjHdl()
477 SdrGlobalData& rGlobalData=GetSdrGlobalData();
478 return rGlobalData.aUserMakeObjHdl;
481 SdrLinkList& ImpGetUserMakeObjUserDataHdl()
483 SdrGlobalData& rGlobalData=GetSdrGlobalData();
484 return rGlobalData.aUserMakeObjUserDataHdl;
487 ////////////////////////////////////////////////////////////////////////////////////////////////////
489 ResMgr* ImpGetResMgr()
491 SdrGlobalData& rGlobalData = GetSdrGlobalData();
493 if(!rGlobalData.pResMgr)
495 rGlobalData.pResMgr =
496 ResMgr::CreateResMgr( "svx", Application::GetSettings().GetUILocale() );
499 return rGlobalData.pResMgr;
502 ////////////////////////////////////////////////////////////////////////////////////////////////////
504 String ImpGetResStr(sal_uInt16 nResID)
506 return String(ResId(nResID, *ImpGetResMgr()));
509 ////////////////////////////////////////////////////////////////////////////////////////////////////
511 namespace sdr
513 String GetResourceString(sal_uInt16 nResID)
515 return ImpGetResStr( nResID );
519 ////////////////////////////////////////////////////////////////////////////////////////////////////
521 sal_Bool SearchOutlinerItems(const SfxItemSet& rSet, sal_Bool bInklDefaults, sal_Bool* pbOnlyEE)
523 sal_Bool bHas=sal_False;
524 sal_Bool bOnly=sal_True;
525 sal_Bool bLookOnly=pbOnlyEE!=NULL;
526 SfxWhichIter aIter(rSet);
527 sal_uInt16 nWhich=aIter.FirstWhich();
528 while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) {
529 // For bInklDefaults, the entire Which range is decisive,
530 // in other cases only the set items are.
531 // Disabled and DontCare are regarded as holes in the Which range.
532 SfxItemState eState=rSet.GetItemState(nWhich);
533 if ((eState==SFX_ITEM_DEFAULT && bInklDefaults) || eState==SFX_ITEM_SET) {
534 if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=sal_False;
535 else bHas=sal_True;
537 nWhich=aIter.NextWhich();
539 if (!bHas) bOnly=sal_False;
540 if (pbOnlyEE!=NULL) *pbOnlyEE=bOnly;
541 return bHas;
544 sal_uInt16* RemoveWhichRange(const sal_uInt16* pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd)
546 // Six possible cases (per range):
547 // [Beg..End] Range, to delete
548 // [b..e] [b..e] [b..e] Cases 1,3,2: doesn't matter, delete, doesn't matter + Ranges
549 // [b........e] [b........e] Cases 4,5 : shrink range | in
550 // [b......................e] Case 6 : splitting + pOldWhichTable
551 sal_uInt16 nAnz=0;
552 while (pOldWhichTable[nAnz]!=0) nAnz++;
553 nAnz++; // nAnz should now be an odd number (0 for end of array)
554 DBG_ASSERT((nAnz&1)==1,"RemoveWhichRange: WhichTable doesn't have an odd number of entries.");
555 sal_uInt16 nAlloc=nAnz;
556 // check necessary size of new array
557 sal_uInt16 nNum=nAnz-1;
558 while (nNum!=0) {
559 nNum-=2;
560 sal_uInt16 nBeg=pOldWhichTable[nNum];
561 sal_uInt16 nEnd=pOldWhichTable[nNum+1];
562 if (nEnd<nRangeBeg) /*nCase=1*/ ;
563 else if (nBeg>nRangeEnd) /* nCase=2 */ ;
564 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2;
565 else if (nEnd<=nRangeEnd) /* nCase=4 */;
566 else if (nBeg>=nRangeBeg) /* nCase=5*/ ;
567 else /* nCase=6 */ nAlloc+=2;
570 sal_uInt16* pNewWhichTable=new sal_uInt16[nAlloc];
571 memcpy(pNewWhichTable,pOldWhichTable,nAlloc*sizeof(sal_uInt16));
572 pNewWhichTable[nAlloc-1]=0; // in case 3, there's no 0 at the end.
573 // now remove the unwanted ranges
574 nNum=nAlloc-1;
575 while (nNum!=0) {
576 nNum-=2;
577 sal_uInt16 nBeg=pNewWhichTable[nNum];
578 sal_uInt16 nEnd=pNewWhichTable[nNum+1];
579 unsigned nCase=0;
580 if (nEnd<nRangeBeg) nCase=1;
581 else if (nBeg>nRangeEnd) nCase=2;
582 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3;
583 else if (nEnd<=nRangeEnd) nCase=4;
584 else if (nBeg>=nRangeBeg) nCase=5;
585 else nCase=6;
586 switch (nCase) {
587 case 3: {
588 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16);
589 memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes);
590 nAnz-=2; // remember: array is now smaller
591 } break;
592 case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break;
593 case 5: pNewWhichTable[nNum]=nRangeEnd+1; break;
594 case 6: {
595 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16);
596 memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes);
597 nAnz+=2; // remember:array is now larger
598 pNewWhichTable[nNum+2]=nRangeEnd+1;
599 pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1];
600 pNewWhichTable[nNum+1]=nRangeBeg-1;
601 } break;
602 } // switch
604 return pNewWhichTable;
607 ////////////////////////////////////////////////////////////////////////////////////////////////////
609 SvdProgressInfo::SvdProgressInfo( Link *_pLink )
611 DBG_ASSERT(_pLink!=NULL,"SvdProgressInfo(): No Link stated!");
613 pLink = _pLink;
614 nSumActionCount = 0;
615 nSumCurAction = 0;
617 nObjCount = 0;
618 nCurObj = 0;
620 nActionCount = 0;
621 nCurAction = 0;
623 nInsertCount = 0;
624 nCurInsert = 0;
627 void SvdProgressInfo::Init( sal_uIntPtr _nSumActionCount, sal_uIntPtr _nObjCount )
629 nSumActionCount = _nSumActionCount;
630 nObjCount = _nObjCount;
633 sal_Bool SvdProgressInfo::ReportActions( sal_uIntPtr nAnzActions )
635 nSumCurAction += nAnzActions;
636 nCurAction += nAnzActions;
637 if(nCurAction > nActionCount)
638 nCurAction = nActionCount;
640 return pLink->Call(NULL) == 1L;
643 sal_Bool SvdProgressInfo::ReportInserts( sal_uIntPtr nAnzInserts )
645 nSumCurAction += nAnzInserts;
646 nCurInsert += nAnzInserts;
648 return pLink->Call(NULL) == 1L;
651 sal_Bool SvdProgressInfo::ReportRescales( sal_uIntPtr nAnzRescales )
653 nSumCurAction += nAnzRescales;
654 return pLink->Call(NULL) == 1L;
657 void SvdProgressInfo::SetActionCount( sal_uIntPtr _nActionCount )
659 nActionCount = _nActionCount;
662 void SvdProgressInfo::SetInsertCount( sal_uIntPtr _nInsertCount )
664 nInsertCount = _nInsertCount;
667 sal_Bool SvdProgressInfo::SetNextObject()
669 nActionCount = 0;
670 nCurAction = 0;
672 nInsertCount = 0;
673 nCurInsert = 0;
675 nCurObj++;
676 return ReportActions(0);
679 void SvdProgressInfo::ReportError()
681 pLink->Call((void *)1L);
684 ////////////////////////////////////////////////////////////////////////////////////////////////////
685 // #i101872# isolate GetTextEditBackgroundColor to tooling; it will anyways only be used as long
686 // as text edit is not running on overlay
688 namespace
690 bool impGetSdrObjListFillColor(
691 const SdrObjList& rList,
692 const Point& rPnt,
693 const SdrPageView& rTextEditPV,
694 const SetOfByte& rVisLayers,
695 Color& rCol)
697 if(!rList.GetModel())
698 return false;
700 bool bRet(false);
701 bool bMaster(rList.GetPage() ? rList.GetPage()->IsMasterPage() : false);
703 for(sal_uIntPtr no(rList.GetObjCount()); !bRet && no > 0; )
705 no--;
706 SdrObject* pObj = rList.GetObj(no);
707 SdrObjList* pOL = pObj->GetSubList();
709 if(pOL)
711 // group object
712 bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol);
714 else
716 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj);
718 // Exclude zero master page object (i.e. background shape) from color query
719 if(pText
720 && pObj->IsClosedObj()
721 && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
722 && pObj->GetCurrentBoundRect().IsInside(rPnt)
723 && !pText->IsHideContour()
724 && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
726 bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
731 return bRet;
734 bool impGetSdrPageFillColor(
735 const SdrPage& rPage,
736 const Point& rPnt,
737 const SdrPageView& rTextEditPV,
738 const SetOfByte& rVisLayers,
739 Color& rCol,
740 bool bSkipBackgroundShape)
742 if(!rPage.GetModel())
743 return false;
745 bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol));
747 if(!bRet && !rPage.IsMasterPage())
749 if(rPage.TRG_HasMasterPage())
751 SetOfByte aSet(rVisLayers);
752 aSet &= rPage.TRG_GetMasterPageVisibleLayers();
753 SdrPage& rMasterPage = rPage.TRG_GetMasterPage();
755 // Don't fall back to background shape on
756 // master pages. This is later handled by
757 // GetBackgroundColor, and is necessary to cater for
758 // the silly ordering: 1. shapes, 2. master page
759 // shapes, 3. page background, 4. master page
760 // background.
761 bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true);
765 // Only now determine background color from background shapes
766 if(!bRet && !bSkipBackgroundShape)
768 rCol = rPage.GetPageBackgroundColor();
769 return true;
772 return bRet;
775 Color impCalcBackgroundColor(
776 const Rectangle& rArea,
777 const SdrPageView& rTextEditPV,
778 const SdrPage& rPage)
780 svtools::ColorConfig aColorConfig;
781 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
782 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
784 if(!rStyleSettings.GetHighContrastMode())
786 // search in page
787 const sal_uInt16 SPOTCOUNT(5);
788 Point aSpotPos[SPOTCOUNT];
789 Color aSpotColor[SPOTCOUNT];
790 sal_uIntPtr nHeight( rArea.GetSize().Height() );
791 sal_uIntPtr nWidth( rArea.GetSize().Width() );
792 sal_uIntPtr nWidth14 = nWidth / 4;
793 sal_uIntPtr nHeight14 = nHeight / 4;
794 sal_uIntPtr nWidth34 = ( 3 * nWidth ) / 4;
795 sal_uIntPtr nHeight34 = ( 3 * nHeight ) / 4;
797 sal_uInt16 i;
798 for ( i = 0; i < SPOTCOUNT; i++ )
800 // five spots are used
801 switch ( i )
803 case 0 :
805 // Center-Spot
806 aSpotPos[i] = rArea.Center();
808 break;
810 case 1 :
812 // TopLeft-Spot
813 aSpotPos[i] = rArea.TopLeft();
814 aSpotPos[i].X() += nWidth14;
815 aSpotPos[i].Y() += nHeight14;
817 break;
819 case 2 :
821 // TopRight-Spot
822 aSpotPos[i] = rArea.TopLeft();
823 aSpotPos[i].X() += nWidth34;
824 aSpotPos[i].Y() += nHeight14;
826 break;
828 case 3 :
830 // BottomLeft-Spot
831 aSpotPos[i] = rArea.TopLeft();
832 aSpotPos[i].X() += nWidth14;
833 aSpotPos[i].Y() += nHeight34;
835 break;
837 case 4 :
839 // BottomRight-Spot
840 aSpotPos[i] = rArea.TopLeft();
841 aSpotPos[i].X() += nWidth34;
842 aSpotPos[i].Y() += nHeight34;
844 break;
848 aSpotColor[i] = Color( COL_WHITE );
849 impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false);
852 sal_uInt16 aMatch[SPOTCOUNT];
854 for ( i = 0; i < SPOTCOUNT; i++ )
856 // were same spot colors found?
857 aMatch[i] = 0;
859 for ( sal_uInt16 j = 0; j < SPOTCOUNT; j++ )
861 if( j != i )
863 if( aSpotColor[i] == aSpotColor[j] )
865 aMatch[i]++;
871 // highest weight to center spot
872 aBackground = aSpotColor[0];
874 for ( sal_uInt16 nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- )
876 // which spot color was found most?
877 for ( i = 0; i < SPOTCOUNT; i++ )
879 if( aMatch[i] == nMatchCount )
881 aBackground = aSpotColor[i];
882 nMatchCount = 1; // break outer for-loop
883 break;
889 return aBackground;
891 } // end of anonymous namespace
893 Color GetTextEditBackgroundColor(const SdrObjEditView& rView)
895 svtools::ColorConfig aColorConfig;
896 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
897 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
899 if(!rStyleSettings.GetHighContrastMode())
901 bool bFound(false);
902 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(rView.GetTextEditObject());
904 if(pText && pText->IsClosedObj())
906 ::sdr::table::SdrTableObj* pTable = dynamic_cast< ::sdr::table::SdrTableObj * >( pText );
908 if( pTable )
909 bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground );
911 if( !bFound )
912 bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground);
915 if(!bFound && pText)
917 SdrPageView* pTextEditPV = rView.GetTextEditPageView();
919 if(pTextEditPV)
921 Point aPvOfs(pText->GetTextEditOffset());
922 const SdrPage* pPg = pTextEditPV->GetPage();
924 if(pPg)
926 Rectangle aSnapRect( pText->GetSnapRect() );
927 aSnapRect.Move(aPvOfs.X(), aPvOfs.Y());
929 return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg);
935 return aBackground;
938 ////////////////////////////////////////////////////////////////////////////////////////////////////
939 // eof
941 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */