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 #include "precompiled_svx.hxx" 29 #include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx> 30 #include <svx/svdotext.hxx> 31 #include <basegfx/color/bcolor.hxx> 32 #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> 33 #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> 34 #include <editeng/outlobj.hxx> 35 #include <editeng/editobj.hxx> 36 #include <editeng/flditem.hxx> 37 #include <drawinglayer/geometry/viewinformation2d.hxx> 38 #include <svx/unoapi.hxx> 39 #include <svx/svdpage.hxx> 40 #include <svx/svdmodel.hxx> 41 #include <svx/svdoutl.hxx> 42 #include <com/sun/star/beans/XPropertySet.hpp> 43 44 ////////////////////////////////////////////////////////////////////////////// 45 46 using namespace com::sun::star; 47 48 ////////////////////////////////////////////////////////////////////////////// 49 50 namespace 51 { 52 sal_Int16 getPageNumber(const uno::Reference< drawing::XDrawPage >& rxDrawPage) 53 { 54 sal_Int16 nRetval(0); 55 uno::Reference< beans::XPropertySet > xSet(rxDrawPage, uno::UNO_QUERY); 56 57 if (xSet.is()) 58 { 59 try 60 { 61 const uno::Any aNumber(xSet->getPropertyValue(::rtl::OUString::createFromAscii("Number"))); 62 aNumber >>= nRetval; 63 } 64 catch(const uno::Exception&) 65 { 66 OSL_ASSERT(false); 67 } 68 } 69 70 return nRetval; 71 } 72 73 sal_Int16 getPageCount(const uno::Reference< drawing::XDrawPage >& rxDrawPage) 74 { 75 sal_Int16 nRetval(0); 76 SdrPage* pPage = GetSdrPageFromXDrawPage(rxDrawPage); 77 78 if(pPage && pPage->GetModel()) 79 { 80 if( (pPage->GetPageNum() == 0) && !pPage->IsMasterPage() ) 81 { 82 // handout page! 83 return pPage->GetModel()->getHandoutPageCount(); 84 } 85 else 86 { 87 const sal_uInt16 nPageCount(pPage->GetModel()->GetPageCount()); 88 nRetval = ((sal_Int16)nPageCount - 1) / 2; 89 } 90 } 91 92 return nRetval; 93 } 94 } // end of anonymous namespace 95 96 ////////////////////////////////////////////////////////////////////////////// 97 98 namespace drawinglayer 99 { 100 namespace primitive2d 101 { 102 // support for XTEXT_PAINTSHAPE_BEGIN/XTEXT_PAINTSHAPE_END Metafile comments 103 // for slideshow. This uses TextHierarchyBlockPrimitive2D to mark a text block. 104 // ATM there is only one text block per SdrObject, this may get more in the future 105 Primitive2DSequence SdrTextPrimitive2D::encapsulateWithTextHierarchyBlockPrimitive2D(const Primitive2DSequence& rCandidate) const 106 { 107 Primitive2DReference xReference(new TextHierarchyBlockPrimitive2D(rCandidate)); 108 Primitive2DSequence xRetval(&xReference, 1); 109 110 return xRetval; 111 } 112 113 SdrTextPrimitive2D::SdrTextPrimitive2D( 114 const SdrText* pSdrText, 115 const OutlinerParaObject& rOutlinerParaObject) 116 : BufferedDecompositionPrimitive2D(), 117 mrSdrText(const_cast< SdrText* >(pSdrText)), 118 maOutlinerParaObject(rOutlinerParaObject), 119 mxLastVisualizingPage(), 120 mnLastPageNumber(0), 121 mnLastPageCount(0), 122 maLastTextBackgroundColor(), 123 mbContainsPageField(false), 124 mbContainsPageCountField(false), 125 mbContainsOtherFields(false) 126 { 127 const EditTextObject& rETO = maOutlinerParaObject.GetTextObject(); 128 129 mbContainsPageField = rETO.HasField(SvxPageField::StaticType()); 130 mbContainsPageCountField = rETO.HasField(SvxPagesField::StaticType()); 131 mbContainsOtherFields = rETO.HasField(SvxHeaderField::StaticType()) 132 || rETO.HasField(SvxFooterField::StaticType()) 133 || rETO.HasField(SvxDateTimeField::StaticType()) 134 || rETO.HasField(SvxAuthorField::StaticType()); 135 } 136 137 bool SdrTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 138 { 139 if(BufferedDecompositionPrimitive2D::operator==(rPrimitive)) 140 { 141 const SdrTextPrimitive2D& rCompare = (SdrTextPrimitive2D&)rPrimitive; 142 143 return ( 144 145 // compare OPO and content, but not WrongList 146 getOutlinerParaObject() == rCompare.getOutlinerParaObject() 147 148 // also compare WrongList (not-persistent data, but visualized) 149 && getOutlinerParaObject().isWrongListEqual(rCompare.getOutlinerParaObject())); 150 } 151 152 return false; 153 } 154 155 Primitive2DSequence SdrTextPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const 156 { 157 uno::Reference< drawing::XDrawPage > xCurrentlyVisualizingPage; 158 bool bCurrentlyVisualizingPageIsSet(false); 159 Color aNewTextBackgroundColor; 160 bool bNewTextBackgroundColorIsSet(false); 161 sal_Int16 nCurrentlyValidPageNumber(0); 162 sal_Int16 nCurrentlyValidPageCount(0); 163 164 if(getBuffered2DDecomposition().hasElements()) 165 { 166 bool bDoDelete(false); 167 168 // check visualized page 169 if(mbContainsPageField || mbContainsPageCountField || mbContainsOtherFields) 170 { 171 // get visualized page and remember 172 xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage(); 173 bCurrentlyVisualizingPageIsSet = true; 174 175 if(xCurrentlyVisualizingPage != mxLastVisualizingPage) 176 { 177 bDoDelete = true; 178 } 179 180 // #i98870# check visualized PageNumber 181 if(!bDoDelete && mbContainsPageField) 182 { 183 nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage); 184 185 if(nCurrentlyValidPageNumber != mnLastPageNumber) 186 { 187 bDoDelete = true; 188 } 189 } 190 191 // #i98870# check visualized PageCount, too 192 if(!bDoDelete && mbContainsPageCountField) 193 { 194 nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage); 195 196 if(nCurrentlyValidPageCount != mnLastPageCount) 197 { 198 bDoDelete = true; 199 } 200 } 201 } 202 203 // #i101443# check change of TextBackgroundolor 204 if(!bDoDelete && getSdrText() && getSdrText()->GetModel()) 205 { 206 SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0); 207 aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor(); 208 bNewTextBackgroundColorIsSet = true; 209 210 if(aNewTextBackgroundColor != maLastTextBackgroundColor) 211 { 212 bDoDelete = true; 213 } 214 } 215 216 if(bDoDelete) 217 { 218 const_cast< SdrTextPrimitive2D* >(this)->setBuffered2DDecomposition(Primitive2DSequence()); 219 } 220 } 221 222 if(!getBuffered2DDecomposition().hasElements()) 223 { 224 if(!bCurrentlyVisualizingPageIsSet && mbContainsPageField) 225 { 226 xCurrentlyVisualizingPage = rViewInformation.getVisualizedPage(); 227 } 228 229 if(!nCurrentlyValidPageNumber && mbContainsPageField) 230 { 231 nCurrentlyValidPageNumber = getPageNumber(xCurrentlyVisualizingPage); 232 } 233 234 if(!nCurrentlyValidPageCount && mbContainsPageCountField) 235 { 236 nCurrentlyValidPageCount = getPageCount(xCurrentlyVisualizingPage); 237 } 238 239 if(!bNewTextBackgroundColorIsSet && getSdrText() && getSdrText()->GetModel()) 240 { 241 SdrOutliner& rDrawOutliner = getSdrText()->GetModel()->GetDrawOutliner(0); 242 aNewTextBackgroundColor = rDrawOutliner.GetBackgroundColor(); 243 } 244 245 const_cast< SdrTextPrimitive2D* >(this)->mxLastVisualizingPage = xCurrentlyVisualizingPage; 246 const_cast< SdrTextPrimitive2D* >(this)->mnLastPageNumber = nCurrentlyValidPageNumber; 247 const_cast< SdrTextPrimitive2D* >(this)->mnLastPageCount = nCurrentlyValidPageCount; 248 const_cast< SdrTextPrimitive2D* >(this)->maLastTextBackgroundColor = aNewTextBackgroundColor; 249 } 250 251 // call parent 252 return BufferedDecompositionPrimitive2D::get2DDecomposition(rViewInformation); 253 } 254 } // end of namespace primitive2d 255 } // end of namespace drawinglayer 256 257 ////////////////////////////////////////////////////////////////////////////// 258 259 namespace drawinglayer 260 { 261 namespace primitive2d 262 { 263 Primitive2DSequence SdrContourTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const 264 { 265 Primitive2DSequence aRetval; 266 getSdrText()->GetObject().impDecomposeContourTextPrimitive(aRetval, *this, aViewInformation); 267 268 return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); 269 } 270 271 SdrContourTextPrimitive2D::SdrContourTextPrimitive2D( 272 const SdrText* pSdrText, 273 const OutlinerParaObject& rOutlinerParaObject, 274 const basegfx::B2DPolyPolygon& rUnitPolyPolygon, 275 const basegfx::B2DHomMatrix& rObjectTransform) 276 : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), 277 maUnitPolyPolygon(rUnitPolyPolygon), 278 maObjectTransform(rObjectTransform) 279 { 280 } 281 282 bool SdrContourTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 283 { 284 if(SdrTextPrimitive2D::operator==(rPrimitive)) 285 { 286 const SdrContourTextPrimitive2D& rCompare = (SdrContourTextPrimitive2D&)rPrimitive; 287 288 return (getUnitPolyPolygon() == rCompare.getUnitPolyPolygon() 289 && getObjectTransform() == rCompare.getObjectTransform()); 290 } 291 292 return false; 293 } 294 295 SdrTextPrimitive2D* SdrContourTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const 296 { 297 return new SdrContourTextPrimitive2D( 298 getSdrText(), 299 getOutlinerParaObject(), 300 getUnitPolyPolygon(), 301 rTransform * getObjectTransform()); 302 } 303 304 // provide unique ID 305 ImplPrimitrive2DIDBlock(SdrContourTextPrimitive2D, PRIMITIVE2D_ID_SDRCONTOURTEXTPRIMITIVE2D) 306 307 } // end of namespace primitive2d 308 } // end of namespace drawinglayer 309 310 ////////////////////////////////////////////////////////////////////////////// 311 312 namespace drawinglayer 313 { 314 namespace primitive2d 315 { 316 Primitive2DSequence SdrPathTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const 317 { 318 Primitive2DSequence aRetval; 319 getSdrText()->GetObject().impDecomposePathTextPrimitive(aRetval, *this, aViewInformation); 320 321 return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); 322 } 323 324 SdrPathTextPrimitive2D::SdrPathTextPrimitive2D( 325 const SdrText* pSdrText, 326 const OutlinerParaObject& rOutlinerParaObject, 327 const basegfx::B2DPolyPolygon& rPathPolyPolygon, 328 const attribute::SdrFormTextAttribute& rSdrFormTextAttribute) 329 : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), 330 maPathPolyPolygon(rPathPolyPolygon), 331 maSdrFormTextAttribute(rSdrFormTextAttribute) 332 { 333 } 334 335 bool SdrPathTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 336 { 337 if(SdrTextPrimitive2D::operator==(rPrimitive)) 338 { 339 const SdrPathTextPrimitive2D& rCompare = (SdrPathTextPrimitive2D&)rPrimitive; 340 341 return (getPathPolyPolygon() == rCompare.getPathPolyPolygon() 342 && getSdrFormTextAttribute() == rCompare.getSdrFormTextAttribute()); 343 } 344 345 return false; 346 } 347 348 SdrTextPrimitive2D* SdrPathTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const 349 { 350 basegfx::B2DPolyPolygon aNewPolyPolygon(getPathPolyPolygon()); 351 aNewPolyPolygon.transform(rTransform); 352 353 return new SdrPathTextPrimitive2D( 354 getSdrText(), 355 getOutlinerParaObject(), 356 aNewPolyPolygon, 357 getSdrFormTextAttribute()); 358 } 359 360 // provide unique ID 361 ImplPrimitrive2DIDBlock(SdrPathTextPrimitive2D, PRIMITIVE2D_ID_SDRPATHTEXTPRIMITIVE2D) 362 363 } // end of namespace primitive2d 364 } // end of namespace drawinglayer 365 366 ////////////////////////////////////////////////////////////////////////////// 367 368 namespace drawinglayer 369 { 370 namespace primitive2d 371 { 372 Primitive2DSequence SdrBlockTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const 373 { 374 Primitive2DSequence aRetval; 375 getSdrText()->GetObject().impDecomposeBlockTextPrimitive(aRetval, *this, aViewInformation); 376 377 return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); 378 } 379 380 SdrBlockTextPrimitive2D::SdrBlockTextPrimitive2D( 381 const SdrText* pSdrText, 382 const OutlinerParaObject& rOutlinerParaObject, 383 const basegfx::B2DHomMatrix& rTextRangeTransform, 384 SdrTextHorzAdjust aSdrTextHorzAdjust, 385 SdrTextVertAdjust aSdrTextVertAdjust, 386 bool bFixedCellHeight, 387 bool bUnlimitedPage, 388 bool bCellText, 389 bool bWordWrap, 390 bool bClipOnBounds) 391 : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), 392 maTextRangeTransform(rTextRangeTransform), 393 maSdrTextHorzAdjust(aSdrTextHorzAdjust), 394 maSdrTextVertAdjust(aSdrTextVertAdjust), 395 mbFixedCellHeight(bFixedCellHeight), 396 mbUnlimitedPage(bUnlimitedPage), 397 mbCellText(bCellText), 398 mbWordWrap(bWordWrap), 399 mbClipOnBounds(bClipOnBounds) 400 { 401 } 402 403 bool SdrBlockTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 404 { 405 if(SdrTextPrimitive2D::operator==(rPrimitive)) 406 { 407 const SdrBlockTextPrimitive2D& rCompare = (SdrBlockTextPrimitive2D&)rPrimitive; 408 409 return (getTextRangeTransform() == rCompare.getTextRangeTransform() 410 && getSdrTextHorzAdjust() == rCompare.getSdrTextHorzAdjust() 411 && getSdrTextVertAdjust() == rCompare.getSdrTextVertAdjust() 412 && isFixedCellHeight() == rCompare.isFixedCellHeight() 413 && getUnlimitedPage() == rCompare.getUnlimitedPage() 414 && getCellText() == rCompare.getCellText() 415 && getWordWrap() == rCompare.getWordWrap() 416 && getClipOnBounds() == rCompare.getClipOnBounds()); 417 } 418 419 return false; 420 } 421 422 SdrTextPrimitive2D* SdrBlockTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const 423 { 424 return new SdrBlockTextPrimitive2D( 425 getSdrText(), 426 getOutlinerParaObject(), 427 rTransform * getTextRangeTransform(), 428 getSdrTextHorzAdjust(), 429 getSdrTextVertAdjust(), 430 isFixedCellHeight(), 431 getUnlimitedPage(), 432 getCellText(), 433 getWordWrap(), 434 getClipOnBounds()); 435 } 436 437 // provide unique ID 438 ImplPrimitrive2DIDBlock(SdrBlockTextPrimitive2D, PRIMITIVE2D_ID_SDRBLOCKTEXTPRIMITIVE2D) 439 440 } // end of namespace primitive2d 441 } // end of namespace drawinglayer 442 443 ////////////////////////////////////////////////////////////////////////////// 444 445 namespace drawinglayer 446 { 447 namespace primitive2d 448 { 449 Primitive2DSequence SdrStretchTextPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& aViewInformation) const 450 { 451 Primitive2DSequence aRetval; 452 getSdrText()->GetObject().impDecomposeStretchTextPrimitive(aRetval, *this, aViewInformation); 453 454 return encapsulateWithTextHierarchyBlockPrimitive2D(aRetval); 455 } 456 457 SdrStretchTextPrimitive2D::SdrStretchTextPrimitive2D( 458 const SdrText* pSdrText, 459 const OutlinerParaObject& rOutlinerParaObject, 460 const basegfx::B2DHomMatrix& rTextRangeTransform, 461 bool bFixedCellHeight) 462 : SdrTextPrimitive2D(pSdrText, rOutlinerParaObject), 463 maTextRangeTransform(rTextRangeTransform), 464 mbFixedCellHeight(bFixedCellHeight) 465 { 466 } 467 468 bool SdrStretchTextPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 469 { 470 if(SdrTextPrimitive2D::operator==(rPrimitive)) 471 { 472 const SdrStretchTextPrimitive2D& rCompare = (SdrStretchTextPrimitive2D&)rPrimitive; 473 474 return (getTextRangeTransform() == rCompare.getTextRangeTransform() 475 && isFixedCellHeight() == rCompare.isFixedCellHeight()); 476 } 477 478 return false; 479 } 480 481 SdrTextPrimitive2D* SdrStretchTextPrimitive2D::createTransformedClone(const basegfx::B2DHomMatrix& rTransform) const 482 { 483 return new SdrStretchTextPrimitive2D( 484 getSdrText(), 485 getOutlinerParaObject(), 486 rTransform * getTextRangeTransform(), 487 isFixedCellHeight()); 488 } 489 490 // provide unique ID 491 ImplPrimitrive2DIDBlock(SdrStretchTextPrimitive2D, PRIMITIVE2D_ID_SDRSTRETCHTEXTPRIMITIVE2D) 492 493 } // end of namespace primitive2d 494 } // end of namespace drawinglayer 495 496 ////////////////////////////////////////////////////////////////////////////// 497 // eof 498