nss: upgrade to release 3.73
[LibreOffice.git] / svx / source / svdraw / svdetc.cxx
blob0d82f6632b35f1a2cb5d6cc86ad02b6e74d2b5e1
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 <officecfg/Office/Common.hxx>
23 #include <svtools/colorcfg.hxx>
24 #include <svx/svdetc.hxx>
25 #include <svx/svdedxv.hxx>
26 #include <svx/svdmodel.hxx>
27 #include <svx/svdoutl.hxx>
28 #include <vcl/bitmapaccess.hxx>
29 #include <editeng/eeitem.hxx>
30 #include <svl/itemset.hxx>
31 #include <svl/whiter.hxx>
32 #include <svx/xgrad.hxx>
33 #include <svx/xfillit0.hxx>
34 #include <svx/xflclit.hxx>
35 #include <svx/xflhtit.hxx>
36 #include <svx/xbtmpit.hxx>
37 #include <svx/xflgrit.hxx>
38 #include <svx/svdoole2.hxx>
39 #include <svl/itempool.hxx>
40 #include <tools/debug.hxx>
41 #include <unotools/configmgr.hxx>
42 #include <unotools/localedatawrapper.hxx>
43 #include <unotools/syslocale.hxx>
44 #include <svx/xflbckit.hxx>
45 #include <svx/extrusionbar.hxx>
46 #include <svx/fontworkbar.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/settings.hxx>
49 #include <svx/sdr/contact/viewcontact.hxx>
50 #include <svx/svdpage.hxx>
51 #include <svx/svdpagv.hxx>
52 #include <svx/svdotable.hxx>
53 #include <svx/sdrhittesthelper.hxx>
55 #include <com/sun/star/frame/XModel.hpp>
56 #include <com/sun/star/embed/XEmbeddedObject.hpp>
58 using namespace ::com::sun::star;
60 // Global data of the DrawingEngine
61 SdrGlobalData::SdrGlobalData()
62 : pSysLocale(nullptr)
63 , pLocaleData(nullptr)
65 if (!utl::ConfigManager::IsFuzzing())
67 svx::ExtrusionBar::RegisterInterface();
68 svx::FontworkBar::RegisterInterface();
72 const SvtSysLocale* SdrGlobalData::GetSysLocale()
74 if ( !pSysLocale )
75 pSysLocale = new SvtSysLocale;
76 return pSysLocale;
78 const LocaleDataWrapper* SdrGlobalData::GetLocaleData()
80 if ( !pLocaleData )
81 pLocaleData = GetSysLocale()->GetLocaleDataPtr();
82 return pLocaleData;
85 namespace {
87 struct TheSdrGlobalData: public rtl::Static<SdrGlobalData, TheSdrGlobalData> {};
91 SdrGlobalData & GetSdrGlobalData() {
92 return TheSdrGlobalData::get();
95 OLEObjCache::OLEObjCache()
97 if (!utl::ConfigManager::IsFuzzing())
98 nSize = officecfg::Office::Common::Cache::DrawingEngine::OLE_Objects::get();
99 else
100 nSize = 100;
101 pTimer.reset( new AutoTimer( "svx OLEObjCache pTimer UnloadCheck" ) );
102 pTimer->SetInvokeHandler( LINK(this, OLEObjCache, UnloadCheckHdl) );
103 pTimer->SetTimeout(20000);
104 pTimer->SetStatic();
107 OLEObjCache::~OLEObjCache()
109 pTimer->Stop();
112 IMPL_LINK_NOARG(OLEObjCache, UnloadCheckHdl, Timer*, void)
114 if (nSize >= maObjs.size())
115 return;
117 // more objects than configured cache size try to remove objects
118 // of course not the freshly inserted one at nIndex=0
119 size_t nCount2 = maObjs.size();
120 size_t nIndex = nCount2-1;
121 while( nIndex && nCount2 > nSize )
123 SdrOle2Obj* pUnloadObj = maObjs[nIndex--];
124 if (!pUnloadObj)
125 continue;
129 // it is important to get object without reinitialization to avoid reentrance
130 uno::Reference< embed::XEmbeddedObject > xUnloadObj = pUnloadObj->GetObjRef_NoInit();
132 bool bUnload = SdrOle2Obj::CanUnloadRunningObj( xUnloadObj, pUnloadObj->GetAspect() );
134 // check whether the object can be unloaded before looking for the parent objects
135 if ( xUnloadObj.is() && bUnload )
137 uno::Reference< frame::XModel > xUnloadModel( xUnloadObj->getComponent(), uno::UNO_QUERY );
138 if ( xUnloadModel.is() )
140 for (SdrOle2Obj* pCacheObj : maObjs)
142 if ( pCacheObj && pCacheObj != pUnloadObj )
144 uno::Reference< frame::XModel > xParentModel = pCacheObj->GetParentXModel();
145 if ( xUnloadModel == xParentModel )
146 bUnload = false; // the object has running embedded objects
152 if ( bUnload && UnloadObj(pUnloadObj) )
153 // object was successfully unloaded
154 nCount2--;
156 catch( uno::Exception& )
161 void OLEObjCache::InsertObj(SdrOle2Obj* pObj)
163 if (!maObjs.empty())
165 SdrOle2Obj* pExistingObj = maObjs.front();
166 if ( pObj == pExistingObj )
167 // the object is already on the top, nothing has to be changed
168 return;
171 // get the old position of the object to know whether it is already in container
172 std::vector<SdrOle2Obj*>::iterator it = std::find(maObjs.begin(), maObjs.end(), pObj);
173 bool bFound = it != maObjs.end();
175 if (bFound)
176 maObjs.erase(it);
177 // insert object into first position
178 maObjs.insert(maObjs.begin(), pObj);
180 // if a new object was inserted, recalculate the cache
181 if (!bFound)
182 pTimer->Invoke();
184 if (!bFound || !pTimer->IsActive())
185 pTimer->Start();
188 void OLEObjCache::RemoveObj(SdrOle2Obj* pObj)
190 std::vector<SdrOle2Obj*>::iterator it = std::find(maObjs.begin(), maObjs.end(), pObj);
191 if (it != maObjs.end())
192 maObjs.erase(it);
193 if (maObjs.empty())
194 pTimer->Stop();
197 size_t OLEObjCache::size() const
199 return maObjs.size();
202 SdrOle2Obj* OLEObjCache::operator[](size_t nPos)
204 return maObjs[nPos];
207 const SdrOle2Obj* OLEObjCache::operator[](size_t nPos) const
209 return maObjs[nPos];
212 bool OLEObjCache::UnloadObj(SdrOle2Obj* pObj)
214 bool bUnloaded = false;
215 if (pObj)
217 //#i80528# The old mechanism is completely useless, only taking into account if
218 // in all views the GrafDraft feature is used. This will nearly never have been the
219 // case since no one ever used this option.
221 // A much better (and working) criteria would be the VOC contact count.
222 // The question is what will happen when i make it work now suddenly? I
223 // will try it for 2.4.
224 const sdr::contact::ViewContact& rViewContact = pObj->GetViewContact();
225 const bool bVisible(rViewContact.HasViewObjectContacts());
227 if(!bVisible)
229 bUnloaded = pObj->Unload();
233 return bUnloaded;
236 bool GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
238 drawing::FillStyle eFill=rSet.Get(XATTR_FILLSTYLE).GetValue();
239 bool bRetval = false;
241 switch(eFill)
243 case drawing::FillStyle_SOLID:
245 rCol = rSet.Get(XATTR_FILLCOLOR).GetColorValue();
246 bRetval = true;
248 break;
250 case drawing::FillStyle_HATCH:
252 Color aCol1(rSet.Get(XATTR_FILLHATCH).GetHatchValue().GetColor());
253 Color aCol2(COL_WHITE);
255 // when hatched background is activated, use object fill color as hatch color
256 bool bFillHatchBackground = rSet.Get(XATTR_FILLBACKGROUND).GetValue();
257 if(bFillHatchBackground)
259 aCol2 = rSet.Get(XATTR_FILLCOLOR).GetColorValue();
262 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
263 rCol = Color(aAverageColor);
264 bRetval = true;
266 break;
268 case drawing::FillStyle_GRADIENT: {
269 const XGradient& rGrad=rSet.Get(XATTR_FILLGRADIENT).GetGradientValue();
270 Color aCol1(rGrad.GetStartColor());
271 Color aCol2(rGrad.GetEndColor());
272 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
273 rCol = Color(aAverageColor);
274 bRetval = true;
276 break;
278 case drawing::FillStyle_BITMAP:
280 Bitmap aBitmap(rSet.Get(XATTR_FILLBITMAP).GetGraphicObject().GetGraphic().GetBitmapEx().GetBitmap());
281 const Size aSize(aBitmap.GetSizePixel());
282 const sal_uInt32 nWidth = aSize.Width();
283 const sal_uInt32 nHeight = aSize.Height();
284 if (nWidth <= 0 || nHeight <= 0)
285 return bRetval;
287 Bitmap::ScopedReadAccess pAccess(aBitmap);
289 if (pAccess)
291 sal_uInt32 nRt(0);
292 sal_uInt32 nGn(0);
293 sal_uInt32 nBl(0);
294 const sal_uInt32 nMaxSteps(8);
295 const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1);
296 const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1);
297 sal_uInt32 nCount(0);
299 for(sal_uInt32 nY(0); nY < nHeight; nY += nYStep)
301 for(sal_uInt32 nX(0); nX < nWidth; nX += nXStep)
303 const BitmapColor& rCol2 = pAccess->GetColor(nY, nX);
305 nRt += rCol2.GetRed();
306 nGn += rCol2.GetGreen();
307 nBl += rCol2.GetBlue();
308 nCount++;
312 nRt /= nCount;
313 nGn /= nCount;
314 nBl /= nCount;
316 rCol = Color(sal_uInt8(nRt), sal_uInt8(nGn), sal_uInt8(nBl));
318 bRetval = true;
320 break;
322 default: break;
325 return bRetval;
328 std::unique_ptr<SdrOutliner> SdrMakeOutliner(OutlinerMode nOutlinerMode, SdrModel& rModel)
330 SfxItemPool* pPool = &rModel.GetItemPool();
331 std::unique_ptr<SdrOutliner> pOutl(new SdrOutliner( pPool, nOutlinerMode ));
332 pOutl->SetEditTextObjectPool( pPool );
333 pOutl->SetStyleSheetPool( static_cast<SfxStyleSheetPool*>(rModel.GetStyleSheetPool()));
334 pOutl->SetDefTab(rModel.GetDefaultTabulator());
335 Outliner::SetForbiddenCharsTable(rModel.GetForbiddenCharsTable());
336 pOutl->SetAsianCompressionMode(rModel.GetCharCompressType());
337 pOutl->SetKernAsianPunctuation(rModel.IsKernAsianPunctuation());
338 pOutl->SetAddExtLeading(rModel.IsAddExtLeading());
339 return pOutl;
342 std::vector<Link<SdrObjCreatorParams, SdrObject*>>& ImpGetUserMakeObjHdl()
344 SdrGlobalData& rGlobalData=GetSdrGlobalData();
345 return rGlobalData.aUserMakeObjHdl;
348 bool SearchOutlinerItems(const SfxItemSet& rSet, bool bInklDefaults, bool* pbOnlyEE)
350 bool bHas=false;
351 bool bOnly=true;
352 bool bLookOnly=pbOnlyEE!=nullptr;
353 SfxWhichIter aIter(rSet);
354 sal_uInt16 nWhich=aIter.FirstWhich();
355 while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) {
356 // For bInklDefaults, the entire Which range is decisive,
357 // in other cases only the set items are.
358 // Disabled and DontCare are regarded as holes in the Which range.
359 SfxItemState eState=rSet.GetItemState(nWhich);
360 if ((eState==SfxItemState::DEFAULT && bInklDefaults) || eState==SfxItemState::SET) {
361 if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=false;
362 else bHas=true;
364 nWhich=aIter.NextWhich();
366 if (!bHas) bOnly=false;
367 if (pbOnlyEE!=nullptr) *pbOnlyEE=bOnly;
368 return bHas;
371 std::unique_ptr<sal_uInt16[]> RemoveWhichRange(const sal_uInt16* pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd)
373 // Six possible cases (per range):
374 // [Beg..End] Range, to delete
375 // [b..e] [b..e] [b..e] Cases 1,3,2: doesn't matter, delete, doesn't matter + Ranges
376 // [b........e] [b........e] Cases 4,5 : shrink range | in
377 // [b......................e] Case 6 : splitting + pOldWhichTable
378 sal_uInt16 nCount=0;
379 while (pOldWhichTable[nCount]!=0) nCount++;
380 nCount++; // nCount should now be an odd number (0 for end of array)
381 DBG_ASSERT((nCount&1)==1,"RemoveWhichRange: WhichTable doesn't have an odd number of entries.");
382 sal_uInt16 nAlloc=nCount;
383 // check necessary size of new array
384 sal_uInt16 nNum=nCount-1;
385 while (nNum!=0) {
386 nNum-=2;
387 sal_uInt16 nBeg=pOldWhichTable[nNum];
388 sal_uInt16 nEnd=pOldWhichTable[nNum+1];
389 if (nEnd<nRangeBeg) /*nCase=1*/ ;
390 else if (nBeg>nRangeEnd) /* nCase=2 */ ;
391 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2;
392 else if (nEnd<=nRangeEnd) /* nCase=4 */;
393 else if (nBeg>=nRangeBeg) /* nCase=5*/ ;
394 else /* nCase=6 */ nAlloc+=2;
397 std::unique_ptr<sal_uInt16[]> pNewWhichTable(new sal_uInt16[nAlloc]);
398 memcpy(pNewWhichTable.get(), pOldWhichTable, nAlloc*sizeof(sal_uInt16));
399 pNewWhichTable[nAlloc-1]=0; // in case 3, there's no 0 at the end.
400 // now remove the unwanted ranges
401 nNum=nAlloc-1;
402 while (nNum!=0) {
403 nNum-=2;
404 sal_uInt16 nBeg=pNewWhichTable[nNum];
405 sal_uInt16 nEnd=pNewWhichTable[nNum+1];
406 unsigned nCase=0;
407 if (nEnd<nRangeBeg) nCase=1;
408 else if (nBeg>nRangeEnd) nCase=2;
409 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3;
410 else if (nEnd<=nRangeEnd) nCase=4;
411 else if (nBeg>=nRangeBeg) nCase=5;
412 else nCase=6;
413 switch (nCase) {
414 case 3: {
415 unsigned nTailBytes=(nCount-(nNum+2))*sizeof(sal_uInt16);
416 memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes);
417 nCount-=2; // remember: array is now smaller
418 } break;
419 case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break;
420 case 5: pNewWhichTable[nNum]=nRangeEnd+1; break;
421 case 6: {
422 unsigned nTailBytes=(nCount-(nNum+2))*sizeof(sal_uInt16);
423 memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes);
424 nCount+=2; // remember:array is now larger
425 pNewWhichTable[nNum+2]=nRangeEnd+1;
426 pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1];
427 pNewWhichTable[nNum+1]=nRangeBeg-1;
428 } break;
429 } // switch
431 return pNewWhichTable;
435 SvdProgressInfo::SvdProgressInfo( const Link<void*,bool>&_rLink )
437 maLink = _rLink;
438 m_nSumCurAction = 0;
440 m_nObjCount = 0;
441 m_nCurObj = 0;
443 m_nActionCount = 0;
444 m_nCurAction = 0;
446 m_nInsertCount = 0;
447 m_nCurInsert = 0;
450 void SvdProgressInfo::Init( size_t nObjCount )
452 m_nObjCount = nObjCount;
455 bool SvdProgressInfo::ReportActions( size_t nActionCount )
457 m_nSumCurAction += nActionCount;
458 m_nCurAction += nActionCount;
459 if(m_nCurAction > m_nActionCount)
460 m_nCurAction = m_nActionCount;
462 return maLink.Call(nullptr);
465 void SvdProgressInfo::ReportInserts( size_t nInsertCount )
467 m_nSumCurAction += nInsertCount;
468 m_nCurInsert += nInsertCount;
470 maLink.Call(nullptr);
473 void SvdProgressInfo::ReportRescales( size_t nRescaleCount )
475 m_nSumCurAction += nRescaleCount;
476 maLink.Call(nullptr);
479 void SvdProgressInfo::SetActionCount( size_t nActionCount )
481 m_nActionCount = nActionCount;
484 void SvdProgressInfo::SetInsertCount( size_t nInsertCount )
486 m_nInsertCount = nInsertCount;
489 void SvdProgressInfo::SetNextObject()
491 m_nActionCount = 0;
492 m_nCurAction = 0;
494 m_nInsertCount = 0;
495 m_nCurInsert = 0;
497 m_nCurObj++;
498 ReportActions(0);
501 // #i101872# isolate GetTextEditBackgroundColor to tooling; it will anyways only be used as long
502 // as text edit is not running on overlay
504 namespace
506 bool impGetSdrObjListFillColor(
507 const SdrObjList& rList,
508 const Point& rPnt,
509 const SdrPageView& rTextEditPV,
510 const SdrLayerIDSet& rVisLayers,
511 Color& rCol)
513 bool bRet(false);
514 bool bMaster(rList.getSdrPageFromSdrObjList() && rList.getSdrPageFromSdrObjList()->IsMasterPage());
516 for(size_t no(rList.GetObjCount()); !bRet && no > 0; )
518 no--;
519 SdrObject* pObj = rList.GetObj(no);
520 SdrObjList* pOL = pObj->GetSubList();
522 if(pOL)
524 // group object
525 bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol);
527 else
529 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj);
531 // Exclude zero master page object (i.e. background shape) from color query
532 if(pText
533 && pObj->IsClosedObj()
534 && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
535 && pObj->GetCurrentBoundRect().IsInside(rPnt)
536 && !pText->IsHideContour()
537 && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
539 bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
544 return bRet;
547 bool impGetSdrPageFillColor(
548 const SdrPage& rPage,
549 const Point& rPnt,
550 const SdrPageView& rTextEditPV,
551 const SdrLayerIDSet& rVisLayers,
552 Color& rCol,
553 bool bSkipBackgroundShape)
555 bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol));
557 if(!bRet && !rPage.IsMasterPage())
559 if(rPage.TRG_HasMasterPage())
561 SdrLayerIDSet aSet(rVisLayers);
562 aSet &= rPage.TRG_GetMasterPageVisibleLayers();
563 SdrPage& rMasterPage = rPage.TRG_GetMasterPage();
565 // Don't fall back to background shape on
566 // master pages. This is later handled by
567 // GetBackgroundColor, and is necessary to cater for
568 // the silly ordering: 1. shapes, 2. master page
569 // shapes, 3. page background, 4. master page
570 // background.
571 bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true);
575 // Only now determine background color from background shapes
576 if(!bRet && !bSkipBackgroundShape)
578 rCol = rPage.GetPageBackgroundColor();
579 return true;
582 return bRet;
585 Color impCalcBackgroundColor(
586 const tools::Rectangle& rArea,
587 const SdrPageView& rTextEditPV,
588 const SdrPage& rPage)
590 svtools::ColorConfig aColorConfig;
591 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
592 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
594 if(!rStyleSettings.GetHighContrastMode())
596 // search in page
597 const sal_uInt16 SPOTCOUNT(5);
598 Point aSpotPos[SPOTCOUNT];
599 Color aSpotColor[SPOTCOUNT];
600 sal_uInt32 nHeight( rArea.GetSize().Height() );
601 sal_uInt32 nWidth( rArea.GetSize().Width() );
602 sal_uInt32 nWidth14 = nWidth / 4;
603 sal_uInt32 nHeight14 = nHeight / 4;
604 sal_uInt32 nWidth34 = ( 3 * nWidth ) / 4;
605 sal_uInt32 nHeight34 = ( 3 * nHeight ) / 4;
607 sal_uInt16 i;
608 for ( i = 0; i < SPOTCOUNT; i++ )
610 // five spots are used
611 switch ( i )
613 case 0 :
615 // Center-Spot
616 aSpotPos[i] = rArea.Center();
618 break;
620 case 1 :
622 // TopLeft-Spot
623 aSpotPos[i] = rArea.TopLeft();
624 aSpotPos[i].AdjustX(nWidth14 );
625 aSpotPos[i].AdjustY(nHeight14 );
627 break;
629 case 2 :
631 // TopRight-Spot
632 aSpotPos[i] = rArea.TopLeft();
633 aSpotPos[i].AdjustX(nWidth34 );
634 aSpotPos[i].AdjustY(nHeight14 );
636 break;
638 case 3 :
640 // BottomLeft-Spot
641 aSpotPos[i] = rArea.TopLeft();
642 aSpotPos[i].AdjustX(nWidth14 );
643 aSpotPos[i].AdjustY(nHeight34 );
645 break;
647 case 4 :
649 // BottomRight-Spot
650 aSpotPos[i] = rArea.TopLeft();
651 aSpotPos[i].AdjustX(nWidth34 );
652 aSpotPos[i].AdjustY(nHeight34 );
654 break;
658 aSpotColor[i] = COL_WHITE;
659 impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false);
662 sal_uInt16 aMatch[SPOTCOUNT];
664 for ( i = 0; i < SPOTCOUNT; i++ )
666 // were same spot colors found?
667 aMatch[i] = 0;
669 for ( sal_uInt16 j = 0; j < SPOTCOUNT; j++ )
671 if( j != i )
673 if( aSpotColor[i] == aSpotColor[j] )
675 aMatch[i]++;
681 // highest weight to center spot
682 aBackground = aSpotColor[0];
684 for ( sal_uInt16 nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- )
686 // which spot color was found most?
687 for ( i = 0; i < SPOTCOUNT; i++ )
689 if( aMatch[i] == nMatchCount )
691 aBackground = aSpotColor[i];
692 nMatchCount = 1; // break outer for-loop
693 break;
699 return aBackground;
701 } // end of anonymous namespace
703 Color GetTextEditBackgroundColor(const SdrObjEditView& rView)
705 svtools::ColorConfig aColorConfig;
706 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
707 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
709 if(!rStyleSettings.GetHighContrastMode())
711 bool bFound(false);
712 SdrTextObj* pText = rView.GetTextEditObject();
714 if(pText && pText->IsClosedObj())
716 sdr::table::SdrTableObj* pTable = dynamic_cast< sdr::table::SdrTableObj * >( pText );
718 if( pTable )
719 bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground );
721 if( !bFound )
722 bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground);
725 if(!bFound && pText)
727 SdrPageView* pTextEditPV = rView.GetTextEditPageView();
729 if(pTextEditPV)
731 Point aPvOfs(pText->GetTextEditOffset());
732 const SdrPage* pPg = pTextEditPV->GetPage();
734 if(pPg)
736 tools::Rectangle aSnapRect( pText->GetSnapRect() );
737 aSnapRect.Move(aPvOfs.X(), aPvOfs.Y());
739 return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg);
745 return aBackground;
748 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */