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