Adjust includes
[LibreOffice.git] / svx / source / svdraw / svdetc.cxx
blob807e31fc6da9cf544830354d3936e51b1d8b59f4
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 <officecfg/Office/Common.hxx>
24 #include <svx/dialmgr.hxx>
25 #include <svx/svdetc.hxx>
26 #include <svx/svdmodel.hxx>
27 #include <svx/svdtrans.hxx>
28 #include <svdglob.hxx>
29 #include <svx/strings.hrc>
30 #include <svx/svdviter.hxx>
31 #include <svx/svdview.hxx>
32 #include <svx/svdoutl.hxx>
33 #include <vcl/bitmapaccess.hxx>
34 #include <editeng/editdata.hxx>
35 #include <editeng/eeitem.hxx>
36 #include <svl/itemset.hxx>
37 #include <svl/whiter.hxx>
38 #include <editeng/fontitem.hxx>
39 #include <editeng/colritem.hxx>
40 #include <editeng/fhgtitem.hxx>
41 #include <svx/xgrad.hxx>
42 #include <svx/xfillit0.hxx>
43 #include <svx/xflclit.hxx>
44 #include <svx/xflhtit.hxx>
45 #include <svx/xbtmpit.hxx>
46 #include <svx/xflgrit.hxx>
47 #include <svx/svdoole2.hxx>
48 #include <svl/itempool.hxx>
49 #include <unotools/configmgr.hxx>
50 #include <unotools/localedatawrapper.hxx>
51 #include <i18nlangtag/lang.h>
52 #include <unotools/syslocale.hxx>
53 #include <svx/xflbckit.hxx>
54 #include <svx/extrusionbar.hxx>
55 #include <svx/fontworkbar.hxx>
56 #include <vcl/svapp.hxx>
57 #include <vcl/settings.hxx>
58 #include <svx/sdr/contact/viewcontact.hxx>
59 #include <svx/svdpage.hxx>
60 #include <svx/svdotable.hxx>
61 #include <svx/sdrhittesthelper.hxx>
63 #include <com/sun/star/frame/XModel.hpp>
64 #include <com/sun/star/embed/XEmbeddedObject.hpp>
65 #include <com/sun/star/embed/EmbedStates.hpp>
66 #include <com/sun/star/lang/Locale.hpp>
68 using namespace ::com::sun::star;
70 // Global data of the DrawingEngine
71 SdrGlobalData::SdrGlobalData()
72 : pSysLocale(nullptr)
73 , pLocaleData(nullptr)
75 if (!utl::ConfigManager::IsFuzzing())
77 svx::ExtrusionBar::RegisterInterface();
78 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;
95 namespace {
97 struct TheSdrGlobalData: public rtl::Static<SdrGlobalData, TheSdrGlobalData> {};
101 SdrGlobalData & GetSdrGlobalData() {
102 return TheSdrGlobalData::get();
105 OLEObjCache::OLEObjCache()
107 if (!utl::ConfigManager::IsFuzzing())
108 nSize = officecfg::Office::Common::Cache::DrawingEngine::OLE_Objects::get();
109 else
110 nSize = 100;
111 pTimer = new AutoTimer( "svx OLEObjCache pTimer UnloadCheck" );
112 pTimer->SetInvokeHandler( LINK(this, OLEObjCache, UnloadCheckHdl) );
113 pTimer->SetTimeout(20000);
114 pTimer->SetStatic();
117 OLEObjCache::~OLEObjCache()
119 pTimer->Stop();
120 delete pTimer;
123 IMPL_LINK_NOARG(OLEObjCache, UnloadCheckHdl, Timer*, void)
125 if (nSize >= maObjs.size())
126 return;
128 // more objects than configured cache size try to remove objects
129 // of course not the freshly inserted one at nIndex=0
130 size_t nCount2 = maObjs.size();
131 size_t nIndex = nCount2-1;
132 while( nIndex && nCount2 > nSize )
134 SdrOle2Obj* pUnloadObj = maObjs[nIndex--];
135 if (!pUnloadObj)
136 continue;
140 // it is important to get object without reinitialization to avoid reentrance
141 uno::Reference< embed::XEmbeddedObject > xUnloadObj = pUnloadObj->GetObjRef_NoInit();
143 bool bUnload = SdrOle2Obj::CanUnloadRunningObj( xUnloadObj, pUnloadObj->GetAspect() );
145 // check whether the object can be unloaded before looking for the parent objects
146 if ( xUnloadObj.is() && bUnload )
148 uno::Reference< frame::XModel > xUnloadModel( xUnloadObj->getComponent(), uno::UNO_QUERY );
149 if ( xUnloadModel.is() )
151 for (SdrOle2Obj* pCacheObj : maObjs)
153 if ( pCacheObj && pCacheObj != pUnloadObj )
155 uno::Reference< frame::XModel > xParentModel = pCacheObj->GetParentXModel();
156 if ( xUnloadModel == xParentModel )
157 bUnload = false; // the object has running embedded objects
163 if ( bUnload && UnloadObj(pUnloadObj) )
164 // object was successfully unloaded
165 nCount2--;
167 catch( uno::Exception& )
172 void OLEObjCache::InsertObj(SdrOle2Obj* pObj)
174 if (!maObjs.empty())
176 SdrOle2Obj* pExistingObj = maObjs.front();
177 if ( pObj == pExistingObj )
178 // the object is already on the top, nothing has to be changed
179 return;
182 // get the old position of the object to know whether it is already in container
183 std::vector<SdrOle2Obj*>::iterator it = std::find(maObjs.begin(), maObjs.end(), pObj);
184 bool bFound = it != maObjs.end();
186 if (bFound)
187 maObjs.erase(it);
188 // insert object into first position
189 maObjs.insert(maObjs.begin(), pObj);
191 // if a new object was inserted, recalculate the cache
192 if (!bFound)
193 pTimer->Invoke();
195 if (!bFound || !pTimer->IsActive())
196 pTimer->Start();
199 void OLEObjCache::RemoveObj(SdrOle2Obj* pObj)
201 std::vector<SdrOle2Obj*>::iterator it = std::find(maObjs.begin(), maObjs.end(), pObj);
202 if (it != maObjs.end())
203 maObjs.erase(it);
204 if (maObjs.empty())
205 pTimer->Stop();
208 size_t OLEObjCache::size() const
210 return maObjs.size();
213 SdrOle2Obj* OLEObjCache::operator[](size_t nPos)
215 return maObjs[nPos];
218 const SdrOle2Obj* OLEObjCache::operator[](size_t nPos) const
220 return maObjs[nPos];
223 bool OLEObjCache::UnloadObj(SdrOle2Obj* pObj)
225 bool bUnloaded = false;
226 if (pObj)
228 //#i80528# The old mechanism is completely useless, only taking into account if
229 // in all views the GrafDraft feature is used. This will nearly never have been the
230 // case since no one ever used this option.
232 // A much better (and working) criteria would be the VOC contact count.
233 // The question is what will happen when i make it work now suddenly? I
234 // will try it for 2.4.
235 const sdr::contact::ViewContact& rViewContact = pObj->GetViewContact();
236 const bool bVisible(rViewContact.HasViewObjectContacts());
238 if(!bVisible)
240 bUnloaded = pObj->Unload();
244 return bUnloaded;
247 bool GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
249 drawing::FillStyle eFill=rSet.Get(XATTR_FILLSTYLE).GetValue();
250 bool bRetval = false;
252 switch(eFill)
254 case drawing::FillStyle_SOLID:
256 rCol = rSet.Get(XATTR_FILLCOLOR).GetColorValue();
257 bRetval = true;
259 break;
261 case drawing::FillStyle_HATCH:
263 Color aCol1(rSet.Get(XATTR_FILLHATCH).GetHatchValue().GetColor());
264 Color aCol2(COL_WHITE);
266 // when hatched background is activated, use object fill color as hatch color
267 bool bFillHatchBackground = rSet.Get(XATTR_FILLBACKGROUND).GetValue();
268 if(bFillHatchBackground)
270 aCol2 = rSet.Get(XATTR_FILLCOLOR).GetColorValue();
273 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
274 rCol = Color(aAverageColor);
275 bRetval = true;
277 break;
279 case drawing::FillStyle_GRADIENT: {
280 const XGradient& rGrad=rSet.Get(XATTR_FILLGRADIENT).GetGradientValue();
281 Color aCol1(rGrad.GetStartColor());
282 Color aCol2(rGrad.GetEndColor());
283 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
284 rCol = Color(aAverageColor);
285 bRetval = true;
287 break;
289 case drawing::FillStyle_BITMAP:
291 Bitmap aBitmap(rSet.Get(XATTR_FILLBITMAP).GetGraphicObject().GetGraphic().GetBitmapEx().GetBitmap());
292 const Size aSize(aBitmap.GetSizePixel());
293 const sal_uInt32 nWidth = aSize.Width();
294 const sal_uInt32 nHeight = aSize.Height();
295 Bitmap::ScopedReadAccess pAccess(aBitmap);
297 if(pAccess && nWidth > 0 && nHeight > 0)
299 sal_uInt32 nRt(0);
300 sal_uInt32 nGn(0);
301 sal_uInt32 nBl(0);
302 const sal_uInt32 nMaxSteps(8);
303 const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1);
304 const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1);
305 sal_uInt32 nCount(0);
307 for(sal_uInt32 nY(0); nY < nHeight; nY += nYStep)
309 for(sal_uInt32 nX(0); nX < nWidth; nX += nXStep)
311 const BitmapColor& rCol2 = pAccess->GetColor(nY, nX);
313 nRt += rCol2.GetRed();
314 nGn += rCol2.GetGreen();
315 nBl += rCol2.GetBlue();
316 nCount++;
320 nRt /= nCount;
321 nGn /= nCount;
322 nBl /= nCount;
324 rCol = Color(sal_uInt8(nRt), sal_uInt8(nGn), sal_uInt8(nBl));
326 bRetval = true;
328 break;
330 default: break;
333 return bRetval;
336 SdrOutliner* SdrMakeOutliner(OutlinerMode nOutlinerMode, SdrModel& rModel)
338 SfxItemPool* pPool = &rModel.GetItemPool();
339 SdrOutliner* pOutl = new SdrOutliner( pPool, nOutlinerMode );
340 pOutl->SetEditTextObjectPool( pPool );
341 pOutl->SetStyleSheetPool( static_cast<SfxStyleSheetPool*>(rModel.GetStyleSheetPool()));
342 pOutl->SetDefTab(rModel.GetDefaultTabulator());
343 Outliner::SetForbiddenCharsTable(rModel.GetForbiddenCharsTable());
344 pOutl->SetAsianCompressionMode(rModel.GetCharCompressType());
345 pOutl->SetKernAsianPunctuation(rModel.IsKernAsianPunctuation());
346 pOutl->SetAddExtLeading(rModel.IsAddExtLeading());
347 return pOutl;
350 std::vector<Link<SdrObjCreatorParams, SdrObject*>>& ImpGetUserMakeObjHdl()
352 SdrGlobalData& rGlobalData=GetSdrGlobalData();
353 return rGlobalData.aUserMakeObjHdl;
356 OUString ImpGetResStr(const char* pResID)
358 return SvxResId(pResID);
361 namespace sdr
363 OUString GetResourceString(const char* pResID)
365 return ImpGetResStr(pResID);
369 bool SearchOutlinerItems(const SfxItemSet& rSet, bool bInklDefaults, bool* pbOnlyEE)
371 bool bHas=false;
372 bool bOnly=true;
373 bool bLookOnly=pbOnlyEE!=nullptr;
374 SfxWhichIter aIter(rSet);
375 sal_uInt16 nWhich=aIter.FirstWhich();
376 while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) {
377 // For bInklDefaults, the entire Which range is decisive,
378 // in other cases only the set items are.
379 // Disabled and DontCare are regarded as holes in the Which range.
380 SfxItemState eState=rSet.GetItemState(nWhich);
381 if ((eState==SfxItemState::DEFAULT && bInklDefaults) || eState==SfxItemState::SET) {
382 if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=false;
383 else bHas=true;
385 nWhich=aIter.NextWhich();
387 if (!bHas) bOnly=false;
388 if (pbOnlyEE!=nullptr) *pbOnlyEE=bOnly;
389 return bHas;
392 sal_uInt16* RemoveWhichRange(const sal_uInt16* pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd)
394 // Six possible cases (per range):
395 // [Beg..End] Range, to delete
396 // [b..e] [b..e] [b..e] Cases 1,3,2: doesn't matter, delete, doesn't matter + Ranges
397 // [b........e] [b........e] Cases 4,5 : shrink range | in
398 // [b......................e] Case 6 : splitting + pOldWhichTable
399 sal_uInt16 nCount=0;
400 while (pOldWhichTable[nCount]!=0) nCount++;
401 nCount++; // nCount should now be an odd number (0 for end of array)
402 DBG_ASSERT((nCount&1)==1,"RemoveWhichRange: WhichTable doesn't have an odd number of entries.");
403 sal_uInt16 nAlloc=nCount;
404 // check necessary size of new array
405 sal_uInt16 nNum=nCount-1;
406 while (nNum!=0) {
407 nNum-=2;
408 sal_uInt16 nBeg=pOldWhichTable[nNum];
409 sal_uInt16 nEnd=pOldWhichTable[nNum+1];
410 if (nEnd<nRangeBeg) /*nCase=1*/ ;
411 else if (nBeg>nRangeEnd) /* nCase=2 */ ;
412 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2;
413 else if (nEnd<=nRangeEnd) /* nCase=4 */;
414 else if (nBeg>=nRangeBeg) /* nCase=5*/ ;
415 else /* nCase=6 */ nAlloc+=2;
418 sal_uInt16* pNewWhichTable=new sal_uInt16[nAlloc];
419 memcpy(pNewWhichTable,pOldWhichTable,nAlloc*sizeof(sal_uInt16));
420 pNewWhichTable[nAlloc-1]=0; // in case 3, there's no 0 at the end.
421 // now remove the unwanted ranges
422 nNum=nAlloc-1;
423 while (nNum!=0) {
424 nNum-=2;
425 sal_uInt16 nBeg=pNewWhichTable[nNum];
426 sal_uInt16 nEnd=pNewWhichTable[nNum+1];
427 unsigned nCase=0;
428 if (nEnd<nRangeBeg) nCase=1;
429 else if (nBeg>nRangeEnd) nCase=2;
430 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3;
431 else if (nEnd<=nRangeEnd) nCase=4;
432 else if (nBeg>=nRangeBeg) nCase=5;
433 else nCase=6;
434 switch (nCase) {
435 case 3: {
436 unsigned nTailBytes=(nCount-(nNum+2))*sizeof(sal_uInt16);
437 memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes);
438 nCount-=2; // remember: array is now smaller
439 } break;
440 case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break;
441 case 5: pNewWhichTable[nNum]=nRangeEnd+1; break;
442 case 6: {
443 unsigned nTailBytes=(nCount-(nNum+2))*sizeof(sal_uInt16);
444 memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes);
445 nCount+=2; // remember:array is now larger
446 pNewWhichTable[nNum+2]=nRangeEnd+1;
447 pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1];
448 pNewWhichTable[nNum+1]=nRangeBeg-1;
449 } break;
450 } // switch
452 return pNewWhichTable;
456 SvdProgressInfo::SvdProgressInfo( const Link<void*,bool>&_rLink )
458 maLink = _rLink;
459 m_nSumCurAction = 0;
461 m_nObjCount = 0;
462 m_nCurObj = 0;
464 m_nActionCount = 0;
465 m_nCurAction = 0;
467 m_nInsertCount = 0;
468 m_nCurInsert = 0;
471 void SvdProgressInfo::Init( size_t nObjCount )
473 m_nObjCount = nObjCount;
476 bool SvdProgressInfo::ReportActions( size_t nActionCount )
478 m_nSumCurAction += nActionCount;
479 m_nCurAction += nActionCount;
480 if(m_nCurAction > m_nActionCount)
481 m_nCurAction = m_nActionCount;
483 return maLink.Call(nullptr);
486 void SvdProgressInfo::ReportInserts( size_t nInsertCount )
488 m_nSumCurAction += nInsertCount;
489 m_nCurInsert += nInsertCount;
491 maLink.Call(nullptr);
494 void SvdProgressInfo::ReportRescales( size_t nRescaleCount )
496 m_nSumCurAction += nRescaleCount;
497 maLink.Call(nullptr);
500 void SvdProgressInfo::SetActionCount( size_t nActionCount )
502 m_nActionCount = nActionCount;
505 void SvdProgressInfo::SetInsertCount( size_t nInsertCount )
507 m_nInsertCount = nInsertCount;
510 void SvdProgressInfo::SetNextObject()
512 m_nActionCount = 0;
513 m_nCurAction = 0;
515 m_nInsertCount = 0;
516 m_nCurInsert = 0;
518 m_nCurObj++;
519 ReportActions(0);
522 // #i101872# isolate GetTextEditBackgroundColor to tooling; it will anyways only be used as long
523 // as text edit is not running on overlay
525 namespace
527 bool impGetSdrObjListFillColor(
528 const SdrObjList& rList,
529 const Point& rPnt,
530 const SdrPageView& rTextEditPV,
531 const SdrLayerIDSet& rVisLayers,
532 Color& rCol)
534 if(!rList.GetModel())
535 return false;
537 bool bRet(false);
538 bool bMaster(rList.GetPage() && rList.GetPage()->IsMasterPage());
540 for(size_t no(rList.GetObjCount()); !bRet && no > 0; )
542 no--;
543 SdrObject* pObj = rList.GetObj(no);
544 SdrObjList* pOL = pObj->GetSubList();
546 if(pOL)
548 // group object
549 bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol);
551 else
553 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj);
555 // Exclude zero master page object (i.e. background shape) from color query
556 if(pText
557 && pObj->IsClosedObj()
558 && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
559 && pObj->GetCurrentBoundRect().IsInside(rPnt)
560 && !pText->IsHideContour()
561 && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
563 bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
568 return bRet;
571 bool impGetSdrPageFillColor(
572 const SdrPage& rPage,
573 const Point& rPnt,
574 const SdrPageView& rTextEditPV,
575 const SdrLayerIDSet& rVisLayers,
576 Color& rCol,
577 bool bSkipBackgroundShape)
579 if(!rPage.GetModel())
580 return false;
582 bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol));
584 if(!bRet && !rPage.IsMasterPage())
586 if(rPage.TRG_HasMasterPage())
588 SdrLayerIDSet aSet(rVisLayers);
589 aSet &= rPage.TRG_GetMasterPageVisibleLayers();
590 SdrPage& rMasterPage = rPage.TRG_GetMasterPage();
592 // Don't fall back to background shape on
593 // master pages. This is later handled by
594 // GetBackgroundColor, and is necessary to cater for
595 // the silly ordering: 1. shapes, 2. master page
596 // shapes, 3. page background, 4. master page
597 // background.
598 bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true);
602 // Only now determine background color from background shapes
603 if(!bRet && !bSkipBackgroundShape)
605 rCol = rPage.GetPageBackgroundColor();
606 return true;
609 return bRet;
612 Color impCalcBackgroundColor(
613 const tools::Rectangle& rArea,
614 const SdrPageView& rTextEditPV,
615 const SdrPage& rPage)
617 svtools::ColorConfig aColorConfig;
618 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
619 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
621 if(!rStyleSettings.GetHighContrastMode())
623 // search in page
624 const sal_uInt16 SPOTCOUNT(5);
625 Point aSpotPos[SPOTCOUNT];
626 Color aSpotColor[SPOTCOUNT];
627 sal_uInt32 nHeight( rArea.GetSize().Height() );
628 sal_uInt32 nWidth( rArea.GetSize().Width() );
629 sal_uInt32 nWidth14 = nWidth / 4;
630 sal_uInt32 nHeight14 = nHeight / 4;
631 sal_uInt32 nWidth34 = ( 3 * nWidth ) / 4;
632 sal_uInt32 nHeight34 = ( 3 * nHeight ) / 4;
634 sal_uInt16 i;
635 for ( i = 0; i < SPOTCOUNT; i++ )
637 // five spots are used
638 switch ( i )
640 case 0 :
642 // Center-Spot
643 aSpotPos[i] = rArea.Center();
645 break;
647 case 1 :
649 // TopLeft-Spot
650 aSpotPos[i] = rArea.TopLeft();
651 aSpotPos[i].X() += nWidth14;
652 aSpotPos[i].Y() += nHeight14;
654 break;
656 case 2 :
658 // TopRight-Spot
659 aSpotPos[i] = rArea.TopLeft();
660 aSpotPos[i].X() += nWidth34;
661 aSpotPos[i].Y() += nHeight14;
663 break;
665 case 3 :
667 // BottomLeft-Spot
668 aSpotPos[i] = rArea.TopLeft();
669 aSpotPos[i].X() += nWidth14;
670 aSpotPos[i].Y() += nHeight34;
672 break;
674 case 4 :
676 // BottomRight-Spot
677 aSpotPos[i] = rArea.TopLeft();
678 aSpotPos[i].X() += nWidth34;
679 aSpotPos[i].Y() += nHeight34;
681 break;
685 aSpotColor[i] = Color( COL_WHITE );
686 impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false);
689 sal_uInt16 aMatch[SPOTCOUNT];
691 for ( i = 0; i < SPOTCOUNT; i++ )
693 // were same spot colors found?
694 aMatch[i] = 0;
696 for ( sal_uInt16 j = 0; j < SPOTCOUNT; j++ )
698 if( j != i )
700 if( aSpotColor[i] == aSpotColor[j] )
702 aMatch[i]++;
708 // highest weight to center spot
709 aBackground = aSpotColor[0];
711 for ( sal_uInt16 nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- )
713 // which spot color was found most?
714 for ( i = 0; i < SPOTCOUNT; i++ )
716 if( aMatch[i] == nMatchCount )
718 aBackground = aSpotColor[i];
719 nMatchCount = 1; // break outer for-loop
720 break;
726 return aBackground;
728 } // end of anonymous namespace
730 Color GetTextEditBackgroundColor(const SdrObjEditView& rView)
732 svtools::ColorConfig aColorConfig;
733 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
734 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
736 if(!rStyleSettings.GetHighContrastMode())
738 bool bFound(false);
739 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(rView.GetTextEditObject());
741 if(pText && pText->IsClosedObj())
743 sdr::table::SdrTableObj* pTable = dynamic_cast< sdr::table::SdrTableObj * >( pText );
745 if( pTable )
746 bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground );
748 if( !bFound )
749 bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground);
752 if(!bFound && pText)
754 SdrPageView* pTextEditPV = rView.GetTextEditPageView();
756 if(pTextEditPV)
758 Point aPvOfs(pText->GetTextEditOffset());
759 const SdrPage* pPg = pTextEditPV->GetPage();
761 if(pPg)
763 tools::Rectangle aSnapRect( pText->GetSnapRect() );
764 aSnapRect.Move(aPvOfs.X(), aPvOfs.Y());
766 return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg);
772 return aBackground;
775 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */