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