bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / svdraw / svdetc.cxx
blobf133ca8fb14d95d3e1503e2dbbff96884c038ea0
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "sal/config.h"
22 #include "editeng/forbiddencharacterstable.hxx"
23 #include <com/sun/star/embed/XEmbeddedObject.hpp>
24 #include <com/sun/star/embed/EmbedStates.hpp>
25 #include "officecfg/Office/Common.hxx"
26 #include <svx/svdetc.hxx>
27 #include <svx/svdmodel.hxx>
28 #include <svx/svdtrans.hxx>
29 #include "svx/svdglob.hxx"
30 #include "svx/svdstr.hrc"
31 #include "svx/svdviter.hxx"
32 #include <svx/svdview.hxx>
33 #include <svx/svdoutl.hxx>
34 #include <vcl/bmpacc.hxx>
35 #include <editeng/editdata.hxx>
36 #include <editeng/eeitem.hxx>
37 #include <svl/itemset.hxx>
38 #include <svl/whiter.hxx>
39 #include "editeng/fontitem.hxx"
40 #include <editeng/colritem.hxx>
41 #include <editeng/fhgtitem.hxx>
42 #include <svx/xgrad.hxx>
43 #include <svx/xfillit0.hxx>
44 #include <svx/xflclit.hxx>
45 #include <svx/xflhtit.hxx>
46 #include <svx/xbtmpit.hxx>
47 #include <svx/xflgrit.hxx>
48 #include <svx/svdoole2.hxx>
49 #include <svl/itempool.hxx>
50 #include <unotools/localedatawrapper.hxx>
51 #include <com/sun/star/lang/Locale.hpp>
52 #include <i18nlangtag/lang.h>
53 #include <unotools/syslocale.hxx>
54 #include <svx/xflbckit.hxx>
55 #include <svx/extrusionbar.hxx>
56 #include <svx/fontworkbar.hxx>
57 #include <vcl/svapp.hxx>
58 #include <svx/sdr/contact/viewcontact.hxx>
59 #include <svx/svdpage.hxx>
60 #include <svx/svdotable.hxx>
61 #include <svx/sdrhittesthelper.hxx>
63 using namespace ::com::sun::star;
65 /******************************************************************************
66 * Global data of the DrawingEngine
67 ******************************************************************************/
69 SdrGlobalData::SdrGlobalData() :
70 pSysLocale(NULL),
71 pLocaleData(NULL),
72 pOutliner(NULL),
73 pDefaults(NULL),
74 pResMgr(NULL),
75 nExchangeFormat(0)
78 svx::ExtrusionBar::RegisterInterface();
79 svx::FontworkBar::RegisterInterface();
82 const SvtSysLocale* SdrGlobalData::GetSysLocale()
84 if ( !pSysLocale )
85 pSysLocale = new SvtSysLocale;
86 return pSysLocale;
88 const LocaleDataWrapper* SdrGlobalData::GetLocaleData()
90 if ( !pLocaleData )
91 pLocaleData = GetSysLocale()->GetLocaleDataPtr();
92 return pLocaleData;
94 ////////////////////////////////////////////////////////////////////////////////////////////////////
96 OLEObjCache::OLEObjCache()
97 : std::vector<SdrOle2Obj*>()
99 nSize = officecfg::Office::Common::Cache::DrawingEngine::OLE_Objects::get();
100 pTimer = new AutoTimer();
101 Link aLink = LINK(this, OLEObjCache, UnloadCheckHdl);
103 pTimer->SetTimeoutHdl(aLink);
104 pTimer->SetTimeout(20000);
105 pTimer->Start();
107 aLink.Call(pTimer);
110 OLEObjCache::~OLEObjCache()
112 pTimer->Stop();
113 delete pTimer;
116 void OLEObjCache::UnloadOnDemand()
118 if ( nSize < size() )
120 // more objects than configured cache size try to remove objects
121 // of course not the freshly inserted one at nIndex=0
122 sal_uIntPtr nCount2 = size();
123 sal_uIntPtr nIndex = nCount2-1;
124 while( nIndex && nCount2 > nSize )
126 SdrOle2Obj* pUnloadObj = (*this)[nIndex--];
127 if ( pUnloadObj )
131 // it is important to get object without reinitialization to avoid reentrance
132 uno::Reference< embed::XEmbeddedObject > xUnloadObj = pUnloadObj->GetObjRef_NoInit();
134 sal_Bool bUnload = SdrOle2Obj::CanUnloadRunningObj( xUnloadObj, pUnloadObj->GetAspect() );
136 // check whether the object can be unloaded before looking for the parent objects
137 if ( xUnloadObj.is() && bUnload )
139 uno::Reference< frame::XModel > xUnloadModel( xUnloadObj->getComponent(), uno::UNO_QUERY );
140 if ( xUnloadModel.is() )
142 for ( sal_uIntPtr nCheckInd = 0; nCheckInd < size(); nCheckInd++ )
144 SdrOle2Obj* pCacheObj = (*this)[nCheckInd];
145 if ( pCacheObj && pCacheObj != pUnloadObj )
147 uno::Reference< frame::XModel > xParentModel = pCacheObj->GetParentXModel();
148 if ( xUnloadModel == xParentModel )
149 bUnload = sal_False; // the object has running embedded objects
155 if ( bUnload && UnloadObj(pUnloadObj) )
156 // object was successfully unloaded
157 nCount2--;
159 catch( uno::Exception& )
166 void OLEObjCache::InsertObj(SdrOle2Obj* pObj)
168 if ( !empty() )
170 SdrOle2Obj* pExistingObj = front();
171 if ( pObj == pExistingObj )
172 // the object is already on the top, nothing has to be changed
173 return;
176 // get the old position of the object to know whether it is already in container
177 iterator it = std::find( begin(), end(), pObj );
178 bool bFound = it != end();
180 if( it != end() )
181 erase( it );
182 // insert object into first position
183 insert(begin(), pObj);
185 if ( !bFound )
187 // a new object was inserted, recalculate the cache
188 UnloadOnDemand();
192 void OLEObjCache::RemoveObj(SdrOle2Obj* pObj)
194 iterator it = std::find( begin(), end(), pObj );
195 if( it != end() )
196 erase( it );
199 sal_Bool OLEObjCache::UnloadObj(SdrOle2Obj* pObj)
201 sal_Bool bUnloaded = sal_False;
202 if (pObj)
204 //#i80528# The old mechanism is completely useless, only taking into account if
205 // in all views the GrafDraft feature is used. This will nearly never have been the
206 // case since no one ever used this option.
208 // A much better (and working) criteria would be the VOC contact count.
209 // The question is what will happen when i make it work now suddenly? I
210 // will try it for 2.4.
211 const sdr::contact::ViewContact& rViewContact = pObj->GetViewContact();
212 const bool bVisible(rViewContact.HasViewObjectContacts(true));
214 if(!bVisible)
216 bUnloaded = pObj->Unload();
220 return bUnloaded;
223 IMPL_LINK(OLEObjCache, UnloadCheckHdl, AutoTimer*, /*pTim*/)
225 UnloadOnDemand();
226 return 0;
229 ////////////////////////////////////////////////////////////////////////////////////////////////////
231 void SdrLinkList::Clear()
233 unsigned nAnz=GetLinkCount();
234 for (unsigned i=0; i<nAnz; i++) {
235 delete aList[i];
237 aList.clear();
240 unsigned SdrLinkList::FindEntry(const Link& rLink) const
242 unsigned nAnz=GetLinkCount();
243 for (unsigned i=0; i<nAnz; i++) {
244 if (GetLink(i)==rLink) return i;
246 return 0xFFFF;
249 void SdrLinkList::InsertLink(const Link& rLink, unsigned nPos)
251 unsigned nFnd=FindEntry(rLink);
252 if (nFnd==0xFFFF) {
253 if (rLink.IsSet()) {
254 if(nPos==0xFFFF)
255 aList.push_back(new Link(rLink));
256 else
257 aList.insert(aList.begin() + nPos, new Link(rLink));
258 } else {
259 OSL_FAIL("SdrLinkList::InsertLink(): Tried to insert a link that was not set already.");
261 } else {
262 OSL_FAIL("SdrLinkList::InsertLink(): Link already in place.");
266 void SdrLinkList::RemoveLink(const Link& rLink)
268 unsigned nFnd=FindEntry(rLink);
269 if (nFnd!=0xFFFF) {
270 Link* pLink = aList[nFnd];
271 aList.erase( aList.begin() + nFnd );
272 delete pLink;
273 } else {
274 OSL_FAIL("SdrLinkList::RemoveLink(): Link not found.");
278 ////////////////////////////////////////////////////////////////////////////////////////////////////
280 bool GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
282 XFillStyle eFill=((XFillStyleItem&)rSet.Get(XATTR_FILLSTYLE)).GetValue();
283 bool bRetval = false;
285 switch(eFill)
287 case XFILL_SOLID:
289 rCol = ((XFillColorItem&)rSet.Get(XATTR_FILLCOLOR)).GetColorValue();
290 bRetval = true;
292 break;
294 case XFILL_HATCH:
296 Color aCol1(((XFillHatchItem&)rSet.Get(XATTR_FILLHATCH)).GetHatchValue().GetColor());
297 Color aCol2(COL_WHITE);
299 // when hatched background is activated, use object fill color as hatch color
300 sal_Bool bFillHatchBackground = ((const XFillBackgroundItem&)(rSet.Get(XATTR_FILLBACKGROUND))).GetValue();
301 if(bFillHatchBackground)
303 aCol2 = ((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue();
306 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
307 rCol = Color(aAverageColor);
308 bRetval = true;
310 break;
312 case XFILL_GRADIENT: {
313 const XGradient& rGrad=((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
314 Color aCol1(rGrad.GetStartColor());
315 Color aCol2(rGrad.GetEndColor());
316 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
317 rCol = Color(aAverageColor);
318 bRetval = true;
320 break;
322 case XFILL_BITMAP:
324 Bitmap aBitmap(((XFillBitmapItem&)rSet.Get(XATTR_FILLBITMAP)).GetGraphicObject().GetGraphic().GetBitmapEx().GetBitmap());
325 const Size aSize(aBitmap.GetSizePixel());
326 const sal_uInt32 nWidth = aSize.Width();
327 const sal_uInt32 nHeight = aSize.Height();
328 BitmapReadAccess* pAccess = aBitmap.AcquireReadAccess();
330 if(pAccess && nWidth > 0 && nHeight > 0)
332 sal_uInt32 nRt(0L);
333 sal_uInt32 nGn(0L);
334 sal_uInt32 nBl(0L);
335 const sal_uInt32 nMaxSteps(8L);
336 const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1L);
337 const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1L);
338 sal_uInt32 nAnz(0L);
340 for(sal_uInt32 nY(0L); nY < nHeight; nY += nYStep)
342 for(sal_uInt32 nX(0L); nX < nWidth; nX += nXStep)
344 const BitmapColor& rCol2 = pAccess->GetColor(nY, nX);
346 nRt += rCol2.GetRed();
347 nGn += rCol2.GetGreen();
348 nBl += rCol2.GetBlue();
349 nAnz++;
353 nRt /= nAnz;
354 nGn /= nAnz;
355 nBl /= nAnz;
357 rCol = Color(sal_uInt8(nRt), sal_uInt8(nGn), sal_uInt8(nBl));
359 bRetval = true;
362 if(pAccess)
364 aBitmap.ReleaseAccess(pAccess);
367 break;
369 default: break;
372 return bRetval;
375 ////////////////////////////////////////////////////////////////////////////////////////////////////
377 SdrEngineDefaults::SdrEngineDefaults():
378 aFontName( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ).GetName() ),
379 eFontFamily(FAMILY_ROMAN),
380 aFontColor(COL_AUTO),
381 nFontHeight(847), // 847/100mm = ca. 24 Point
382 eMapUnit(MAP_100TH_MM),
383 aMapFraction(1,1)
387 SdrEngineDefaults& SdrEngineDefaults::GetDefaults()
389 SdrGlobalData& rGlobalData=GetSdrGlobalData();
390 if (rGlobalData.pDefaults==NULL) {
391 rGlobalData.pDefaults=new SdrEngineDefaults;
393 return *rGlobalData.pDefaults;
396 ////////////////////////////////////////////////////////////////////////////////////////////////////
398 SdrOutliner* SdrMakeOutliner( sal_uInt16 nOutlinerMode, SdrModel* pModel )
400 SfxItemPool* pPool = &pModel->GetItemPool();
401 SdrOutliner* pOutl = new SdrOutliner( pPool, nOutlinerMode );
402 pOutl->SetEditTextObjectPool( pPool );
403 pOutl->SetStyleSheetPool( (SfxStyleSheetPool*) pModel->GetStyleSheetPool() );
404 pOutl->SetDefTab( pModel->GetDefaultTabulator() );
405 pOutl->SetForbiddenCharsTable( pModel->GetForbiddenCharsTable() );
406 pOutl->SetAsianCompressionMode( pModel->GetCharCompressType() );
407 pOutl->SetKernAsianPunctuation( pModel->IsKernAsianPunctuation() );
408 pOutl->SetAddExtLeading( pModel->IsAddExtLeading() );
410 return pOutl;
413 ////////////////////////////////////////////////////////////////////////////////////////////////////
416 SdrLinkList& ImpGetUserMakeObjHdl()
418 SdrGlobalData& rGlobalData=GetSdrGlobalData();
419 return rGlobalData.aUserMakeObjHdl;
422 SdrLinkList& ImpGetUserMakeObjUserDataHdl()
424 SdrGlobalData& rGlobalData=GetSdrGlobalData();
425 return rGlobalData.aUserMakeObjUserDataHdl;
428 ////////////////////////////////////////////////////////////////////////////////////////////////////
430 ResMgr* ImpGetResMgr()
432 SdrGlobalData& rGlobalData = GetSdrGlobalData();
434 if(!rGlobalData.pResMgr)
436 rGlobalData.pResMgr =
437 ResMgr::CreateResMgr( "svx", Application::GetSettings().GetUILanguageTag() );
440 return rGlobalData.pResMgr;
443 ////////////////////////////////////////////////////////////////////////////////////////////////////
445 String ImpGetResStr(sal_uInt16 nResID)
447 return String(ResId(nResID, *ImpGetResMgr()));
450 ////////////////////////////////////////////////////////////////////////////////////////////////////
452 namespace sdr
454 String GetResourceString(sal_uInt16 nResID)
456 return ImpGetResStr( nResID );
460 ////////////////////////////////////////////////////////////////////////////////////////////////////
462 sal_Bool SearchOutlinerItems(const SfxItemSet& rSet, sal_Bool bInklDefaults, sal_Bool* pbOnlyEE)
464 sal_Bool bHas=sal_False;
465 sal_Bool bOnly=sal_True;
466 bool bLookOnly=pbOnlyEE!=NULL;
467 SfxWhichIter aIter(rSet);
468 sal_uInt16 nWhich=aIter.FirstWhich();
469 while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) {
470 // For bInklDefaults, the entire Which range is decisive,
471 // in other cases only the set items are.
472 // Disabled and DontCare are regarded as holes in the Which range.
473 SfxItemState eState=rSet.GetItemState(nWhich);
474 if ((eState==SFX_ITEM_DEFAULT && bInklDefaults) || eState==SFX_ITEM_SET) {
475 if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=sal_False;
476 else bHas=sal_True;
478 nWhich=aIter.NextWhich();
480 if (!bHas) bOnly=sal_False;
481 if (pbOnlyEE!=NULL) *pbOnlyEE=bOnly;
482 return bHas;
485 sal_uInt16* RemoveWhichRange(const sal_uInt16* pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd)
487 // Six possible cases (per range):
488 // [Beg..End] Range, to delete
489 // [b..e] [b..e] [b..e] Cases 1,3,2: doesn't matter, delete, doesn't matter + Ranges
490 // [b........e] [b........e] Cases 4,5 : shrink range | in
491 // [b......................e] Case 6 : splitting + pOldWhichTable
492 sal_uInt16 nAnz=0;
493 while (pOldWhichTable[nAnz]!=0) nAnz++;
494 nAnz++; // nAnz should now be an odd number (0 for end of array)
495 DBG_ASSERT((nAnz&1)==1,"RemoveWhichRange: WhichTable doesn't have an odd number of entries.");
496 sal_uInt16 nAlloc=nAnz;
497 // check necessary size of new array
498 sal_uInt16 nNum=nAnz-1;
499 while (nNum!=0) {
500 nNum-=2;
501 sal_uInt16 nBeg=pOldWhichTable[nNum];
502 sal_uInt16 nEnd=pOldWhichTable[nNum+1];
503 if (nEnd<nRangeBeg) /*nCase=1*/ ;
504 else if (nBeg>nRangeEnd) /* nCase=2 */ ;
505 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2;
506 else if (nEnd<=nRangeEnd) /* nCase=4 */;
507 else if (nBeg>=nRangeBeg) /* nCase=5*/ ;
508 else /* nCase=6 */ nAlloc+=2;
511 sal_uInt16* pNewWhichTable=new sal_uInt16[nAlloc];
512 memcpy(pNewWhichTable,pOldWhichTable,nAlloc*sizeof(sal_uInt16));
513 pNewWhichTable[nAlloc-1]=0; // in case 3, there's no 0 at the end.
514 // now remove the unwanted ranges
515 nNum=nAlloc-1;
516 while (nNum!=0) {
517 nNum-=2;
518 sal_uInt16 nBeg=pNewWhichTable[nNum];
519 sal_uInt16 nEnd=pNewWhichTable[nNum+1];
520 unsigned nCase=0;
521 if (nEnd<nRangeBeg) nCase=1;
522 else if (nBeg>nRangeEnd) nCase=2;
523 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3;
524 else if (nEnd<=nRangeEnd) nCase=4;
525 else if (nBeg>=nRangeBeg) nCase=5;
526 else nCase=6;
527 switch (nCase) {
528 case 3: {
529 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16);
530 memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes);
531 nAnz-=2; // remember: array is now smaller
532 } break;
533 case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break;
534 case 5: pNewWhichTable[nNum]=nRangeEnd+1; break;
535 case 6: {
536 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16);
537 memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes);
538 nAnz+=2; // remember:array is now larger
539 pNewWhichTable[nNum+2]=nRangeEnd+1;
540 pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1];
541 pNewWhichTable[nNum+1]=nRangeBeg-1;
542 } break;
543 } // switch
545 return pNewWhichTable;
548 ////////////////////////////////////////////////////////////////////////////////////////////////////
550 SvdProgressInfo::SvdProgressInfo( Link *_pLink )
552 DBG_ASSERT(_pLink!=NULL,"SvdProgressInfo(): No Link stated!");
554 pLink = _pLink;
555 nSumActionCount = 0;
556 nSumCurAction = 0;
558 nObjCount = 0;
559 nCurObj = 0;
561 nActionCount = 0;
562 nCurAction = 0;
564 nInsertCount = 0;
565 nCurInsert = 0;
568 void SvdProgressInfo::Init( sal_uIntPtr _nSumActionCount, sal_uIntPtr _nObjCount )
570 nSumActionCount = _nSumActionCount;
571 nObjCount = _nObjCount;
574 sal_Bool SvdProgressInfo::ReportActions( sal_uIntPtr nAnzActions )
576 nSumCurAction += nAnzActions;
577 nCurAction += nAnzActions;
578 if(nCurAction > nActionCount)
579 nCurAction = nActionCount;
581 return pLink->Call(NULL) == 1L;
584 sal_Bool SvdProgressInfo::ReportInserts( sal_uIntPtr nAnzInserts )
586 nSumCurAction += nAnzInserts;
587 nCurInsert += nAnzInserts;
589 return pLink->Call(NULL) == 1L;
592 sal_Bool SvdProgressInfo::ReportRescales( sal_uIntPtr nAnzRescales )
594 nSumCurAction += nAnzRescales;
595 return pLink->Call(NULL) == 1L;
598 void SvdProgressInfo::SetActionCount( sal_uIntPtr _nActionCount )
600 nActionCount = _nActionCount;
603 void SvdProgressInfo::SetInsertCount( sal_uIntPtr _nInsertCount )
605 nInsertCount = _nInsertCount;
608 sal_Bool SvdProgressInfo::SetNextObject()
610 nActionCount = 0;
611 nCurAction = 0;
613 nInsertCount = 0;
614 nCurInsert = 0;
616 nCurObj++;
617 return ReportActions(0);
620 void SvdProgressInfo::ReportError()
622 pLink->Call((void *)1L);
625 ////////////////////////////////////////////////////////////////////////////////////////////////////
626 // #i101872# isolate GetTextEditBackgroundColor to tooling; it will anyways only be used as long
627 // as text edit is not running on overlay
629 namespace
631 bool impGetSdrObjListFillColor(
632 const SdrObjList& rList,
633 const Point& rPnt,
634 const SdrPageView& rTextEditPV,
635 const SetOfByte& rVisLayers,
636 Color& rCol)
638 if(!rList.GetModel())
639 return false;
641 bool bRet(false);
642 bool bMaster(rList.GetPage() ? rList.GetPage()->IsMasterPage() : false);
644 for(sal_uIntPtr no(rList.GetObjCount()); !bRet && no > 0; )
646 no--;
647 SdrObject* pObj = rList.GetObj(no);
648 SdrObjList* pOL = pObj->GetSubList();
650 if(pOL)
652 // group object
653 bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol);
655 else
657 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj);
659 // Exclude zero master page object (i.e. background shape) from color query
660 if(pText
661 && pObj->IsClosedObj()
662 && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
663 && pObj->GetCurrentBoundRect().IsInside(rPnt)
664 && !pText->IsHideContour()
665 && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
667 bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
672 return bRet;
675 bool impGetSdrPageFillColor(
676 const SdrPage& rPage,
677 const Point& rPnt,
678 const SdrPageView& rTextEditPV,
679 const SetOfByte& rVisLayers,
680 Color& rCol,
681 bool bSkipBackgroundShape)
683 if(!rPage.GetModel())
684 return false;
686 bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol));
688 if(!bRet && !rPage.IsMasterPage())
690 if(rPage.TRG_HasMasterPage())
692 SetOfByte aSet(rVisLayers);
693 aSet &= rPage.TRG_GetMasterPageVisibleLayers();
694 SdrPage& rMasterPage = rPage.TRG_GetMasterPage();
696 // Don't fall back to background shape on
697 // master pages. This is later handled by
698 // GetBackgroundColor, and is necessary to cater for
699 // the silly ordering: 1. shapes, 2. master page
700 // shapes, 3. page background, 4. master page
701 // background.
702 bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true);
706 // Only now determine background color from background shapes
707 if(!bRet && !bSkipBackgroundShape)
709 rCol = rPage.GetPageBackgroundColor();
710 return true;
713 return bRet;
716 Color impCalcBackgroundColor(
717 const Rectangle& rArea,
718 const SdrPageView& rTextEditPV,
719 const SdrPage& rPage)
721 svtools::ColorConfig aColorConfig;
722 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
723 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
725 if(!rStyleSettings.GetHighContrastMode())
727 // search in page
728 const sal_uInt16 SPOTCOUNT(5);
729 Point aSpotPos[SPOTCOUNT];
730 Color aSpotColor[SPOTCOUNT];
731 sal_uIntPtr nHeight( rArea.GetSize().Height() );
732 sal_uIntPtr nWidth( rArea.GetSize().Width() );
733 sal_uIntPtr nWidth14 = nWidth / 4;
734 sal_uIntPtr nHeight14 = nHeight / 4;
735 sal_uIntPtr nWidth34 = ( 3 * nWidth ) / 4;
736 sal_uIntPtr nHeight34 = ( 3 * nHeight ) / 4;
738 sal_uInt16 i;
739 for ( i = 0; i < SPOTCOUNT; i++ )
741 // five spots are used
742 switch ( i )
744 case 0 :
746 // Center-Spot
747 aSpotPos[i] = rArea.Center();
749 break;
751 case 1 :
753 // TopLeft-Spot
754 aSpotPos[i] = rArea.TopLeft();
755 aSpotPos[i].X() += nWidth14;
756 aSpotPos[i].Y() += nHeight14;
758 break;
760 case 2 :
762 // TopRight-Spot
763 aSpotPos[i] = rArea.TopLeft();
764 aSpotPos[i].X() += nWidth34;
765 aSpotPos[i].Y() += nHeight14;
767 break;
769 case 3 :
771 // BottomLeft-Spot
772 aSpotPos[i] = rArea.TopLeft();
773 aSpotPos[i].X() += nWidth14;
774 aSpotPos[i].Y() += nHeight34;
776 break;
778 case 4 :
780 // BottomRight-Spot
781 aSpotPos[i] = rArea.TopLeft();
782 aSpotPos[i].X() += nWidth34;
783 aSpotPos[i].Y() += nHeight34;
785 break;
789 aSpotColor[i] = Color( COL_WHITE );
790 impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false);
793 sal_uInt16 aMatch[SPOTCOUNT];
795 for ( i = 0; i < SPOTCOUNT; i++ )
797 // were same spot colors found?
798 aMatch[i] = 0;
800 for ( sal_uInt16 j = 0; j < SPOTCOUNT; j++ )
802 if( j != i )
804 if( aSpotColor[i] == aSpotColor[j] )
806 aMatch[i]++;
812 // highest weight to center spot
813 aBackground = aSpotColor[0];
815 for ( sal_uInt16 nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- )
817 // which spot color was found most?
818 for ( i = 0; i < SPOTCOUNT; i++ )
820 if( aMatch[i] == nMatchCount )
822 aBackground = aSpotColor[i];
823 nMatchCount = 1; // break outer for-loop
824 break;
830 return aBackground;
832 } // end of anonymous namespace
834 Color GetTextEditBackgroundColor(const SdrObjEditView& rView)
836 svtools::ColorConfig aColorConfig;
837 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
838 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
840 if(!rStyleSettings.GetHighContrastMode())
842 bool bFound(false);
843 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(rView.GetTextEditObject());
845 if(pText && pText->IsClosedObj())
847 ::sdr::table::SdrTableObj* pTable = dynamic_cast< ::sdr::table::SdrTableObj * >( pText );
849 if( pTable )
850 bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground );
852 if( !bFound )
853 bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground);
856 if(!bFound && pText)
858 SdrPageView* pTextEditPV = rView.GetTextEditPageView();
860 if(pTextEditPV)
862 Point aPvOfs(pText->GetTextEditOffset());
863 const SdrPage* pPg = pTextEditPV->GetPage();
865 if(pPg)
867 Rectangle aSnapRect( pText->GetSnapRect() );
868 aSnapRect.Move(aPvOfs.X(), aPvOfs.Y());
870 return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg);
876 return aBackground;
879 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */