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 #include "precompiled_sd.hxx"
29 
30 #include "FullScreenPane.hxx"
31 #include "ViewShellBase.hxx"
32 #include <cppcanvas/vclfactory.hxx>
33 #include <sfx2/dispatch.hxx>
34 #include <vcl/wrkwin.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/dialog.hxx>
37 #include <toolkit/helper/vclunohelper.hxx>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/frame/XLayoutManager.hpp>
40 #include <com/sun/star/lang/IllegalArgumentException.hpp>
41 #include <com/sun/star/lang/XInitialization.hpp>
42 #include <com/sun/star/util/URL.hpp>
43 
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::drawing::framework;
47 using ::rtl::OUString;
48 
49 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
50 
51 namespace sd { namespace framework {
52 
53 FullScreenPane::FullScreenPane (
54     const Reference<XComponentContext>& rxComponentContext,
55     const Reference<XResourceId>& rxPaneId,
56     const ::Window* pViewShellWindow)
57     : FrameWindowPane(rxPaneId,NULL),
58       mxComponentContext(rxComponentContext),
59       mpWorkWindow(NULL)
60 {
61     ::Window* pParent = NULL;
62     mpWorkWindow.reset(new WorkWindow(
63         pParent,
64         0));  // For debugging (non-fullscreen) use WB_BORDER | WB_MOVEABLE | WB_SIZEABLE));
65 
66     if ( ! rxPaneId.is())
67         throw lang::IllegalArgumentException();
68 
69     sal_Int32 nScreenNumber = 1;
70     ExtractArguments(rxPaneId, nScreenNumber);
71 
72     if (mpWorkWindow.get() == NULL)
73         return;
74 
75     // Create a new top-leve window that is displayed full screen.
76     mpWorkWindow->ShowFullScreenMode(sal_True, nScreenNumber);
77     // For debugging (non-fullscreen) use mpWorkWindow->SetScreenNumber(nScreenNumber);
78     mpWorkWindow->SetMenuBarMode(MENUBAR_MODE_HIDE);
79     mpWorkWindow->SetBorderStyle(WINDOW_BORDER_REMOVEBORDER);
80     mpWorkWindow->SetBackground(Wallpaper());
81     // Don't show the window right now in order to allow the setting of an
82     // accessibility object: accessibility objects are typically
83     // requested by AT-tools when the window is shown.  Chaning it
84     // afterwards may or may not work.
85 
86     // Add resize listener at the work window.
87     Link aWindowEventHandler (LINK(this, FullScreenPane, WindowEventHandler));
88     mpWorkWindow->AddEventListener(aWindowEventHandler);
89 
90     // Set title and icon of the new window to those of the current window
91     // of the view shell.
92     if (pViewShellWindow != NULL)
93     {
94         const SystemWindow* pSystemWindow = pViewShellWindow->GetSystemWindow();
95         mpWorkWindow->SetText(pSystemWindow->GetText());
96         mpWorkWindow->SetIcon(pSystemWindow->GetIcon());
97     }
98 
99     // For some reason the VCL canvas can not paint into a WorkWindow.
100     // Therefore a child window is created that covers the WorkWindow
101     // completely.
102     mpWindow = new ::Window(mpWorkWindow.get());
103     mpWindow->SetPosSizePixel(Point(0,0), mpWorkWindow->GetSizePixel());
104     mpWindow->SetBackground(Wallpaper());
105     mxWindow = VCLUnoHelper::GetInterface(mpWindow);
106 
107     // Create the canvas.
108     mxCanvas = CreateCanvas();
109 
110     mpWindow->GrabFocus();
111 }
112 
113 
114 
115 
116 FullScreenPane::~FullScreenPane (void) throw()
117 {
118 }
119 
120 
121 
122 
123 void SAL_CALL FullScreenPane::disposing (void)
124 {
125     // We have created the window pointed to by mpWindow, we delete it.
126     if (mpWindow != NULL)
127     {
128         delete mpWindow;
129     }
130 
131     if (mpWorkWindow.get() != NULL)
132     {
133         Link aWindowEventHandler (LINK(this, FullScreenPane, WindowEventHandler));
134         mpWorkWindow->RemoveEventListener(aWindowEventHandler);
135         mpWorkWindow.reset();
136     }
137 
138 
139     FrameWindowPane::disposing();
140 }
141 
142 
143 
144 
145 //----- XPane -----------------------------------------------------------------
146 
147 sal_Bool SAL_CALL FullScreenPane::isVisible (void)
148     throw (RuntimeException)
149 {
150     ThrowIfDisposed();
151 
152     if (mpWindow != NULL)
153         return mpWindow->IsReallyVisible();
154     else
155         return false;
156 }
157 
158 
159 
160 
161 void SAL_CALL FullScreenPane::setVisible (const sal_Bool bIsVisible)
162     throw (RuntimeException)
163 {
164     ThrowIfDisposed();
165 
166     if (mpWindow != NULL)
167         mpWindow->Show(bIsVisible);
168     if (mpWorkWindow != NULL)
169         mpWorkWindow->Show(bIsVisible);
170 }
171 
172 
173 
174 
175 Reference<accessibility::XAccessible> SAL_CALL FullScreenPane::getAccessible (void)
176     throw (RuntimeException)
177 {
178     ThrowIfDisposed();
179 
180     if (mpWorkWindow != NULL)
181         return mpWorkWindow->GetAccessible(sal_False);
182     else
183         return NULL;
184 }
185 
186 
187 
188 
189 void SAL_CALL FullScreenPane::setAccessible (
190     const Reference<accessibility::XAccessible>& rxAccessible)
191     throw (RuntimeException)
192 {
193     ThrowIfDisposed();
194 
195     if (mpWindow != NULL)
196     {
197         Reference<lang::XInitialization> xInitializable (rxAccessible, UNO_QUERY);
198         if (xInitializable.is())
199         {
200             ::Window* pParentWindow = mpWindow->GetParent();
201             Reference<accessibility::XAccessible> xAccessibleParent;
202             if (pParentWindow != NULL)
203                 xAccessibleParent = pParentWindow->GetAccessible();
204             Sequence<Any> aArguments (1);
205             aArguments[0] = Any(xAccessibleParent);
206             xInitializable->initialize(aArguments);
207         }
208         GetWindow()->SetAccessible(rxAccessible);
209     }
210 }
211 
212 
213 
214 
215 //-----------------------------------------------------------------------------
216 
217 IMPL_LINK(FullScreenPane, WindowEventHandler, VclWindowEvent*, pEvent)
218 {
219 	switch (pEvent->GetId())
220     {
221         case VCLEVENT_WINDOW_RESIZE:
222             GetWindow()->SetPosPixel(Point(0,0));
223             GetWindow()->SetSizePixel(Size(
224                 mpWorkWindow->GetSizePixel().Width(),
225                 mpWorkWindow->GetSizePixel().Height()));
226             break;
227 
228         case VCLEVENT_OBJECT_DYING:
229             mpWorkWindow.reset();
230             break;
231     }
232     return 1;
233 }
234 
235 
236 
237 
238 Reference<rendering::XCanvas> FullScreenPane::CreateCanvas (void)
239     throw (RuntimeException)
240 {
241     ::Window* pWindow = VCLUnoHelper::GetWindow(mxWindow);
242     if (pWindow != NULL)
243     {
244         Sequence<Any> aArg (5);
245 
246         // common: first any is VCL pointer to window (for VCL canvas)
247         aArg[0] = makeAny(reinterpret_cast<sal_Int64>(pWindow));
248         aArg[1] = Any();
249         aArg[2] = makeAny(::com::sun::star::awt::Rectangle());
250         aArg[3] = makeAny(sal_False);
251         aArg[4] = makeAny(mxWindow);
252 
253         Reference<lang::XMultiServiceFactory> xFactory (
254             mxComponentContext->getServiceManager(), UNO_QUERY_THROW);
255         return Reference<rendering::XCanvas>(
256             xFactory->createInstanceWithArguments(
257                 OUString::createFromAscii("com.sun.star.rendering.SpriteCanvas.VCL"),
258                 aArg),
259             UNO_QUERY);
260     }
261     else
262         throw RuntimeException();
263 }
264 
265 
266 
267 
268 void FullScreenPane::ExtractArguments (
269     const Reference<XResourceId>& rxPaneId,
270     sal_Int32& rnScreenNumberReturnValue)
271 {
272     // Extract arguments from the resource URL.
273     const util::URL aURL = rxPaneId->getFullResourceURL();
274     sal_Int32 nIndex = 0;
275     while (nIndex >= 0)
276     {
277         const OUString aToken = aURL.Arguments.getToken(0, '&', nIndex);
278         if (aToken.getLength() > 0)
279         {
280             // Split at the first '='.
281             const sal_Int32 nAssign = aToken.indexOf('=');
282             const OUString sKey = aToken.copy(0, nAssign);
283             const OUString sValue = aToken.copy(nAssign+1);
284 
285             if (sKey.compareToAscii("ScreenNumber") == 0)
286             {
287                 rnScreenNumberReturnValue = sValue.toInt32();
288             }
289         }
290     }
291 }
292 
293 
294 } } // end of namespace sd::framework
295