xref: /AOO41X/main/svx/source/svdraw/svdetc.cxx (revision 87bc88d3ed834c36654f277ed18005c290f77bdd)
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