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_sdext.hxx" 30 31 #include "PresenterPaneBase.hxx" 32 #include "PresenterCanvasHelper.hxx" 33 #include "PresenterController.hxx" 34 #include "PresenterGeometryHelper.hxx" 35 #include "PresenterPaintManager.hxx" 36 #include "PresenterTextView.hxx" 37 #include <com/sun/star/awt/PosSize.hpp> 38 #include <com/sun/star/awt/XWindow2.hpp> 39 #include <com/sun/star/awt/XWindowPeer.hpp> 40 #include <com/sun/star/lang/XMultiComponentFactory.hpp> 41 #include <com/sun/star/drawing/CanvasFeature.hpp> 42 #include <com/sun/star/rendering/CompositeOperation.hpp> 43 #include <com/sun/star/rendering/TexturingMode.hpp> 44 #include <osl/mutex.hxx> 45 46 using namespace ::com::sun::star; 47 using namespace ::com::sun::star::uno; 48 using namespace ::com::sun::star::drawing::framework; 49 using ::rtl::OUString; 50 51 namespace sdext { namespace presenter { 52 53 //===== PresenterPaneBase ===================================================== 54 55 PresenterPaneBase::PresenterPaneBase ( 56 const Reference<XComponentContext>& rxContext, 57 const ::rtl::Reference<PresenterController>& rpPresenterController) 58 : PresenterPaneBaseInterfaceBase(m_aMutex), 59 mpPresenterController(rpPresenterController), 60 mxParentWindow(), 61 mxBorderWindow(), 62 mxBorderCanvas(), 63 mxContentWindow(), 64 mxContentCanvas(), 65 mxPaneId(), 66 mxBorderPainter(), 67 mxPresenterHelper(), 68 msTitle(), 69 mxComponentContext(rxContext), 70 mpViewBackground(), 71 mbHasCallout(false), 72 maCalloutAnchor() 73 { 74 if (mpPresenterController.get() != NULL) 75 mxPresenterHelper = mpPresenterController->GetPresenterHelper(); 76 } 77 78 79 80 81 PresenterPaneBase::~PresenterPaneBase (void) 82 { 83 } 84 85 86 87 88 void PresenterPaneBase::disposing (void) 89 { 90 if (mxBorderWindow.is()) 91 { 92 mxBorderWindow->removeWindowListener(this); 93 mxBorderWindow->removePaintListener(this); 94 } 95 96 { 97 Reference<XComponent> xComponent (mxContentCanvas, UNO_QUERY); 98 mxContentCanvas = NULL; 99 if (xComponent.is()) 100 xComponent->dispose(); 101 } 102 103 { 104 Reference<XComponent> xComponent (mxContentWindow, UNO_QUERY); 105 mxContentWindow = NULL; 106 if (xComponent.is()) 107 xComponent->dispose(); 108 } 109 110 { 111 Reference<XComponent> xComponent (mxBorderCanvas, UNO_QUERY); 112 mxBorderCanvas = NULL; 113 if (xComponent.is()) 114 xComponent->dispose(); 115 } 116 117 { 118 Reference<XComponent> xComponent (mxBorderWindow, UNO_QUERY); 119 mxBorderWindow = NULL; 120 if (xComponent.is()) 121 xComponent->dispose(); 122 } 123 124 mxComponentContext = NULL; 125 } 126 127 128 129 130 void PresenterPaneBase::SetTitle (const OUString& rsTitle) 131 { 132 msTitle = rsTitle; 133 134 OSL_ASSERT(mpPresenterController.get()!=NULL); 135 OSL_ASSERT(mpPresenterController->GetPaintManager().get()!=NULL); 136 137 mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow); 138 } 139 140 141 142 143 ::rtl::OUString PresenterPaneBase::GetTitle (void) const 144 { 145 return msTitle; 146 } 147 148 149 150 151 Reference<drawing::framework::XPaneBorderPainter> 152 PresenterPaneBase::GetPaneBorderPainter (void) const 153 { 154 return mxBorderPainter; 155 } 156 157 158 159 160 void PresenterPaneBase::SetCalloutAnchor (const css::awt::Point& rCalloutAnchor) 161 { 162 mbHasCallout = true; 163 // Anchor is given in the coorindate system of the parent window. 164 // Transform it into the local coordinate system. 165 maCalloutAnchor = rCalloutAnchor; 166 const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); 167 maCalloutAnchor.X -= aBorderBox.X; 168 maCalloutAnchor.Y -= aBorderBox.Y; 169 170 // Move the bottom of the border window so that it goes through the 171 // callout anchor (special case for bottom callout). 172 sal_Int32 nHeight (rCalloutAnchor.Y - aBorderBox.Y); 173 if (mxBorderPainter.is() && mxPaneId.is()) 174 nHeight += mxBorderPainter->getCalloutOffset(mxPaneId->getResourceURL()).Y; 175 176 if (nHeight != aBorderBox.Height) 177 { 178 mxBorderWindow->setPosSize( 179 aBorderBox.X, 180 aBorderBox.Y, 181 aBorderBox.Width, 182 nHeight, 183 awt::PosSize::HEIGHT); 184 } 185 186 mpPresenterController->GetPaintManager()->Invalidate(mxBorderWindow); 187 } 188 189 190 191 192 awt::Point PresenterPaneBase::GetCalloutAnchor (void) const 193 { 194 return maCalloutAnchor; 195 } 196 197 198 199 200 ::boost::shared_ptr<PresenterTextView> PresenterPaneBase::GetTextViewForTitle (void) 201 { 202 ::boost::shared_ptr<PresenterTextView> pTextView( 203 new PresenterTextView( 204 mxComponentContext, 205 mxBorderCanvas)); 206 pTextView->SetText(msTitle); 207 return pTextView; 208 } 209 210 211 212 213 //----- XInitialization ------------------------------------------------------- 214 215 void SAL_CALL PresenterPaneBase::initialize (const Sequence<Any>& rArguments) 216 throw (Exception, RuntimeException) 217 { 218 ThrowIfDisposed(); 219 220 if ( ! mxComponentContext.is()) 221 { 222 throw RuntimeException( 223 OUString::createFromAscii("PresenterSpritePane: missing component context"), 224 static_cast<XWeak*>(this)); 225 } 226 227 if (rArguments.getLength() == 5 || rArguments.getLength() == 6) 228 { 229 try 230 { 231 // Get the resource id from the first argument. 232 if ( ! (rArguments[0] >>= mxPaneId)) 233 { 234 throw lang::IllegalArgumentException( 235 OUString::createFromAscii("PresenterPane: invalid pane id"), 236 static_cast<XWeak*>(this), 237 0); 238 } 239 240 if ( ! (rArguments[1] >>= mxParentWindow)) 241 { 242 throw lang::IllegalArgumentException( 243 OUString::createFromAscii("PresenterPane: invalid parent window"), 244 static_cast<XWeak*>(this), 245 1); 246 } 247 248 Reference<rendering::XSpriteCanvas> xParentCanvas; 249 if ( ! (rArguments[2] >>= xParentCanvas)) 250 { 251 throw lang::IllegalArgumentException( 252 OUString::createFromAscii("PresenterPane: invalid parent canvas"), 253 static_cast<XWeak*>(this), 254 2); 255 } 256 257 if ( ! (rArguments[3] >>= msTitle)) 258 { 259 throw lang::IllegalArgumentException( 260 OUString::createFromAscii("PresenterPane: invalid title"), 261 static_cast<XWeak*>(this), 262 3); 263 } 264 265 if ( ! (rArguments[4] >>= mxBorderPainter)) 266 { 267 throw lang::IllegalArgumentException( 268 OUString::createFromAscii("PresenterPane: invalid border painter"), 269 static_cast<XWeak*>(this), 270 4); 271 } 272 273 bool bIsWindowVisibleOnCreation (true); 274 if (rArguments.getLength()>5 && ! (rArguments[5] >>= bIsWindowVisibleOnCreation)) 275 { 276 throw lang::IllegalArgumentException( 277 OUString::createFromAscii("PresenterPane: invalid window visibility flag"), 278 static_cast<XWeak*>(this), 279 5); 280 } 281 282 CreateWindows(mxParentWindow, bIsWindowVisibleOnCreation); 283 284 if (mxBorderWindow.is()) 285 { 286 mxBorderWindow->addWindowListener(this); 287 mxBorderWindow->addPaintListener(this); 288 } 289 290 CreateCanvases(mxParentWindow, xParentCanvas); 291 292 // Raise new windows. 293 ToTop(); 294 } 295 catch (Exception&) 296 { 297 mxContentWindow = NULL; 298 mxComponentContext = NULL; 299 throw; 300 } 301 } 302 else 303 { 304 throw RuntimeException( 305 OUString::createFromAscii("PresenterSpritePane: invalid number of arguments"), 306 static_cast<XWeak*>(this)); 307 } 308 } 309 310 311 312 313 //----- XResourceId ----------------------------------------------------------- 314 315 Reference<XResourceId> SAL_CALL PresenterPaneBase::getResourceId (void) 316 throw (RuntimeException) 317 { 318 ThrowIfDisposed(); 319 return mxPaneId; 320 } 321 322 323 324 325 sal_Bool SAL_CALL PresenterPaneBase::isAnchorOnly (void) 326 throw (RuntimeException) 327 { 328 return true; 329 } 330 331 332 333 334 //----- XWindowListener ------------------------------------------------------- 335 336 void SAL_CALL PresenterPaneBase::windowResized (const awt::WindowEvent& rEvent) 337 throw (RuntimeException) 338 { 339 (void)rEvent; 340 ThrowIfDisposed(); 341 } 342 343 344 345 346 347 void SAL_CALL PresenterPaneBase::windowMoved (const awt::WindowEvent& rEvent) 348 throw (RuntimeException) 349 { 350 (void)rEvent; 351 ThrowIfDisposed(); 352 } 353 354 355 356 357 void SAL_CALL PresenterPaneBase::windowShown (const lang::EventObject& rEvent) 358 throw (RuntimeException) 359 { 360 (void)rEvent; 361 ThrowIfDisposed(); 362 } 363 364 365 366 367 void SAL_CALL PresenterPaneBase::windowHidden (const lang::EventObject& rEvent) 368 throw (RuntimeException) 369 { 370 (void)rEvent; 371 ThrowIfDisposed(); 372 } 373 374 375 376 377 //----- lang::XEventListener -------------------------------------------------- 378 379 void SAL_CALL PresenterPaneBase::disposing (const lang::EventObject& rEvent) 380 throw (RuntimeException) 381 { 382 if (rEvent.Source == mxBorderWindow) 383 { 384 mxBorderWindow = NULL; 385 } 386 } 387 388 389 390 391 //----------------------------------------------------------------------------- 392 393 394 void PresenterPaneBase::CreateWindows ( 395 const Reference<awt::XWindow>& rxParentWindow, 396 const bool bIsWindowVisibleOnCreation) 397 { 398 if (mxPresenterHelper.is() && rxParentWindow.is()) 399 { 400 401 mxBorderWindow = mxPresenterHelper->createWindow( 402 rxParentWindow, 403 sal_False, 404 bIsWindowVisibleOnCreation, 405 sal_False, 406 sal_False); 407 mxContentWindow = mxPresenterHelper->createWindow( 408 mxBorderWindow, 409 sal_False, 410 bIsWindowVisibleOnCreation, 411 sal_False, 412 sal_False); 413 } 414 } 415 416 417 418 419 Reference<awt::XWindow> PresenterPaneBase::GetBorderWindow (void) const 420 { 421 return mxBorderWindow; 422 } 423 424 425 426 427 void PresenterPaneBase::ToTop (void) 428 { 429 if (mxPresenterHelper.is()) 430 mxPresenterHelper->toTop(mxContentWindow); 431 } 432 433 434 435 436 void PresenterPaneBase::SetBackground (const SharedBitmapDescriptor& rpBackground) 437 { 438 mpViewBackground = rpBackground; 439 } 440 441 442 443 444 void PresenterPaneBase::PaintBorderBackground ( 445 const awt::Rectangle& rBorderBox, 446 const awt::Rectangle& rUpdateBox) 447 { 448 (void)rBorderBox; 449 (void)rUpdateBox; 450 /* 451 // The outer box of the border is given. We need the center and inner 452 // box as well. 453 awt::Rectangle aCenterBox ( 454 mxBorderPainter->removeBorder( 455 mxPaneId->getResourceURL(), 456 rBorderBox, 457 drawing::framework::BorderType_OUTER_BORDER)); 458 awt::Rectangle aInnerBox ( 459 mxBorderPainter->removeBorder( 460 mxPaneId->getResourceURL(), 461 rBorderBox, 462 drawing::framework::BorderType_TOTAL_BORDER)); 463 mpPresenterController->GetCanvasHelper()->Paint( 464 mpViewBackground, 465 mxBorderCanvas, 466 rUpdateBox, 467 aCenterBox, 468 aInnerBox); 469 */ 470 } 471 472 473 474 475 void PresenterPaneBase::PaintBorder (const awt::Rectangle& rUpdateBox) 476 { 477 OSL_ASSERT(mxPaneId.is()); 478 479 if (mxBorderPainter.is() && mxBorderWindow.is() && mxBorderCanvas.is()) 480 { 481 awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); 482 awt::Rectangle aLocalBorderBox (0,0, aBorderBox.Width, aBorderBox.Height); 483 484 PaintBorderBackground(aLocalBorderBox, rUpdateBox); 485 486 if (mbHasCallout) 487 mxBorderPainter->paintBorderWithCallout( 488 mxPaneId->getResourceURL(), 489 mxBorderCanvas, 490 aLocalBorderBox, 491 rUpdateBox, 492 msTitle, 493 maCalloutAnchor); 494 else 495 mxBorderPainter->paintBorder( 496 mxPaneId->getResourceURL(), 497 mxBorderCanvas, 498 aLocalBorderBox, 499 rUpdateBox, 500 msTitle); 501 } 502 } 503 504 505 506 507 void PresenterPaneBase::LayoutContextWindow (void) 508 { 509 OSL_ASSERT(mxPaneId.is()); 510 OSL_ASSERT(mxBorderWindow.is()); 511 OSL_ASSERT(mxContentWindow.is()); 512 if (mxBorderPainter.is() && mxPaneId.is() && mxBorderWindow.is() && mxContentWindow.is()) 513 { 514 const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize()); 515 const awt::Rectangle aInnerBox (mxBorderPainter->removeBorder( 516 mxPaneId->getResourceURL(), 517 aBorderBox, 518 drawing::framework::BorderType_TOTAL_BORDER)); 519 mxContentWindow->setPosSize( 520 aInnerBox.X - aBorderBox.X, 521 aInnerBox.Y - aBorderBox.Y, 522 aInnerBox.Width, 523 aInnerBox.Height, 524 awt::PosSize::POSSIZE); 525 } 526 } 527 528 529 530 531 bool PresenterPaneBase::IsVisible (void) const 532 { 533 Reference<awt::XWindow2> xWindow2 (mxBorderPainter, UNO_QUERY); 534 if (xWindow2.is()) 535 return xWindow2->isVisible(); 536 537 return false; 538 } 539 540 541 542 543 void PresenterPaneBase::ThrowIfDisposed (void) 544 throw (::com::sun::star::lang::DisposedException) 545 { 546 if (rBHelper.bDisposed || rBHelper.bInDispose) 547 { 548 throw lang::DisposedException ( 549 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 550 "PresenterPane object has already been disposed")), 551 static_cast<uno::XWeak*>(this)); 552 } 553 } 554 555 556 557 558 } } // end of namespace ::sd::presenter 559