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