1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include "editeng/forbiddencharacterstable.hxx"
27 #include <com/sun/star/embed/XEmbeddedObject.hpp>
28 #include <com/sun/star/embed/EmbedStates.hpp>
29 #include <svx/svdetc.hxx>
30 #include "svx/svditext.hxx"
31 #include <svx/svdmodel.hxx>
32 #include <svx/svdtrans.hxx>
33 #include "svx/svdglob.hxx"
34 #include "svx/svdstr.hrc"
35 #include "svx/svdviter.hxx"
36 #include <svx/svdview.hxx>
37 #include <svx/svdoutl.hxx>
38 #include <vcl/bmpacc.hxx>
39 #include <editeng/eeitem.hxx>
40 #include <svl/itemset.hxx>
41 #include <tools/config.hxx>
42 #include <unotools/cacheoptions.hxx>
43 #include <svl/whiter.hxx>
44 #include <tools/bigint.hxx>
45 #include "editeng/fontitem.hxx"
46 #include <editeng/colritem.hxx>
47 #include <editeng/fhgtitem.hxx>
48 #include <svx/xgrad.hxx>
49 #include <svx/xfillit0.hxx>
50 #include <svx/xflclit.hxx>
51 #include <svx/xflhtit.hxx>
52 #include <svx/xbtmpit.hxx>
53 #include <svx/xflgrit.hxx>
54 #include <svx/svdoole2.hxx>
55 #include <svl/itempool.hxx>
56 #include <unotools/localedatawrapper.hxx>
57 #include <com/sun/star/lang/Locale.hpp>
58 #include <comphelper/processfactory.hxx>
59 #include <i18npool/lang.h>
60 #include <unotools/charclass.hxx>
61 #include <unotools/syslocale.hxx>
62 #include <svx/xflbckit.hxx>
63 #include <svx/extrusionbar.hxx>
64 #include <svx/fontworkbar.hxx>
65 #include <vcl/svapp.hxx> //add CHINA001
66 #include <svx/sdr/contact/viewcontact.hxx>
67 #include <svx/svdpage.hxx>
68 #include <svx/svdotable.hxx>
69 #include <svx/sdrhittesthelper.hxx>
70
71 using namespace ::com::sun::star;
72
73 /******************************************************************************
74 * Globale Daten der DrawingEngine
75 ******************************************************************************/
76
SdrGlobalData()77 SdrGlobalData::SdrGlobalData() :
78 pSysLocale(NULL),
79 pCharClass(NULL),
80 pLocaleData(NULL),
81 pOutliner(NULL),
82 pDefaults(NULL),
83 pResMgr(NULL),
84 nExchangeFormat(0)
85 {
86 //pSysLocale = new SvtSysLocale;
87 //pCharClass = pSysLocale->GetCharClassPtr();
88 //pLocaleData = pSysLocale->GetLocaleDataPtr();
89
90 svx::ExtrusionBar::RegisterInterface();
91 svx::FontworkBar::RegisterInterface();
92 }
93
~SdrGlobalData()94 SdrGlobalData::~SdrGlobalData()
95 {
96 delete pOutliner;
97 delete pDefaults;
98 delete pResMgr;
99 //! do NOT delete pCharClass and pLocaleData
100 delete pSysLocale;
101 }
GetSysLocale()102 const SvtSysLocale* SdrGlobalData::GetSysLocale()
103 {
104 if ( !pSysLocale )
105 pSysLocale = new SvtSysLocale;
106 return pSysLocale;
107 }
GetCharClass()108 const CharClass* SdrGlobalData::GetCharClass()
109 {
110 if ( !pCharClass )
111 pCharClass = GetSysLocale()->GetCharClassPtr();
112 return pCharClass;
113 }
GetLocaleData()114 const LocaleDataWrapper* SdrGlobalData::GetLocaleData()
115 {
116 if ( !pLocaleData )
117 pLocaleData = GetSysLocale()->GetLocaleDataPtr();
118 return pLocaleData;
119 }
120 ////////////////////////////////////////////////////////////////////////////////////////////////////
121
OLEObjCache()122 OLEObjCache::OLEObjCache()
123 : Container( 0 )
124 {
125 SvtCacheOptions aCacheOptions;
126
127 nSize = aCacheOptions.GetDrawingEngineOLE_Objects();
128 pTimer = new AutoTimer();
129 Link aLink = LINK(this, OLEObjCache, UnloadCheckHdl);
130
131 pTimer->SetTimeoutHdl(aLink);
132 pTimer->SetTimeout(20000);
133 pTimer->Start();
134
135 aLink.Call(pTimer);
136 }
137
~OLEObjCache()138 OLEObjCache::~OLEObjCache()
139 {
140 pTimer->Stop();
141 delete pTimer;
142 }
143
UnloadOnDemand()144 void OLEObjCache::UnloadOnDemand()
145 {
146 if ( nSize < Count() )
147 {
148 // more objects than configured cache size try to remove objects
149 // of course not the freshly inserted one at nIndex=0
150 sal_uIntPtr nCount2 = Count();
151 sal_uIntPtr nIndex = nCount2-1;
152 while( nIndex && nCount2 > nSize )
153 {
154 SdrOle2Obj* pUnloadObj = (SdrOle2Obj*) GetObject(nIndex--);
155 if ( pUnloadObj )
156 {
157 try
158 {
159 // it is important to get object without reinitialization to avoid reentrance
160 uno::Reference< embed::XEmbeddedObject > xUnloadObj = pUnloadObj->GetObjRef_NoInit();
161
162 sal_Bool bUnload = SdrOle2Obj::CanUnloadRunningObj( xUnloadObj, pUnloadObj->GetAspect() );
163
164 // check whether the object can be unloaded before looking for the parent objects
165 if ( xUnloadObj.is() && bUnload )
166 {
167 uno::Reference< frame::XModel > xUnloadModel( xUnloadObj->getComponent(), uno::UNO_QUERY );
168 if ( xUnloadModel.is() )
169 {
170 for ( sal_uIntPtr nCheckInd = 0; nCheckInd < Count(); nCheckInd++ )
171 {
172 SdrOle2Obj* pCacheObj = (SdrOle2Obj*) GetObject(nCheckInd);
173 if ( pCacheObj && pCacheObj != pUnloadObj )
174 {
175 uno::Reference< frame::XModel > xParentModel = pCacheObj->GetParentXModel();
176 if ( xUnloadModel == xParentModel )
177 bUnload = sal_False; // the object has running embedded objects
178 }
179 }
180 }
181 }
182
183 if ( bUnload && UnloadObj(pUnloadObj) )
184 // object was successfully unloaded
185 nCount2--;
186 }
187 catch( uno::Exception& )
188 {}
189 }
190 }
191 }
192 }
193
SetSize(sal_uIntPtr nNewSize)194 void OLEObjCache::SetSize(sal_uIntPtr nNewSize)
195 {
196 nSize = nNewSize;
197 }
198
InsertObj(SdrOle2Obj * pObj)199 void OLEObjCache::InsertObj(SdrOle2Obj* pObj)
200 {
201 if ( Count() )
202 {
203 SdrOle2Obj* pExistingObj = (SdrOle2Obj*)GetObject( 0 );
204 if ( pObj == pExistingObj )
205 // the object is already on the top, nothing has to be changed
206 return;
207 }
208
209 // get the old position of the object to know whether it is already in container
210 sal_uIntPtr nOldPos = GetPos( pObj );
211
212 // insert object into first position
213 Remove( nOldPos );
214 Insert(pObj, (sal_uIntPtr) 0L);
215
216 if ( nOldPos == CONTAINER_ENTRY_NOTFOUND )
217 {
218 // a new object was inserted, recalculate the cache
219 UnloadOnDemand();
220 }
221 }
222
RemoveObj(SdrOle2Obj * pObj)223 void OLEObjCache::RemoveObj(SdrOle2Obj* pObj)
224 {
225 Remove(pObj);
226 }
227
UnloadObj(SdrOle2Obj * pObj)228 sal_Bool OLEObjCache::UnloadObj(SdrOle2Obj* pObj)
229 {
230 sal_Bool bUnloaded = sal_False;
231 if (pObj)
232 {
233 //#i80528# The old mechanism is completely useless, only taking into account if
234 // in all views the GrafDraft feature is used. This will nearly never have been the
235 // case since no one ever used this option.
236 //
237 // A much better (and working) criteria would be the VOC contact count.
238 // The quesion is what will happen whe i make it work now suddenly? I
239 // will try it for 2.4.
240 const sdr::contact::ViewContact& rViewContact = pObj->GetViewContact();
241 const bool bVisible(rViewContact.HasViewObjectContacts(true));
242
243 if(!bVisible)
244 {
245 bUnloaded = pObj->Unload();
246 }
247 }
248
249 return bUnloaded;
250 }
251
252 IMPL_LINK(OLEObjCache, UnloadCheckHdl, AutoTimer*, /*pTim*/)
253 {
254 UnloadOnDemand();
255 return 0;
256 }
257
DoSort(sal_uIntPtr a,sal_uIntPtr b) const258 void ContainerSorter::DoSort(sal_uIntPtr a, sal_uIntPtr b) const
259 {
260 sal_uIntPtr nAnz=rCont.Count();
261 if (b>nAnz) b=nAnz;
262 if (b>0) b--;
263 if (a<b) ImpSubSort(a,b);
264 }
265
Is1stLessThan2nd(const void *,const void *) const266 void ContainerSorter::Is1stLessThan2nd(const void* /*pElem1*/, const void* /*pElem2*/) const
267 {
268 }
269
ImpSubSort(long nL,long nR) const270 void ContainerSorter::ImpSubSort(long nL, long nR) const
271 {
272 long i,j;
273 const void* pX;
274 void* pI;
275 void* pJ;
276 i=nL;
277 j=nR;
278 pX=rCont.GetObject((nL+nR)/2);
279 do {
280 pI=rCont.Seek(i);
281 while (pI!=pX && Compare(pI,pX)<0) { i++; pI=rCont.Next(); }
282 pJ=rCont.Seek(j);
283 while (pJ!=pX && Compare(pX,pJ)<0) { j--; pJ=rCont.Prev(); }
284 if (i<=j) {
285 rCont.Replace(pJ,i);
286 rCont.Replace(pI,j);
287 i++;
288 j--;
289 }
290 } while (i<=j);
291 if (nL<j) ImpSubSort(nL,j);
292 if (i<nR) ImpSubSort(i,nR);
293 }
294
295 ////////////////////////////////////////////////////////////////////////////////////////////////////
296
297 class ImpUShortContainerSorter: public ContainerSorter {
298 public:
ImpUShortContainerSorter(Container & rNewCont)299 ImpUShortContainerSorter(Container& rNewCont): ContainerSorter(rNewCont) {}
300 virtual int Compare(const void* pElem1, const void* pElem2) const;
301 };
302
Compare(const void * pElem1,const void * pElem2) const303 int ImpUShortContainerSorter::Compare(const void* pElem1, const void* pElem2) const
304 {
305 sal_uInt16 n1=sal_uInt16(sal_uIntPtr(pElem1));
306 sal_uInt16 n2=sal_uInt16(sal_uIntPtr(pElem2));
307 return n1<n2 ? -1 : n1>n2 ? 1 : 0;
308 }
309
Sort()310 void UShortCont::Sort()
311 {
312 ImpUShortContainerSorter aSorter(aArr);
313 aSorter.DoSort();
314 }
315
316 ////////////////////////////////////////////////////////////////////////////////////////////////////
317
318 class ImpClipMerk {
319 Region aClip;
320 FASTBOOL bClip;
321 public:
ImpClipMerk(const OutputDevice & rOut)322 ImpClipMerk(const OutputDevice& rOut): aClip(rOut.GetClipRegion()),bClip(rOut.IsClipRegion()) {}
Restore(OutputDevice & rOut)323 void Restore(OutputDevice& rOut)
324 {
325 // Kein Clipping in die Metafileaufzeichnung
326 GDIMetaFile* pMtf=rOut.GetConnectMetaFile();
327 if (pMtf!=NULL && (!pMtf->IsRecord() || pMtf->IsPause())) pMtf=NULL;
328 if (pMtf!=NULL) pMtf->Pause(sal_True);
329 if (bClip) rOut.SetClipRegion(aClip);
330 else rOut.SetClipRegion();
331 if (pMtf!=NULL) pMtf->Pause(sal_False);
332 }
333 };
334
335 class ImpColorMerk {
336 Color aLineColor;
337 Color aFillColor;
338 Color aBckgrdColor;
339 Font aFont;
340 public:
ImpColorMerk(const OutputDevice & rOut)341 ImpColorMerk(const OutputDevice& rOut):
342 aLineColor( rOut.GetLineColor() ),
343 aFillColor( rOut.GetFillColor() ),
344 aBckgrdColor( rOut.GetBackground().GetColor() ),
345 aFont (rOut.GetFont()) {}
346
ImpColorMerk(const OutputDevice & rOut,sal_uInt16 nMode)347 ImpColorMerk(const OutputDevice& rOut, sal_uInt16 nMode)
348 {
349 if ( (nMode & SDRHDC_SAVEPEN) == SDRHDC_SAVEPEN )
350 aLineColor = rOut.GetLineColor();
351
352 if ( (nMode & SDRHDC_SAVEBRUSH) == SDRHDC_SAVEBRUSH)
353 {
354 aFillColor = rOut.GetFillColor();
355 aBckgrdColor = rOut.GetBackground().GetColor();
356 }
357
358 if ( (nMode & SDRHDC_SAVEFONT) == SDRHDC_SAVEFONT)
359 aFont=rOut.GetFont();
360 }
361
Restore(OutputDevice & rOut,sal_uInt16 nMode=SDRHDC_SAVEPENANDBRUSHANDFONT)362 void Restore(OutputDevice& rOut, sal_uInt16 nMode=SDRHDC_SAVEPENANDBRUSHANDFONT)
363 {
364 if ( (nMode & SDRHDC_SAVEPEN) == SDRHDC_SAVEPEN)
365 rOut.SetLineColor( aLineColor );
366
367 if ( (nMode & SDRHDC_SAVEBRUSH) == SDRHDC_SAVEBRUSH)
368 {
369 rOut.SetFillColor( aFillColor );
370 rOut.SetBackground( Wallpaper( aBckgrdColor ) );
371 }
372 if ((nMode & SDRHDC_SAVEFONT) ==SDRHDC_SAVEFONT)
373 {
374 if (!rOut.GetFont().IsSameInstance(aFont))
375 {
376 rOut.SetFont(aFont);
377 }
378 }
379 }
380
GetLineColor() const381 const Color& GetLineColor() const { return aLineColor; }
382 };
383
ImpSdrHdcMerk(const OutputDevice & rOut,sal_uInt16 nNewMode,FASTBOOL bAutoMerk)384 ImpSdrHdcMerk::ImpSdrHdcMerk(const OutputDevice& rOut, sal_uInt16 nNewMode, FASTBOOL bAutoMerk):
385 pFarbMerk(NULL),
386 pClipMerk(NULL),
387 pLineColorMerk(NULL),
388 nMode(nNewMode)
389 {
390 if (bAutoMerk) Save(rOut);
391 }
392
~ImpSdrHdcMerk()393 ImpSdrHdcMerk::~ImpSdrHdcMerk()
394 {
395 if (pFarbMerk!=NULL) delete pFarbMerk;
396 if (pClipMerk!=NULL) delete pClipMerk;
397 if (pLineColorMerk !=NULL) delete pLineColorMerk;
398 }
399
Save(const OutputDevice & rOut)400 void ImpSdrHdcMerk::Save(const OutputDevice& rOut)
401 {
402 if (pFarbMerk!=NULL)
403 {
404 delete pFarbMerk;
405 pFarbMerk=NULL;
406 }
407 if (pClipMerk!=NULL)
408 {
409 delete pClipMerk;
410 pClipMerk=NULL;
411 }
412 if (pLineColorMerk !=NULL)
413 {
414 delete pLineColorMerk ;
415 pLineColorMerk =NULL;
416 }
417 if ((nMode & SDRHDC_SAVECLIPPING) ==SDRHDC_SAVECLIPPING)
418 pClipMerk=new ImpClipMerk(rOut);
419
420 sal_uInt16 nCol=nMode & SDRHDC_SAVEPENANDBRUSHANDFONT;
421
422 if (nCol==SDRHDC_SAVEPEN)
423 pLineColorMerk=new Color( rOut.GetLineColor() );
424 else if (nCol==SDRHDC_SAVEPENANDBRUSHANDFONT)
425 pFarbMerk=new ImpColorMerk(rOut);
426 else if (nCol!=0)
427 pFarbMerk=new ImpColorMerk(rOut,nCol);
428 }
429
Restore(OutputDevice & rOut,sal_uInt16 nMask) const430 void ImpSdrHdcMerk::Restore(OutputDevice& rOut, sal_uInt16 nMask) const
431 {
432 nMask&=nMode; // nur restaurieren, was auch gesichert wurde
433
434 if ((nMask & SDRHDC_SAVECLIPPING) ==SDRHDC_SAVECLIPPING && pClipMerk!=NULL)
435 pClipMerk->Restore(rOut);
436
437 sal_uInt16 nCol=nMask & SDRHDC_SAVEPENANDBRUSHANDFONT;
438
439 if (nCol==SDRHDC_SAVEPEN)
440 {
441 if (pLineColorMerk!=NULL)
442 rOut.SetLineColor(*pLineColorMerk);
443 else if (pFarbMerk!=NULL)
444 rOut.SetLineColor( pFarbMerk->GetLineColor() );
445 } else if (nCol!=0 && pFarbMerk!=NULL)
446 pFarbMerk->Restore(rOut,nCol);
447 }
448
449 ////////////////////////////////////////////////////////////////////////////////////////////////////
450
Clear()451 void SdrLinkList::Clear()
452 {
453 unsigned nAnz=GetLinkCount();
454 for (unsigned i=0; i<nAnz; i++) {
455 delete (Link*)aList.GetObject(i);
456 }
457 aList.Clear();
458 }
459
FindEntry(const Link & rLink) const460 unsigned SdrLinkList::FindEntry(const Link& rLink) const
461 {
462 unsigned nAnz=GetLinkCount();
463 for (unsigned i=0; i<nAnz; i++) {
464 if (GetLink(i)==rLink) return i;
465 }
466 return 0xFFFF;
467 }
468
InsertLink(const Link & rLink,unsigned nPos)469 void SdrLinkList::InsertLink(const Link& rLink, unsigned nPos)
470 {
471 unsigned nFnd=FindEntry(rLink);
472 if (nFnd==0xFFFF) {
473 if (rLink.IsSet()) {
474 aList.Insert(new Link(rLink),nPos);
475 } else {
476 DBG_ERROR("SdrLinkList::InsertLink(): Versuch, einen nicht gesetzten Link einzufuegen");
477 }
478 } else {
479 DBG_ERROR("SdrLinkList::InsertLink(): Link schon vorhanden");
480 }
481 }
482
RemoveLink(const Link & rLink)483 void SdrLinkList::RemoveLink(const Link& rLink)
484 {
485 unsigned nFnd=FindEntry(rLink);
486 if (nFnd!=0xFFFF) {
487 Link* pLink=(Link*)aList.Remove(nFnd);
488 delete pLink;
489 } else {
490 DBG_ERROR("SdrLinkList::RemoveLink(): Link nicht gefunden");
491 }
492 }
493
494 ////////////////////////////////////////////////////////////////////////////////////////////////////
495 // #98988# Re-implement GetDraftFillColor(...)
496
GetDraftFillColor(const SfxItemSet & rSet,Color & rCol)497 FASTBOOL GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
498 {
499 XFillStyle eFill=((XFillStyleItem&)rSet.Get(XATTR_FILLSTYLE)).GetValue();
500 FASTBOOL bRetval(sal_False);
501
502 switch(eFill)
503 {
504 case XFILL_SOLID:
505 {
506 rCol = ((XFillColorItem&)rSet.Get(XATTR_FILLCOLOR)).GetColorValue();
507 bRetval = sal_True;
508
509 break;
510 }
511 case XFILL_HATCH:
512 {
513 Color aCol1(((XFillHatchItem&)rSet.Get(XATTR_FILLHATCH)).GetHatchValue().GetColor());
514 Color aCol2(COL_WHITE);
515
516 // #97870# when hatch background is activated, use object fill color as hatch color
517 sal_Bool bFillHatchBackground = ((const XFillBackgroundItem&)(rSet.Get(XATTR_FILLBACKGROUND))).GetValue();
518 if(bFillHatchBackground)
519 {
520 aCol2 = ((const XFillColorItem&)(rSet.Get(XATTR_FILLCOLOR))).GetColorValue();
521 }
522
523 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
524 rCol = Color(aAverageColor);
525 bRetval = sal_True;
526
527 break;
528 }
529 case XFILL_GRADIENT: {
530 const XGradient& rGrad=((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue();
531 Color aCol1(rGrad.GetStartColor());
532 Color aCol2(rGrad.GetEndColor());
533 const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
534 rCol = Color(aAverageColor);
535 bRetval = sal_True;
536
537 break;
538 }
539 case XFILL_BITMAP:
540 {
541 Bitmap aBitmap(((XFillBitmapItem&)rSet.Get(XATTR_FILLBITMAP)).GetGraphicObject().GetGraphic().GetBitmapEx().GetBitmap());
542 const Size aSize(aBitmap.GetSizePixel());
543 const sal_uInt32 nWidth = aSize.Width();
544 const sal_uInt32 nHeight = aSize.Height();
545 BitmapReadAccess* pAccess = aBitmap.AcquireReadAccess();
546
547 if(pAccess && nWidth > 0 && nHeight > 0)
548 {
549 sal_uInt32 nRt(0L);
550 sal_uInt32 nGn(0L);
551 sal_uInt32 nBl(0L);
552 const sal_uInt32 nMaxSteps(8L);
553 const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1L);
554 const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1L);
555 sal_uInt32 nAnz(0L);
556
557 for(sal_uInt32 nY(0L); nY < nHeight; nY += nYStep)
558 {
559 for(sal_uInt32 nX(0L); nX < nWidth; nX += nXStep)
560 {
561 const BitmapColor& rCol2 = pAccess->GetColor(nY, nX);
562
563 nRt += rCol2.GetRed();
564 nGn += rCol2.GetGreen();
565 nBl += rCol2.GetBlue();
566 nAnz++;
567 }
568 }
569
570 nRt /= nAnz;
571 nGn /= nAnz;
572 nBl /= nAnz;
573
574 rCol = Color(sal_uInt8(nRt), sal_uInt8(nGn), sal_uInt8(nBl));
575
576 bRetval = sal_True;
577 }
578
579 if(pAccess)
580 {
581 aBitmap.ReleaseAccess(pAccess);
582 }
583
584 break;
585 }
586 default: break;
587 }
588
589 return bRetval;
590 }
591
592 ////////////////////////////////////////////////////////////////////////////////////////////////////
593
SdrEngineDefaults()594 SdrEngineDefaults::SdrEngineDefaults():
595 aFontName( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ).GetName() ),
596 eFontFamily(FAMILY_ROMAN),
597 aFontColor(COL_AUTO),
598 nFontHeight(847), // 847/100mm = ca. 24 Point
599 eMapUnit(MAP_100TH_MM),
600 aMapFraction(1,1)
601 {
602 }
603
GetDefaults()604 SdrEngineDefaults& SdrEngineDefaults::GetDefaults()
605 {
606 SdrGlobalData& rGlobalData=GetSdrGlobalData();
607 if (rGlobalData.pDefaults==NULL) {
608 rGlobalData.pDefaults=new SdrEngineDefaults;
609 }
610 return *rGlobalData.pDefaults;
611 }
612
613 ////////////////////////////////////////////////////////////////////////////////////////////////////
614
LanguageHasChanged()615 void SdrEngineDefaults::LanguageHasChanged()
616 {
617 SdrGlobalData& rGlobalData=GetSdrGlobalData();
618 if (rGlobalData.pResMgr!=NULL) {
619 delete rGlobalData.pResMgr;
620 rGlobalData.pResMgr=NULL;
621 }
622 }
623
624 ////////////////////////////////////////////////////////////////////////////////////////////////////
625
SdrMakeOutliner(sal_uInt16 nOutlinerMode,SdrModel * pModel)626 SdrOutliner* SdrMakeOutliner( sal_uInt16 nOutlinerMode, SdrModel* pModel )
627 {
628 //SdrEngineDefaults& rDefaults = SdrEngineDefaults::GetDefaults();
629
630 SfxItemPool* pPool = &pModel->GetItemPool();
631 SdrOutliner* pOutl = new SdrOutliner( pPool, nOutlinerMode );
632 pOutl->SetEditTextObjectPool( pPool );
633 pOutl->SetStyleSheetPool( (SfxStyleSheetPool*) pModel->GetStyleSheetPool() );
634 pOutl->SetDefTab( pModel->GetDefaultTabulator() );
635 pOutl->SetForbiddenCharsTable( pModel->GetForbiddenCharsTable() );
636 pOutl->SetAsianCompressionMode( pModel->GetCharCompressType() );
637 pOutl->SetKernAsianPunctuation( pModel->IsKernAsianPunctuation() );
638 pOutl->SetAddExtLeading( pModel->IsAddExtLeading() );
639
640 return pOutl;
641 }
642
643 ////////////////////////////////////////////////////////////////////////////////////////////////////
644
645
ImpGetUserMakeObjHdl()646 SdrLinkList& ImpGetUserMakeObjHdl()
647 {
648 SdrGlobalData& rGlobalData=GetSdrGlobalData();
649 return rGlobalData.aUserMakeObjHdl;
650 }
651
ImpGetUserMakeObjUserDataHdl()652 SdrLinkList& ImpGetUserMakeObjUserDataHdl()
653 {
654 SdrGlobalData& rGlobalData=GetSdrGlobalData();
655 return rGlobalData.aUserMakeObjUserDataHdl;
656 }
657
658 ////////////////////////////////////////////////////////////////////////////////////////////////////
659
ImpGetResMgr()660 ResMgr* ImpGetResMgr()
661 {
662 SdrGlobalData& rGlobalData = GetSdrGlobalData();
663
664 if(!rGlobalData.pResMgr)
665 {
666 ByteString aName("svx");
667 rGlobalData.pResMgr =
668 ResMgr::CreateResMgr( aName.GetBuffer(), Application::GetSettings().GetUILocale() );
669 }
670
671 return rGlobalData.pResMgr;
672 }
673
674 ////////////////////////////////////////////////////////////////////////////////////////////////////
675
ImpGetResStr(sal_uInt16 nResID)676 String ImpGetResStr(sal_uInt16 nResID)
677 {
678 return String(ResId(nResID, *ImpGetResMgr()));
679 }
680
681 ////////////////////////////////////////////////////////////////////////////////////////////////////
682
683 namespace sdr
684 {
GetResourceString(sal_uInt16 nResID)685 String GetResourceString(sal_uInt16 nResID)
686 {
687 return ImpGetResStr( nResID );
688 }
689 }
690
691 ////////////////////////////////////////////////////////////////////////////////////////////////////
692
SearchOutlinerItems(const SfxItemSet & rSet,sal_Bool bInklDefaults,sal_Bool * pbOnlyEE)693 sal_Bool SearchOutlinerItems(const SfxItemSet& rSet, sal_Bool bInklDefaults, sal_Bool* pbOnlyEE)
694 {
695 sal_Bool bHas=sal_False;
696 sal_Bool bOnly=sal_True;
697 sal_Bool bLookOnly=pbOnlyEE!=NULL;
698 SfxWhichIter aIter(rSet);
699 sal_uInt16 nWhich=aIter.FirstWhich();
700 while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) {
701 // bei bInklDefaults ist der gesamte Which-Range
702 // ausschlaggebend, ansonsten nur die gesetzten Items
703 // Disabled und DontCare wird als Loch im Which-Range betrachtet
704 SfxItemState eState=rSet.GetItemState(nWhich);
705 if ((eState==SFX_ITEM_DEFAULT && bInklDefaults) || eState==SFX_ITEM_SET) {
706 if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=sal_False;
707 else bHas=sal_True;
708 }
709 nWhich=aIter.NextWhich();
710 }
711 if (!bHas) bOnly=sal_False;
712 if (pbOnlyEE!=NULL) *pbOnlyEE=bOnly;
713 return bHas;
714 }
715
RemoveWhichRange(const sal_uInt16 * pOldWhichTable,sal_uInt16 nRangeBeg,sal_uInt16 nRangeEnd)716 sal_uInt16* RemoveWhichRange(const sal_uInt16* pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd)
717 {
718 // insgesamt sind 6 Faelle moeglich (je Range):
719 // [Beg..End] zu entfernender Range
720 // [b..e] [b..e] [b..e] Fall 1,3,2: egal, ganz weg, egal + Ranges
721 // [b........e] [b........e] Fall 4,5 : Bereich verkleinern | in
722 // [b......................e] Fall 6 : Splitting + pOldWhichTable
723 sal_uInt16 nAnz=0;
724 while (pOldWhichTable[nAnz]!=0) nAnz++;
725 nAnz++; // nAnz muesste nun in jedem Fall eine ungerade Zahl sein (0 am Ende des Arrays)
726 DBG_ASSERT((nAnz&1)==1,"Joe: RemoveWhichRange: WhichTable hat keine ungerade Anzahl von Eintraegen");
727 sal_uInt16 nAlloc=nAnz;
728 // benoetigte Groesse des neuen Arrays ermitteln
729 sal_uInt16 nNum=nAnz-1;
730 while (nNum!=0) {
731 nNum-=2;
732 sal_uInt16 nBeg=pOldWhichTable[nNum];
733 sal_uInt16 nEnd=pOldWhichTable[nNum+1];
734 if (nEnd<nRangeBeg) /*nCase=1*/ ;
735 else if (nBeg>nRangeEnd) /* nCase=2 */ ;
736 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2;
737 else if (nEnd<=nRangeEnd) /* nCase=4 */;
738 else if (nBeg>=nRangeBeg) /* nCase=5*/ ;
739 else /* nCase=6 */ nAlloc+=2;
740 }
741
742 sal_uInt16* pNewWhichTable=new sal_uInt16[nAlloc];
743 memcpy(pNewWhichTable,pOldWhichTable,nAlloc*sizeof(sal_uInt16));
744 pNewWhichTable[nAlloc-1]=0; // im Falle 3 fehlt die 0 am Ende
745 // nun die unerwuenschten Ranges entfernen
746 nNum=nAlloc-1;
747 while (nNum!=0) {
748 nNum-=2;
749 sal_uInt16 nBeg=pNewWhichTable[nNum];
750 sal_uInt16 nEnd=pNewWhichTable[nNum+1];
751 unsigned nCase=0;
752 if (nEnd<nRangeBeg) nCase=1;
753 else if (nBeg>nRangeEnd) nCase=2;
754 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3;
755 else if (nEnd<=nRangeEnd) nCase=4;
756 else if (nBeg>=nRangeBeg) nCase=5;
757 else nCase=6;
758 switch (nCase) {
759 case 3: {
760 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16);
761 memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes);
762 nAnz-=2; // Merken: Array hat sich verkleinert
763 } break;
764 case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break;
765 case 5: pNewWhichTable[nNum]=nRangeEnd+1; break;
766 case 6: {
767 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16);
768 memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes);
769 nAnz+=2; // Merken: Array hat sich vergroessert
770 pNewWhichTable[nNum+2]=nRangeEnd+1;
771 pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1];
772 pNewWhichTable[nNum+1]=nRangeBeg-1;
773 } break;
774 } // switch
775 }
776 return pNewWhichTable;
777 }
778
779 ////////////////////////////////////////////////////////////////////////////////////////////////////
780
SvdProgressInfo(Link * _pLink)781 SvdProgressInfo::SvdProgressInfo( Link *_pLink )
782 {
783 DBG_ASSERT(_pLink!=NULL,"SvdProgressInfo(): Kein Link angegeben!!");
784
785 pLink = _pLink;
786 nSumActionCount = 0;
787 nSumCurAction = 0;
788
789 nObjCount = 0;
790 nCurObj = 0;
791
792 nActionCount = 0;
793 nCurAction = 0;
794
795 nInsertCount = 0;
796 nCurInsert = 0;
797 }
798
Init(sal_uIntPtr _nSumActionCount,sal_uIntPtr _nObjCount)799 void SvdProgressInfo::Init( sal_uIntPtr _nSumActionCount, sal_uIntPtr _nObjCount )
800 {
801 nSumActionCount = _nSumActionCount;
802 nObjCount = _nObjCount;
803 }
804
ReportActions(sal_uIntPtr nAnzActions)805 sal_Bool SvdProgressInfo::ReportActions( sal_uIntPtr nAnzActions )
806 {
807 nSumCurAction += nAnzActions;
808 nCurAction += nAnzActions;
809 if(nCurAction > nActionCount)
810 nCurAction = nActionCount;
811
812 return pLink->Call(NULL) == 1L;
813 }
814
ReportInserts(sal_uIntPtr nAnzInserts)815 sal_Bool SvdProgressInfo::ReportInserts( sal_uIntPtr nAnzInserts )
816 {
817 nSumCurAction += nAnzInserts;
818 nCurInsert += nAnzInserts;
819
820 return pLink->Call(NULL) == 1L;
821 }
822
ReportRescales(sal_uIntPtr nAnzRescales)823 sal_Bool SvdProgressInfo::ReportRescales( sal_uIntPtr nAnzRescales )
824 {
825 nSumCurAction += nAnzRescales;
826 return pLink->Call(NULL) == 1L;
827 }
828
SetActionCount(sal_uIntPtr _nActionCount)829 void SvdProgressInfo::SetActionCount( sal_uIntPtr _nActionCount )
830 {
831 nActionCount = _nActionCount;
832 }
833
SetInsertCount(sal_uIntPtr _nInsertCount)834 void SvdProgressInfo::SetInsertCount( sal_uIntPtr _nInsertCount )
835 {
836 nInsertCount = _nInsertCount;
837 }
838
SetNextObject()839 sal_Bool SvdProgressInfo::SetNextObject()
840 {
841 nActionCount = 0;
842 nCurAction = 0;
843
844 nInsertCount = 0;
845 nCurInsert = 0;
846
847 nCurObj++;
848 return ReportActions(0);
849 }
850
ReportError()851 void SvdProgressInfo::ReportError()
852 {
853 pLink->Call((void *)1L);
854 }
855
856 ////////////////////////////////////////////////////////////////////////////////////////////////////
857 // #i101872# isolate GetTextEditBackgroundColor to tooling; it woll anyways only be used as long
858 // as text edit is not running on overlay
859
860 namespace
861 {
impGetSdrObjListFillColor(const SdrObjList & rList,const Point & rPnt,const SdrPageView & rTextEditPV,const SetOfByte & rVisLayers,Color & rCol)862 bool impGetSdrObjListFillColor(
863 const SdrObjList& rList,
864 const Point& rPnt,
865 const SdrPageView& rTextEditPV,
866 const SetOfByte& rVisLayers,
867 Color& rCol)
868 {
869 if(!rList.GetModel())
870 return false;
871
872 bool bRet(false);
873 bool bMaster(rList.GetPage() ? rList.GetPage()->IsMasterPage() : false);
874
875 for(sal_uIntPtr no(rList.GetObjCount()); !bRet && no > 0; )
876 {
877 no--;
878 SdrObject* pObj = rList.GetObj(no);
879 SdrObjList* pOL = pObj->GetSubList();
880
881 if(pOL)
882 {
883 // group object
884 bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol);
885 }
886 else
887 {
888 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj);
889
890 // #108867# Exclude zero master page object (i.e. background shape) from color query
891 if(pText
892 && pObj->IsClosedObj()
893 && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no))
894 && pObj->GetCurrentBoundRect().IsInside(rPnt)
895 && !pText->IsHideContour()
896 && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false))
897 {
898 bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol);
899 }
900 }
901 }
902
903 return bRet;
904 }
905
impGetSdrPageFillColor(const SdrPage & rPage,const Point & rPnt,const SdrPageView & rTextEditPV,const SetOfByte & rVisLayers,Color & rCol,bool bSkipBackgroundShape)906 bool impGetSdrPageFillColor(
907 const SdrPage& rPage,
908 const Point& rPnt,
909 const SdrPageView& rTextEditPV,
910 const SetOfByte& rVisLayers,
911 Color& rCol,
912 bool bSkipBackgroundShape)
913 {
914 if(!rPage.GetModel())
915 return false;
916
917 bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol));
918
919 if(!bRet && !rPage.IsMasterPage())
920 {
921 if(rPage.TRG_HasMasterPage())
922 {
923 SetOfByte aSet(rVisLayers);
924 aSet &= rPage.TRG_GetMasterPageVisibleLayers();
925 SdrPage& rMasterPage = rPage.TRG_GetMasterPage();
926
927 // #108867# Don't fall back to background shape on
928 // master pages. This is later handled by
929 // GetBackgroundColor, and is necessary to cater for
930 // the silly ordering: 1. shapes, 2. master page
931 // shapes, 3. page background, 4. master page
932 // background.
933 bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true);
934 }
935 }
936
937 // #108867# Only now determine background color from background shapes
938 if(!bRet && !bSkipBackgroundShape)
939 {
940 rCol = rPage.GetPageBackgroundColor();
941 return true;
942 }
943
944 return bRet;
945 }
946
impCalcBackgroundColor(const Rectangle & rArea,const SdrPageView & rTextEditPV,const SdrPage & rPage)947 Color impCalcBackgroundColor(
948 const Rectangle& rArea,
949 const SdrPageView& rTextEditPV,
950 const SdrPage& rPage)
951 {
952 svtools::ColorConfig aColorConfig;
953 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
954 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
955
956 if(!rStyleSettings.GetHighContrastMode())
957 {
958 // search in page
959 const sal_uInt16 SPOTCOUNT(5);
960 Point aSpotPos[SPOTCOUNT];
961 Color aSpotColor[SPOTCOUNT];
962 sal_uIntPtr nHeight( rArea.GetSize().Height() );
963 sal_uIntPtr nWidth( rArea.GetSize().Width() );
964 sal_uIntPtr nWidth14 = nWidth / 4;
965 sal_uIntPtr nHeight14 = nHeight / 4;
966 sal_uIntPtr nWidth34 = ( 3 * nWidth ) / 4;
967 sal_uIntPtr nHeight34 = ( 3 * nHeight ) / 4;
968
969 sal_uInt16 i;
970 for ( i = 0; i < SPOTCOUNT; i++ )
971 {
972 // five spots are used
973 switch ( i )
974 {
975 case 0 :
976 {
977 // Center-Spot
978 aSpotPos[i] = rArea.Center();
979 }
980 break;
981
982 case 1 :
983 {
984 // TopLeft-Spot
985 aSpotPos[i] = rArea.TopLeft();
986 aSpotPos[i].X() += nWidth14;
987 aSpotPos[i].Y() += nHeight14;
988 }
989 break;
990
991 case 2 :
992 {
993 // TopRight-Spot
994 aSpotPos[i] = rArea.TopLeft();
995 aSpotPos[i].X() += nWidth34;
996 aSpotPos[i].Y() += nHeight14;
997 }
998 break;
999
1000 case 3 :
1001 {
1002 // BottomLeft-Spot
1003 aSpotPos[i] = rArea.TopLeft();
1004 aSpotPos[i].X() += nWidth14;
1005 aSpotPos[i].Y() += nHeight34;
1006 }
1007 break;
1008
1009 case 4 :
1010 {
1011 // BottomRight-Spot
1012 aSpotPos[i] = rArea.TopLeft();
1013 aSpotPos[i].X() += nWidth34;
1014 aSpotPos[i].Y() += nHeight34;
1015 }
1016 break;
1017
1018 }
1019
1020 aSpotColor[i] = Color( COL_WHITE );
1021 impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false);
1022 }
1023
1024 sal_uInt16 aMatch[SPOTCOUNT];
1025
1026 for ( i = 0; i < SPOTCOUNT; i++ )
1027 {
1028 // were same spot colors found?
1029 aMatch[i] = 0;
1030
1031 for ( sal_uInt16 j = 0; j < SPOTCOUNT; j++ )
1032 {
1033 if( j != i )
1034 {
1035 if( aSpotColor[i] == aSpotColor[j] )
1036 {
1037 aMatch[i]++;
1038 }
1039 }
1040 }
1041 }
1042
1043 // highest weight to center spot
1044 aBackground = aSpotColor[0];
1045
1046 for ( sal_uInt16 nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- )
1047 {
1048 // which spot color was found most?
1049 for ( i = 0; i < SPOTCOUNT; i++ )
1050 {
1051 if( aMatch[i] == nMatchCount )
1052 {
1053 aBackground = aSpotColor[i];
1054 nMatchCount = 1; // break outer for-loop
1055 break;
1056 }
1057 }
1058 }
1059 }
1060
1061 return aBackground;
1062 }
1063 } // end of anonymous namespace
1064
GetTextEditBackgroundColor(const SdrObjEditView & rView)1065 Color GetTextEditBackgroundColor(const SdrObjEditView& rView)
1066 {
1067 svtools::ColorConfig aColorConfig;
1068 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor);
1069 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
1070
1071 if(!rStyleSettings.GetHighContrastMode())
1072 {
1073 bool bFound(false);
1074 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(rView.GetTextEditObject());
1075
1076 if(pText && pText->IsClosedObj())
1077 {
1078 ::sdr::table::SdrTableObj* pTable = dynamic_cast< ::sdr::table::SdrTableObj * >( pText );
1079
1080 if( pTable )
1081 bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground );
1082
1083 if( !bFound )
1084 bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground);
1085 }
1086
1087 if(!bFound && pText)
1088 {
1089 SdrPageView* pTextEditPV = rView.GetTextEditPageView();
1090
1091 if(pTextEditPV)
1092 {
1093 Point aPvOfs(pText->GetTextEditOffset());
1094 const SdrPage* pPg = pTextEditPV->GetPage();
1095
1096 if(pPg)
1097 {
1098 Rectangle aSnapRect( pText->GetSnapRect() );
1099 aSnapRect.Move(aPvOfs.X(), aPvOfs.Y());
1100
1101 return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg);
1102 }
1103 }
1104 }
1105 }
1106
1107 return aBackground;
1108 }
1109
1110 ////////////////////////////////////////////////////////////////////////////////////////////////////
1111 // eof
1112