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 {
213 ThrowIfDisposed();
214
215 if ( ! mxComponentContext.is())
216 {
217 throw RuntimeException(
218 OUString::createFromAscii("PresenterSpritePane: missing component context"),
219 static_cast<XWeak*>(this));
220 }
221
222 if (rArguments.getLength() == 5 || rArguments.getLength() == 6)
223 {
224 try
225 {
226 // Get the resource id from the first argument.
227 if ( ! (rArguments[0] >>= mxPaneId))
228 {
229 throw lang::IllegalArgumentException(
230 OUString::createFromAscii("PresenterPane: invalid pane id"),
231 static_cast<XWeak*>(this),
232 0);
233 }
234
235 if ( ! (rArguments[1] >>= mxParentWindow))
236 {
237 throw lang::IllegalArgumentException(
238 OUString::createFromAscii("PresenterPane: invalid parent window"),
239 static_cast<XWeak*>(this),
240 1);
241 }
242
243 Reference<rendering::XSpriteCanvas> xParentCanvas;
244 if ( ! (rArguments[2] >>= xParentCanvas))
245 {
246 throw lang::IllegalArgumentException(
247 OUString::createFromAscii("PresenterPane: invalid parent canvas"),
248 static_cast<XWeak*>(this),
249 2);
250 }
251
252 if ( ! (rArguments[3] >>= msTitle))
253 {
254 throw lang::IllegalArgumentException(
255 OUString::createFromAscii("PresenterPane: invalid title"),
256 static_cast<XWeak*>(this),
257 3);
258 }
259
260 if ( ! (rArguments[4] >>= mxBorderPainter))
261 {
262 throw lang::IllegalArgumentException(
263 OUString::createFromAscii("PresenterPane: invalid border painter"),
264 static_cast<XWeak*>(this),
265 4);
266 }
267
268 bool bIsWindowVisibleOnCreation (true);
269 if (rArguments.getLength()>5 && ! (rArguments[5] >>= bIsWindowVisibleOnCreation))
270 {
271 throw lang::IllegalArgumentException(
272 OUString::createFromAscii("PresenterPane: invalid window visibility flag"),
273 static_cast<XWeak*>(this),
274 5);
275 }
276
277 CreateWindows(mxParentWindow, bIsWindowVisibleOnCreation);
278
279 if (mxBorderWindow.is())
280 {
281 mxBorderWindow->addWindowListener(this);
282 mxBorderWindow->addPaintListener(this);
283 }
284
285 CreateCanvases(mxParentWindow, xParentCanvas);
286
287 // Raise new windows.
288 ToTop();
289 }
290 catch (Exception&)
291 {
292 mxContentWindow = NULL;
293 mxComponentContext = NULL;
294 throw;
295 }
296 }
297 else
298 {
299 throw RuntimeException(
300 OUString::createFromAscii("PresenterSpritePane: invalid number of arguments"),
301 static_cast<XWeak*>(this));
302 }
303 }
304
305
306
307
308 //----- XResourceId -----------------------------------------------------------
309
getResourceId(void)310 Reference<XResourceId> SAL_CALL PresenterPaneBase::getResourceId (void)
311 {
312 ThrowIfDisposed();
313 return mxPaneId;
314 }
315
316
317
318
isAnchorOnly(void)319 sal_Bool SAL_CALL PresenterPaneBase::isAnchorOnly (void)
320 {
321 return true;
322 }
323
324
325
326
327 //----- XWindowListener -------------------------------------------------------
328
windowResized(const awt::WindowEvent & rEvent)329 void SAL_CALL PresenterPaneBase::windowResized (const awt::WindowEvent& rEvent)
330 {
331 (void)rEvent;
332 ThrowIfDisposed();
333 }
334
335
336
337
338
windowMoved(const awt::WindowEvent & rEvent)339 void SAL_CALL PresenterPaneBase::windowMoved (const awt::WindowEvent& rEvent)
340 {
341 (void)rEvent;
342 ThrowIfDisposed();
343 }
344
345
346
347
windowShown(const lang::EventObject & rEvent)348 void SAL_CALL PresenterPaneBase::windowShown (const lang::EventObject& rEvent)
349 {
350 (void)rEvent;
351 ThrowIfDisposed();
352 }
353
354
355
356
windowHidden(const lang::EventObject & rEvent)357 void SAL_CALL PresenterPaneBase::windowHidden (const lang::EventObject& rEvent)
358 {
359 (void)rEvent;
360 ThrowIfDisposed();
361 }
362
363
364
365
366 //----- lang::XEventListener --------------------------------------------------
367
disposing(const lang::EventObject & rEvent)368 void SAL_CALL PresenterPaneBase::disposing (const lang::EventObject& rEvent)
369 {
370 if (rEvent.Source == mxBorderWindow)
371 {
372 mxBorderWindow = NULL;
373 }
374 }
375
376
377
378
379 //-----------------------------------------------------------------------------
380
381
CreateWindows(const Reference<awt::XWindow> & rxParentWindow,const bool bIsWindowVisibleOnCreation)382 void PresenterPaneBase::CreateWindows (
383 const Reference<awt::XWindow>& rxParentWindow,
384 const bool bIsWindowVisibleOnCreation)
385 {
386 if (mxPresenterHelper.is() && rxParentWindow.is())
387 {
388
389 mxBorderWindow = mxPresenterHelper->createWindow(
390 rxParentWindow,
391 sal_False,
392 bIsWindowVisibleOnCreation,
393 sal_False,
394 sal_False);
395 mxContentWindow = mxPresenterHelper->createWindow(
396 mxBorderWindow,
397 sal_False,
398 bIsWindowVisibleOnCreation,
399 sal_False,
400 sal_False);
401 }
402 }
403
404
405
406
GetBorderWindow(void) const407 Reference<awt::XWindow> PresenterPaneBase::GetBorderWindow (void) const
408 {
409 return mxBorderWindow;
410 }
411
412
413
414
ToTop(void)415 void PresenterPaneBase::ToTop (void)
416 {
417 if (mxPresenterHelper.is())
418 mxPresenterHelper->toTop(mxContentWindow);
419 }
420
421
422
423
SetBackground(const SharedBitmapDescriptor & rpBackground)424 void PresenterPaneBase::SetBackground (const SharedBitmapDescriptor& rpBackground)
425 {
426 mpViewBackground = rpBackground;
427 }
428
429
430
431
PaintBorderBackground(const awt::Rectangle & rBorderBox,const awt::Rectangle & rUpdateBox)432 void PresenterPaneBase::PaintBorderBackground (
433 const awt::Rectangle& rBorderBox,
434 const awt::Rectangle& rUpdateBox)
435 {
436 (void)rBorderBox;
437 (void)rUpdateBox;
438 /*
439 // The outer box of the border is given. We need the center and inner
440 // box as well.
441 awt::Rectangle aCenterBox (
442 mxBorderPainter->removeBorder(
443 mxPaneId->getResourceURL(),
444 rBorderBox,
445 drawing::framework::BorderType_OUTER_BORDER));
446 awt::Rectangle aInnerBox (
447 mxBorderPainter->removeBorder(
448 mxPaneId->getResourceURL(),
449 rBorderBox,
450 drawing::framework::BorderType_TOTAL_BORDER));
451 mpPresenterController->GetCanvasHelper()->Paint(
452 mpViewBackground,
453 mxBorderCanvas,
454 rUpdateBox,
455 aCenterBox,
456 aInnerBox);
457 */
458 }
459
460
461
462
PaintBorder(const awt::Rectangle & rUpdateBox)463 void PresenterPaneBase::PaintBorder (const awt::Rectangle& rUpdateBox)
464 {
465 OSL_ASSERT(mxPaneId.is());
466
467 if (mxBorderPainter.is() && mxBorderWindow.is() && mxBorderCanvas.is())
468 {
469 awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
470 awt::Rectangle aLocalBorderBox (0,0, aBorderBox.Width, aBorderBox.Height);
471
472 PaintBorderBackground(aLocalBorderBox, rUpdateBox);
473
474 if (mbHasCallout)
475 mxBorderPainter->paintBorderWithCallout(
476 mxPaneId->getResourceURL(),
477 mxBorderCanvas,
478 aLocalBorderBox,
479 rUpdateBox,
480 msTitle,
481 maCalloutAnchor);
482 else
483 mxBorderPainter->paintBorder(
484 mxPaneId->getResourceURL(),
485 mxBorderCanvas,
486 aLocalBorderBox,
487 rUpdateBox,
488 msTitle);
489 }
490 }
491
492
493
494
LayoutContextWindow(void)495 void PresenterPaneBase::LayoutContextWindow (void)
496 {
497 OSL_ASSERT(mxPaneId.is());
498 OSL_ASSERT(mxBorderWindow.is());
499 OSL_ASSERT(mxContentWindow.is());
500 if (mxBorderPainter.is() && mxPaneId.is() && mxBorderWindow.is() && mxContentWindow.is())
501 {
502 const awt::Rectangle aBorderBox (mxBorderWindow->getPosSize());
503 const awt::Rectangle aInnerBox (mxBorderPainter->removeBorder(
504 mxPaneId->getResourceURL(),
505 aBorderBox,
506 drawing::framework::BorderType_TOTAL_BORDER));
507 mxContentWindow->setPosSize(
508 aInnerBox.X - aBorderBox.X,
509 aInnerBox.Y - aBorderBox.Y,
510 aInnerBox.Width,
511 aInnerBox.Height,
512 awt::PosSize::POSSIZE);
513 }
514 }
515
516
517
518
IsVisible(void) const519 bool PresenterPaneBase::IsVisible (void) const
520 {
521 Reference<awt::XWindow2> xWindow2 (mxBorderPainter, UNO_QUERY);
522 if (xWindow2.is())
523 return xWindow2->isVisible();
524
525 return false;
526 }
527
528
529
530
ThrowIfDisposed(void)531 void PresenterPaneBase::ThrowIfDisposed (void)
532 {
533 if (rBHelper.bDisposed || rBHelper.bInDispose)
534 {
535 throw lang::DisposedException (
536 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
537 "PresenterPane object has already been disposed")),
538 static_cast<uno::XWeak*>(this));
539 }
540 }
541
542
543
544
545 } } // end of namespace ::sd::presenter
546