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 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 94 SdrGlobalData::~SdrGlobalData() 95 { 96 delete pOutliner; 97 delete pDefaults; 98 delete pResMgr; 99 //! do NOT delete pCharClass and pLocaleData 100 delete pSysLocale; 101 } 102 const SvtSysLocale* SdrGlobalData::GetSysLocale() 103 { 104 if ( !pSysLocale ) 105 pSysLocale = new SvtSysLocale; 106 return pSysLocale; 107 } 108 const CharClass* SdrGlobalData::GetCharClass() 109 { 110 if ( !pCharClass ) 111 pCharClass = GetSysLocale()->GetCharClassPtr(); 112 return pCharClass; 113 } 114 const LocaleDataWrapper* SdrGlobalData::GetLocaleData() 115 { 116 if ( !pLocaleData ) 117 pLocaleData = GetSysLocale()->GetLocaleDataPtr(); 118 return pLocaleData; 119 } 120 //////////////////////////////////////////////////////////////////////////////////////////////////// 121 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 138 OLEObjCache::~OLEObjCache() 139 { 140 pTimer->Stop(); 141 delete pTimer; 142 } 143 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 194 void OLEObjCache::SetSize(sal_uIntPtr nNewSize) 195 { 196 nSize = nNewSize; 197 } 198 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 223 void OLEObjCache::RemoveObj(SdrOle2Obj* pObj) 224 { 225 Remove(pObj); 226 } 227 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 258 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 266 void ContainerSorter::Is1stLessThan2nd(const void* /*pElem1*/, const void* /*pElem2*/) const 267 { 268 } 269 270 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: 299 ImpUShortContainerSorter(Container& rNewCont): ContainerSorter(rNewCont) {} 300 virtual int Compare(const void* pElem1, const void* pElem2) const; 301 }; 302 303 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 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: 322 ImpClipMerk(const OutputDevice& rOut): aClip(rOut.GetClipRegion()),bClip(rOut.IsClipRegion()) {} 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: 341 ImpColorMerk(const OutputDevice& rOut): 342 aLineColor( rOut.GetLineColor() ), 343 aFillColor( rOut.GetFillColor() ), 344 aBckgrdColor( rOut.GetBackground().GetColor() ), 345 aFont (rOut.GetFont()) {} 346 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 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 381 const Color& GetLineColor() const { return aLineColor; } 382 }; 383 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 393 ImpSdrHdcMerk::~ImpSdrHdcMerk() 394 { 395 if (pFarbMerk!=NULL) delete pFarbMerk; 396 if (pClipMerk!=NULL) delete pClipMerk; 397 if (pLineColorMerk !=NULL) delete pLineColorMerk; 398 } 399 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 430 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 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 460 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 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 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 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 const Bitmap& rBitmap = ((XFillBitmapItem&)rSet.Get(XATTR_FILLBITMAP)).GetBitmapValue().GetBitmap(); 542 const Size aSize(rBitmap.GetSizePixel()); 543 const sal_uInt32 nWidth = aSize.Width(); 544 const sal_uInt32 nHeight = aSize.Height(); 545 Bitmap aBitmap(rBitmap); 546 BitmapReadAccess* pAccess = aBitmap.AcquireReadAccess(); 547 548 if(pAccess && nWidth > 0 && nHeight > 0) 549 { 550 sal_uInt32 nRt(0L); 551 sal_uInt32 nGn(0L); 552 sal_uInt32 nBl(0L); 553 const sal_uInt32 nMaxSteps(8L); 554 const sal_uInt32 nXStep((nWidth > nMaxSteps) ? nWidth / nMaxSteps : 1L); 555 const sal_uInt32 nYStep((nHeight > nMaxSteps) ? nHeight / nMaxSteps : 1L); 556 sal_uInt32 nAnz(0L); 557 558 for(sal_uInt32 nY(0L); nY < nHeight; nY += nYStep) 559 { 560 for(sal_uInt32 nX(0L); nX < nWidth; nX += nXStep) 561 { 562 const BitmapColor& rCol2 = (pAccess->HasPalette()) 563 ? pAccess->GetPaletteColor((sal_uInt8)pAccess->GetPixel(nY, nX)) 564 : pAccess->GetPixel(nY, nX); 565 566 nRt += rCol2.GetRed(); 567 nGn += rCol2.GetGreen(); 568 nBl += rCol2.GetBlue(); 569 nAnz++; 570 } 571 } 572 573 nRt /= nAnz; 574 nGn /= nAnz; 575 nBl /= nAnz; 576 577 rCol = Color(sal_uInt8(nRt), sal_uInt8(nGn), sal_uInt8(nBl)); 578 579 bRetval = sal_True; 580 } 581 582 if(pAccess) 583 { 584 aBitmap.ReleaseAccess(pAccess); 585 } 586 587 break; 588 } 589 default: break; 590 } 591 592 return bRetval; 593 } 594 595 //////////////////////////////////////////////////////////////////////////////////////////////////// 596 597 SdrEngineDefaults::SdrEngineDefaults(): 598 aFontName( OutputDevice::GetDefaultFont( DEFAULTFONT_SERIF, LANGUAGE_SYSTEM, DEFAULTFONT_FLAGS_ONLYONE ).GetName() ), 599 eFontFamily(FAMILY_ROMAN), 600 aFontColor(COL_AUTO), 601 nFontHeight(847), // 847/100mm = ca. 24 Point 602 eMapUnit(MAP_100TH_MM), 603 aMapFraction(1,1) 604 { 605 } 606 607 SdrEngineDefaults& SdrEngineDefaults::GetDefaults() 608 { 609 SdrGlobalData& rGlobalData=GetSdrGlobalData(); 610 if (rGlobalData.pDefaults==NULL) { 611 rGlobalData.pDefaults=new SdrEngineDefaults; 612 } 613 return *rGlobalData.pDefaults; 614 } 615 616 //////////////////////////////////////////////////////////////////////////////////////////////////// 617 618 void SdrEngineDefaults::LanguageHasChanged() 619 { 620 SdrGlobalData& rGlobalData=GetSdrGlobalData(); 621 if (rGlobalData.pResMgr!=NULL) { 622 delete rGlobalData.pResMgr; 623 rGlobalData.pResMgr=NULL; 624 } 625 } 626 627 //////////////////////////////////////////////////////////////////////////////////////////////////// 628 629 SdrOutliner* SdrMakeOutliner( sal_uInt16 nOutlinerMode, SdrModel* pModel ) 630 { 631 //SdrEngineDefaults& rDefaults = SdrEngineDefaults::GetDefaults(); 632 633 SfxItemPool* pPool = &pModel->GetItemPool(); 634 SdrOutliner* pOutl = new SdrOutliner( pPool, nOutlinerMode ); 635 pOutl->SetEditTextObjectPool( pPool ); 636 pOutl->SetStyleSheetPool( (SfxStyleSheetPool*) pModel->GetStyleSheetPool() ); 637 pOutl->SetDefTab( pModel->GetDefaultTabulator() ); 638 pOutl->SetForbiddenCharsTable( pModel->GetForbiddenCharsTable() ); 639 pOutl->SetAsianCompressionMode( pModel->GetCharCompressType() ); 640 pOutl->SetKernAsianPunctuation( pModel->IsKernAsianPunctuation() ); 641 pOutl->SetAddExtLeading( pModel->IsAddExtLeading() ); 642 643 return pOutl; 644 } 645 646 //////////////////////////////////////////////////////////////////////////////////////////////////// 647 648 649 SdrLinkList& ImpGetUserMakeObjHdl() 650 { 651 SdrGlobalData& rGlobalData=GetSdrGlobalData(); 652 return rGlobalData.aUserMakeObjHdl; 653 } 654 655 SdrLinkList& ImpGetUserMakeObjUserDataHdl() 656 { 657 SdrGlobalData& rGlobalData=GetSdrGlobalData(); 658 return rGlobalData.aUserMakeObjUserDataHdl; 659 } 660 661 //////////////////////////////////////////////////////////////////////////////////////////////////// 662 663 ResMgr* ImpGetResMgr() 664 { 665 SdrGlobalData& rGlobalData = GetSdrGlobalData(); 666 667 if(!rGlobalData.pResMgr) 668 { 669 ByteString aName("svx"); 670 rGlobalData.pResMgr = 671 ResMgr::CreateResMgr( aName.GetBuffer(), Application::GetSettings().GetUILocale() ); 672 } 673 674 return rGlobalData.pResMgr; 675 } 676 677 //////////////////////////////////////////////////////////////////////////////////////////////////// 678 679 String ImpGetResStr(sal_uInt16 nResID) 680 { 681 return String(ResId(nResID, *ImpGetResMgr())); 682 } 683 684 //////////////////////////////////////////////////////////////////////////////////////////////////// 685 686 namespace sdr 687 { 688 String GetResourceString(sal_uInt16 nResID) 689 { 690 return ImpGetResStr( nResID ); 691 } 692 } 693 694 //////////////////////////////////////////////////////////////////////////////////////////////////// 695 696 sal_Bool SearchOutlinerItems(const SfxItemSet& rSet, sal_Bool bInklDefaults, sal_Bool* pbOnlyEE) 697 { 698 sal_Bool bHas=sal_False; 699 sal_Bool bOnly=sal_True; 700 sal_Bool bLookOnly=pbOnlyEE!=NULL; 701 SfxWhichIter aIter(rSet); 702 sal_uInt16 nWhich=aIter.FirstWhich(); 703 while (((bLookOnly && bOnly) || !bHas) && nWhich!=0) { 704 // bei bInklDefaults ist der gesamte Which-Range 705 // ausschlaggebend, ansonsten nur die gesetzten Items 706 // Disabled und DontCare wird als Loch im Which-Range betrachtet 707 SfxItemState eState=rSet.GetItemState(nWhich); 708 if ((eState==SFX_ITEM_DEFAULT && bInklDefaults) || eState==SFX_ITEM_SET) { 709 if (nWhich<EE_ITEMS_START || nWhich>EE_ITEMS_END) bOnly=sal_False; 710 else bHas=sal_True; 711 } 712 nWhich=aIter.NextWhich(); 713 } 714 if (!bHas) bOnly=sal_False; 715 if (pbOnlyEE!=NULL) *pbOnlyEE=bOnly; 716 return bHas; 717 } 718 719 sal_uInt16* RemoveWhichRange(const sal_uInt16* pOldWhichTable, sal_uInt16 nRangeBeg, sal_uInt16 nRangeEnd) 720 { 721 // insgesamt sind 6 Faelle moeglich (je Range): 722 // [Beg..End] zu entfernender Range 723 // [b..e] [b..e] [b..e] Fall 1,3,2: egal, ganz weg, egal + Ranges 724 // [b........e] [b........e] Fall 4,5 : Bereich verkleinern | in 725 // [b......................e] Fall 6 : Splitting + pOldWhichTable 726 sal_uInt16 nAnz=0; 727 while (pOldWhichTable[nAnz]!=0) nAnz++; 728 nAnz++; // nAnz muesste nun in jedem Fall eine ungerade Zahl sein (0 am Ende des Arrays) 729 DBG_ASSERT((nAnz&1)==1,"Joe: RemoveWhichRange: WhichTable hat keine ungerade Anzahl von Eintraegen"); 730 sal_uInt16 nAlloc=nAnz; 731 // benoetigte Groesse des neuen Arrays ermitteln 732 sal_uInt16 nNum=nAnz-1; 733 while (nNum!=0) { 734 nNum-=2; 735 sal_uInt16 nBeg=pOldWhichTable[nNum]; 736 sal_uInt16 nEnd=pOldWhichTable[nNum+1]; 737 if (nEnd<nRangeBeg) /*nCase=1*/ ; 738 else if (nBeg>nRangeEnd) /* nCase=2 */ ; 739 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) /* nCase=3 */ nAlloc-=2; 740 else if (nEnd<=nRangeEnd) /* nCase=4 */; 741 else if (nBeg>=nRangeBeg) /* nCase=5*/ ; 742 else /* nCase=6 */ nAlloc+=2; 743 } 744 745 sal_uInt16* pNewWhichTable=new sal_uInt16[nAlloc]; 746 memcpy(pNewWhichTable,pOldWhichTable,nAlloc*sizeof(sal_uInt16)); 747 pNewWhichTable[nAlloc-1]=0; // im Falle 3 fehlt die 0 am Ende 748 // nun die unerwuenschten Ranges entfernen 749 nNum=nAlloc-1; 750 while (nNum!=0) { 751 nNum-=2; 752 sal_uInt16 nBeg=pNewWhichTable[nNum]; 753 sal_uInt16 nEnd=pNewWhichTable[nNum+1]; 754 unsigned nCase=0; 755 if (nEnd<nRangeBeg) nCase=1; 756 else if (nBeg>nRangeEnd) nCase=2; 757 else if (nBeg>=nRangeBeg && nEnd<=nRangeEnd) nCase=3; 758 else if (nEnd<=nRangeEnd) nCase=4; 759 else if (nBeg>=nRangeBeg) nCase=5; 760 else nCase=6; 761 switch (nCase) { 762 case 3: { 763 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16); 764 memcpy(&pNewWhichTable[nNum],&pNewWhichTable[nNum+2],nTailBytes); 765 nAnz-=2; // Merken: Array hat sich verkleinert 766 } break; 767 case 4: pNewWhichTable[nNum+1]=nRangeBeg-1; break; 768 case 5: pNewWhichTable[nNum]=nRangeEnd+1; break; 769 case 6: { 770 unsigned nTailBytes=(nAnz-(nNum+2))*sizeof(sal_uInt16); 771 memcpy(&pNewWhichTable[nNum+4],&pNewWhichTable[nNum+2],nTailBytes); 772 nAnz+=2; // Merken: Array hat sich vergroessert 773 pNewWhichTable[nNum+2]=nRangeEnd+1; 774 pNewWhichTable[nNum+3]=pNewWhichTable[nNum+1]; 775 pNewWhichTable[nNum+1]=nRangeBeg-1; 776 } break; 777 } // switch 778 } 779 return pNewWhichTable; 780 } 781 782 //////////////////////////////////////////////////////////////////////////////////////////////////// 783 784 SvdProgressInfo::SvdProgressInfo( Link *_pLink ) 785 { 786 DBG_ASSERT(_pLink!=NULL,"SvdProgressInfo(): Kein Link angegeben!!"); 787 788 pLink = _pLink; 789 nSumActionCount = 0; 790 nSumCurAction = 0; 791 792 nObjCount = 0; 793 nCurObj = 0; 794 795 nActionCount = 0; 796 nCurAction = 0; 797 798 nInsertCount = 0; 799 nCurInsert = 0; 800 } 801 802 void SvdProgressInfo::Init( sal_uIntPtr _nSumActionCount, sal_uIntPtr _nObjCount ) 803 { 804 nSumActionCount = _nSumActionCount; 805 nObjCount = _nObjCount; 806 } 807 808 sal_Bool SvdProgressInfo::ReportActions( sal_uIntPtr nAnzActions ) 809 { 810 nSumCurAction += nAnzActions; 811 nCurAction += nAnzActions; 812 if(nCurAction > nActionCount) 813 nCurAction = nActionCount; 814 815 return pLink->Call(NULL) == 1L; 816 } 817 818 sal_Bool SvdProgressInfo::ReportInserts( sal_uIntPtr nAnzInserts ) 819 { 820 nSumCurAction += nAnzInserts; 821 nCurInsert += nAnzInserts; 822 823 return pLink->Call(NULL) == 1L; 824 } 825 826 sal_Bool SvdProgressInfo::ReportRescales( sal_uIntPtr nAnzRescales ) 827 { 828 nSumCurAction += nAnzRescales; 829 return pLink->Call(NULL) == 1L; 830 } 831 832 void SvdProgressInfo::SetActionCount( sal_uIntPtr _nActionCount ) 833 { 834 nActionCount = _nActionCount; 835 } 836 837 void SvdProgressInfo::SetInsertCount( sal_uIntPtr _nInsertCount ) 838 { 839 nInsertCount = _nInsertCount; 840 } 841 842 sal_Bool SvdProgressInfo::SetNextObject() 843 { 844 nActionCount = 0; 845 nCurAction = 0; 846 847 nInsertCount = 0; 848 nCurInsert = 0; 849 850 nCurObj++; 851 return ReportActions(0); 852 } 853 854 void SvdProgressInfo::ReportError() 855 { 856 pLink->Call((void *)1L); 857 } 858 859 //////////////////////////////////////////////////////////////////////////////////////////////////// 860 // #i101872# isolate GetTextEditBackgroundColor to tooling; it woll anyways only be used as long 861 // as text edit is not running on overlay 862 863 namespace 864 { 865 bool impGetSdrObjListFillColor( 866 const SdrObjList& rList, 867 const Point& rPnt, 868 const SdrPageView& rTextEditPV, 869 const SetOfByte& rVisLayers, 870 Color& rCol) 871 { 872 if(!rList.GetModel()) 873 return false; 874 875 bool bRet(false); 876 bool bMaster(rList.GetPage() ? rList.GetPage()->IsMasterPage() : false); 877 878 for(sal_uIntPtr no(rList.GetObjCount()); !bRet && no > 0; ) 879 { 880 no--; 881 SdrObject* pObj = rList.GetObj(no); 882 SdrObjList* pOL = pObj->GetSubList(); 883 884 if(pOL) 885 { 886 // group object 887 bRet = impGetSdrObjListFillColor(*pOL, rPnt, rTextEditPV, rVisLayers, rCol); 888 } 889 else 890 { 891 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(pObj); 892 893 // #108867# Exclude zero master page object (i.e. background shape) from color query 894 if(pText 895 && pObj->IsClosedObj() 896 && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no)) 897 && pObj->GetCurrentBoundRect().IsInside(rPnt) 898 && !pText->IsHideContour() 899 && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false)) 900 { 901 bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol); 902 } 903 } 904 } 905 906 return bRet; 907 } 908 909 bool impGetSdrPageFillColor( 910 const SdrPage& rPage, 911 const Point& rPnt, 912 const SdrPageView& rTextEditPV, 913 const SetOfByte& rVisLayers, 914 Color& rCol, 915 bool bSkipBackgroundShape) 916 { 917 if(!rPage.GetModel()) 918 return false; 919 920 bool bRet(impGetSdrObjListFillColor(rPage, rPnt, rTextEditPV, rVisLayers, rCol)); 921 922 if(!bRet && !rPage.IsMasterPage()) 923 { 924 if(rPage.TRG_HasMasterPage()) 925 { 926 SetOfByte aSet(rVisLayers); 927 aSet &= rPage.TRG_GetMasterPageVisibleLayers(); 928 SdrPage& rMasterPage = rPage.TRG_GetMasterPage(); 929 930 // #108867# Don't fall back to background shape on 931 // master pages. This is later handled by 932 // GetBackgroundColor, and is necessary to cater for 933 // the silly ordering: 1. shapes, 2. master page 934 // shapes, 3. page background, 4. master page 935 // background. 936 bRet = impGetSdrPageFillColor(rMasterPage, rPnt, rTextEditPV, aSet, rCol, true); 937 } 938 } 939 940 // #108867# Only now determine background color from background shapes 941 if(!bRet && !bSkipBackgroundShape) 942 { 943 rCol = rPage.GetPageBackgroundColor(); 944 return true; 945 } 946 947 return bRet; 948 } 949 950 Color impCalcBackgroundColor( 951 const Rectangle& rArea, 952 const SdrPageView& rTextEditPV, 953 const SdrPage& rPage) 954 { 955 svtools::ColorConfig aColorConfig; 956 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); 957 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 958 959 if(!rStyleSettings.GetHighContrastMode()) 960 { 961 // search in page 962 const sal_uInt16 SPOTCOUNT(5); 963 Point aSpotPos[SPOTCOUNT]; 964 Color aSpotColor[SPOTCOUNT]; 965 sal_uIntPtr nHeight( rArea.GetSize().Height() ); 966 sal_uIntPtr nWidth( rArea.GetSize().Width() ); 967 sal_uIntPtr nWidth14 = nWidth / 4; 968 sal_uIntPtr nHeight14 = nHeight / 4; 969 sal_uIntPtr nWidth34 = ( 3 * nWidth ) / 4; 970 sal_uIntPtr nHeight34 = ( 3 * nHeight ) / 4; 971 972 sal_uInt16 i; 973 for ( i = 0; i < SPOTCOUNT; i++ ) 974 { 975 // five spots are used 976 switch ( i ) 977 { 978 case 0 : 979 { 980 // Center-Spot 981 aSpotPos[i] = rArea.Center(); 982 } 983 break; 984 985 case 1 : 986 { 987 // TopLeft-Spot 988 aSpotPos[i] = rArea.TopLeft(); 989 aSpotPos[i].X() += nWidth14; 990 aSpotPos[i].Y() += nHeight14; 991 } 992 break; 993 994 case 2 : 995 { 996 // TopRight-Spot 997 aSpotPos[i] = rArea.TopLeft(); 998 aSpotPos[i].X() += nWidth34; 999 aSpotPos[i].Y() += nHeight14; 1000 } 1001 break; 1002 1003 case 3 : 1004 { 1005 // BottomLeft-Spot 1006 aSpotPos[i] = rArea.TopLeft(); 1007 aSpotPos[i].X() += nWidth14; 1008 aSpotPos[i].Y() += nHeight34; 1009 } 1010 break; 1011 1012 case 4 : 1013 { 1014 // BottomRight-Spot 1015 aSpotPos[i] = rArea.TopLeft(); 1016 aSpotPos[i].X() += nWidth34; 1017 aSpotPos[i].Y() += nHeight34; 1018 } 1019 break; 1020 1021 } 1022 1023 aSpotColor[i] = Color( COL_WHITE ); 1024 impGetSdrPageFillColor(rPage, aSpotPos[i], rTextEditPV, rTextEditPV.GetVisibleLayers(), aSpotColor[i], false); 1025 } 1026 1027 sal_uInt16 aMatch[SPOTCOUNT]; 1028 1029 for ( i = 0; i < SPOTCOUNT; i++ ) 1030 { 1031 // were same spot colors found? 1032 aMatch[i] = 0; 1033 1034 for ( sal_uInt16 j = 0; j < SPOTCOUNT; j++ ) 1035 { 1036 if( j != i ) 1037 { 1038 if( aSpotColor[i] == aSpotColor[j] ) 1039 { 1040 aMatch[i]++; 1041 } 1042 } 1043 } 1044 } 1045 1046 // highest weight to center spot 1047 aBackground = aSpotColor[0]; 1048 1049 for ( sal_uInt16 nMatchCount = SPOTCOUNT - 1; nMatchCount > 1; nMatchCount-- ) 1050 { 1051 // which spot color was found most? 1052 for ( i = 0; i < SPOTCOUNT; i++ ) 1053 { 1054 if( aMatch[i] == nMatchCount ) 1055 { 1056 aBackground = aSpotColor[i]; 1057 nMatchCount = 1; // break outer for-loop 1058 break; 1059 } 1060 } 1061 } 1062 } 1063 1064 return aBackground; 1065 } 1066 } // end of anonymous namespace 1067 1068 Color GetTextEditBackgroundColor(const SdrObjEditView& rView) 1069 { 1070 svtools::ColorConfig aColorConfig; 1071 Color aBackground(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); 1072 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); 1073 1074 if(!rStyleSettings.GetHighContrastMode()) 1075 { 1076 bool bFound(false); 1077 SdrTextObj* pText = dynamic_cast< SdrTextObj * >(rView.GetTextEditObject()); 1078 1079 if(pText && pText->IsClosedObj()) 1080 { 1081 ::sdr::table::SdrTableObj* pTable = dynamic_cast< ::sdr::table::SdrTableObj * >( pText ); 1082 1083 if( pTable ) 1084 bFound = GetDraftFillColor(pTable->GetActiveCellItemSet(), aBackground ); 1085 1086 if( !bFound ) 1087 bFound=GetDraftFillColor(pText->GetMergedItemSet(), aBackground); 1088 } 1089 1090 if(!bFound && pText) 1091 { 1092 SdrPageView* pTextEditPV = rView.GetTextEditPageView(); 1093 1094 if(pTextEditPV) 1095 { 1096 Point aPvOfs(pText->GetTextEditOffset()); 1097 const SdrPage* pPg = pTextEditPV->GetPage(); 1098 1099 if(pPg) 1100 { 1101 Rectangle aSnapRect( pText->GetSnapRect() ); 1102 aSnapRect.Move(aPvOfs.X(), aPvOfs.Y()); 1103 1104 return impCalcBackgroundColor(aSnapRect, *pTextEditPV, *pPg); 1105 } 1106 } 1107 } 1108 } 1109 1110 return aBackground; 1111 } 1112 1113 //////////////////////////////////////////////////////////////////////////////////////////////////// 1114 // eof 1115