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