Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "services/taskcreatorsrv.hxx"
30 : :
31 : : #include <helper/persistentwindowstate.hxx>
32 : : #include <helper/tagwindowasmodified.hxx>
33 : : #include <helper/titlebarupdate.hxx>
34 : : #include <threadhelp/readguard.hxx>
35 : : #include <threadhelp/writeguard.hxx>
36 : : #include <loadenv/targethelper.hxx>
37 : : #include <services.h>
38 : :
39 : : #include <com/sun/star/frame/XFrame.hpp>
40 : : #include <com/sun/star/frame/XController.hpp>
41 : : #include <com/sun/star/frame/XModel.hpp>
42 : : #include <com/sun/star/frame/XDesktop.hpp>
43 : : #include <com/sun/star/awt/XTopWindow.hpp>
44 : : #include <com/sun/star/awt/WindowDescriptor.hpp>
45 : : #include <com/sun/star/awt/WindowAttribute.hpp>
46 : : #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
47 : :
48 : : #include <svtools/colorcfg.hxx>
49 : : #include <vcl/svapp.hxx>
50 : :
51 : : #include <toolkit/unohlp.hxx>
52 : : #include <vcl/window.hxx>
53 : :
54 : : //_______________________________________________
55 : : // namespaces
56 : :
57 : : namespace framework
58 : : {
59 : : //-----------------------------------------------
60 [ + + ][ + - ]: 13341 : DEFINE_XINTERFACE_3(TaskCreatorService ,
61 : : OWeakObject ,
62 : : DIRECT_INTERFACE(css::lang::XTypeProvider ),
63 : : DIRECT_INTERFACE(css::lang::XServiceInfo ),
64 : : DIRECT_INTERFACE(css::lang::XSingleServiceFactory))
65 : :
66 : : //-----------------------------------------------
67 [ # # ][ # # ]: 0 : DEFINE_XTYPEPROVIDER_3(TaskCreatorService ,
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
68 : : css::lang::XTypeProvider ,
69 : : css::lang::XServiceInfo ,
70 : : css::lang::XSingleServiceFactory)
71 : :
72 : : //-----------------------------------------------
73 [ + - ][ + - ]: 1069 : DEFINE_XSERVICEINFO_ONEINSTANCESERVICE(TaskCreatorService ,
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ # # ][ # # ]
74 : : ::cppu::OWeakObject ,
75 : : SERVICENAME_TASKCREATOR ,
76 : : IMPLEMENTATIONNAME_FWK_TASKCREATOR)
77 : :
78 : : //-----------------------------------------------
79 : 113 : DEFINE_INIT_SERVICE(
80 : : TaskCreatorService,
81 : : {
82 : : /*Attention
83 : : I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
84 : : to create a new instance of this class by our own supported service factory.
85 : : see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
86 : : */
87 : : }
88 : : )
89 : :
90 : : //-----------------------------------------------
91 : 113 : TaskCreatorService::TaskCreatorService(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
92 [ + - ]: 113 : : ThreadHelpBase (&Application::GetSolarMutex())
93 : : , ::cppu::OWeakObject( )
94 [ + - ]: 226 : , m_xSMGR (xSMGR )
95 : : {
96 : 113 : }
97 : :
98 : : //-----------------------------------------------
99 [ + - ][ + - ]: 113 : TaskCreatorService::~TaskCreatorService()
100 : : {
101 [ - + ]: 226 : }
102 : :
103 : : //-----------------------------------------------
104 : 0 : css::uno::Reference< css::uno::XInterface > SAL_CALL TaskCreatorService::createInstance()
105 : : throw(css::uno::Exception ,
106 : : css::uno::RuntimeException)
107 : : {
108 [ # # ]: 0 : return createInstanceWithArguments(css::uno::Sequence< css::uno::Any >());
109 : : }
110 : :
111 : : //-----------------------------------------------
112 : 1745 : css::uno::Reference< css::uno::XInterface > SAL_CALL TaskCreatorService::createInstanceWithArguments(const css::uno::Sequence< css::uno::Any >& lArguments)
113 : : throw(css::uno::Exception ,
114 : : css::uno::RuntimeException)
115 : : {
116 [ + - ]: 1745 : ::comphelper::SequenceAsHashMap lArgs(lArguments);
117 : :
118 [ + - ]: 1745 : css::uno::Reference< css::frame::XFrame > xParentFrame = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_PARENTFRAME) , css::uno::Reference< css::frame::XFrame >());
119 [ + - ]: 1745 : ::rtl::OUString sFrameName = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_FRAMENAME) , ::rtl::OUString() );
120 [ + - ]: 1745 : sal_Bool bVisible = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_MAKEVISIBLE) , sal_False );
121 [ + - ]: 1745 : sal_Bool bCreateTopWindow = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_CREATETOPWINDOW) , sal_True );
122 : : // only possize=[0,0,0,0] triggers default handling of vcl !
123 [ + - ]: 1745 : css::awt::Rectangle aPosSize = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_POSSIZE) , css::awt::Rectangle(0, 0, 0, 0) );
124 [ + - ]: 1745 : css::uno::Reference< css::awt::XWindow > xContainerWindow = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_CONTAINERWINDOW) , css::uno::Reference< css::awt::XWindow >() );
125 [ + - ]: 1745 : sal_Bool bSupportPersistentWindowState = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_SUPPORTPERSISTENTWINDOWSTATE) , sal_False );
126 [ + - ]: 1745 : sal_Bool bEnableTitleBarUpdate = lArgs.getUnpackedValueOrDefault(rtl::OUString(ARGUMENT_ENABLE_TITLEBARUPDATE) , sal_True );
127 : :
128 : : /* SAFE { */
129 [ + - ]: 1745 : ReadGuard aReadLock( m_aLock );
130 : 1745 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
131 [ + - ]: 1745 : aReadLock.unlock();
132 : : /* } SAFE */
133 : :
134 : : // We use FrameName property to set it as API name of the new created frame later.
135 : : // But those frame names must be different from the set of special target names as e.g. _blank, _self etcpp !
136 [ + - ]: 1745 : ::rtl::OUString sRightName = impl_filterNames(sFrameName);
137 : :
138 : : // if no external frame window was given ... create a new one.
139 [ + + ]: 1745 : if ( ! xContainerWindow.is())
140 : : {
141 : 1743 : css::uno::Reference< css::awt::XWindow > xParentWindow;
142 [ + - ]: 1743 : if (xParentFrame.is())
143 [ + - ][ + - ]: 1743 : xParentWindow = xParentFrame->getContainerWindow();
[ + - ]
144 : :
145 : : // Parent has no own window ...
146 : : // So we have to create a top level window always !
147 [ + - ]: 1743 : if ( ! xParentWindow.is())
148 : 1743 : bCreateTopWindow = sal_True;
149 : :
150 [ + - ][ + - ]: 1743 : xContainerWindow = implts_createContainerWindow(xParentWindow, aPosSize, bCreateTopWindow);
151 : : }
152 : :
153 : : // #i53630#
154 : : // Mark all document windows as "special ones", so VCL can bind
155 : : // special features to it. Because VCL doesnt know anything about documents ...
156 : : // Note: Doing so it's no longer supported, that e.g. our wizards can use findFrame(_blank)
157 : : // to create it's previes frames. They must do it manually by using WindowDescriptor+Toolkit!
158 [ + - ]: 1745 : css::uno::Reference< css::frame::XDesktop > xDesktop(xParentFrame, css::uno::UNO_QUERY);
159 : : ::sal_Bool bTopLevelDocumentWindow = (
160 : 1745 : sRightName.isEmpty() &&
161 : : (
162 : 1745 : (! xParentFrame.is() ) ||
163 : 1745 : ( xDesktop.is() )
164 : : )
165 [ + - + - : 5235 : );
+ + ]
166 [ + + ]: 1745 : if (bTopLevelDocumentWindow)
167 [ + - ]: 1743 : implts_applyDocStyleToWindow(xContainerWindow);
168 : : //------------------->
169 : :
170 : : // create the new frame
171 [ + - ]: 1745 : css::uno::Reference< css::frame::XFrame > xFrame = implts_createFrame(xParentFrame, xContainerWindow, sRightName);
172 : :
173 : : // special freature:
174 : : // A special listener will restore pos/size states in case
175 : : // a component was loaded into the frame first time.
176 [ + + ]: 1745 : if (bSupportPersistentWindowState)
177 [ + - ]: 1743 : implts_establishWindowStateListener(xFrame);
178 : :
179 : : // special feature: On Mac we need tagging the window in case
180 : : // the underlying model was modified.
181 : : // VCL will ignore our calls in case different platform then Mac
182 : : // is used ...
183 [ + + ]: 1745 : if (bTopLevelDocumentWindow)
184 [ + - ]: 1743 : implts_establishDocModifyListener (xFrame);
185 : :
186 : : // special freature:
187 : : // A special listener will update title bar (text and icon)
188 : : // if component of frame will be changed.
189 [ + - ]: 1745 : if (bEnableTitleBarUpdate)
190 [ + - ]: 1745 : implts_establishTitleBarUpdate(xFrame);
191 : :
192 : : // Make it visible directly here ...
193 : : // if its required from outside.
194 [ - + ]: 1745 : if (bVisible)
195 [ # # ][ # # ]: 0 : xContainerWindow->setVisible(bVisible);
196 : :
197 [ + - ][ + - ]: 1745 : return css::uno::Reference< css::uno::XInterface >(xFrame, css::uno::UNO_QUERY_THROW);
[ + - ]
198 : : }
199 : :
200 : : //-----------------------------------------------
201 : 1743 : void TaskCreatorService::implts_applyDocStyleToWindow(const css::uno::Reference< css::awt::XWindow >& xWindow) const
202 : : {
203 : : // SYNCHRONIZED ->
204 [ + - ]: 1743 : SolarMutexGuard aSolarGuard;
205 [ + - ]: 1743 : Window* pVCLWindow = VCLUnoHelper::GetWindow(xWindow);
206 [ + - ]: 1743 : if (pVCLWindow)
207 [ + - ][ + - ]: 1743 : pVCLWindow->SetExtendedStyle(WB_EXT_DOCUMENT);
208 : : // <- SYNCHRONIZED
209 : 1743 : }
210 : :
211 : : //-----------------------------------------------
212 : 1743 : css::uno::Reference< css::awt::XWindow > TaskCreatorService::implts_createContainerWindow( const css::uno::Reference< css::awt::XWindow >& xParentWindow ,
213 : : const css::awt::Rectangle& aPosSize ,
214 : : sal_Bool bTopWindow )
215 : : {
216 : : // SAFE ->
217 [ + - ]: 1743 : ReadGuard aReadLock( m_aLock );
218 : 1743 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
219 [ + - ]: 1743 : aReadLock.unlock();
220 : : // <- SAFE
221 : :
222 : : // get toolkit to create task container window
223 [ + - ][ + - ]: 1743 : css::uno::Reference< css::awt::XToolkit > xToolkit( xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY_THROW);
[ + - ][ + - ]
224 : :
225 : : // Check if child frames can be created realy. We need at least a valid window at the parent frame ...
226 : 1743 : css::uno::Reference< css::awt::XWindowPeer > xParentWindowPeer;
227 [ - + ]: 1743 : if ( ! bTopWindow)
228 : : {
229 [ # # ]: 0 : if ( ! xParentWindow.is())
230 : 0 : bTopWindow = sal_False;
231 : : else
232 [ # # ][ # # ]: 0 : xParentWindowPeer = css::uno::Reference< css::awt::XWindowPeer >(xParentWindow, css::uno::UNO_QUERY_THROW);
233 : : }
234 : :
235 : : // describe window properties.
236 [ + - ]: 1743 : css::awt::WindowDescriptor aDescriptor;
237 [ + - ]: 1743 : if (bTopWindow)
238 : : {
239 : 1743 : aDescriptor.Type = css::awt::WindowClass_TOP ;
240 [ + - ]: 1743 : aDescriptor.WindowServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("window"));
241 : 1743 : aDescriptor.ParentIndex = -1 ;
242 [ + - ]: 1743 : aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >() ;
243 : 1743 : aDescriptor.Bounds = aPosSize ;
244 : : aDescriptor.WindowAttributes = css::awt::WindowAttribute::BORDER |
245 : : css::awt::WindowAttribute::MOVEABLE |
246 : : css::awt::WindowAttribute::SIZEABLE |
247 : : css::awt::WindowAttribute::CLOSEABLE |
248 : 1743 : css::awt::VclWindowPeerAttribute::CLIPCHILDREN ;
249 : : }
250 : : else
251 : : {
252 : 0 : aDescriptor.Type = css::awt::WindowClass_TOP ;
253 [ # # ]: 0 : aDescriptor.WindowServiceName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("dockingwindow"));
254 : 0 : aDescriptor.ParentIndex = 1 ;
255 [ # # ]: 0 : aDescriptor.Parent = xParentWindowPeer ;
256 : 0 : aDescriptor.Bounds = aPosSize ;
257 : 0 : aDescriptor.WindowAttributes = css::awt::VclWindowPeerAttribute::CLIPCHILDREN ;
258 : : }
259 : :
260 : : // create a new blank container window and get access to parent container to append new created task.
261 [ + - ][ + - ]: 1743 : css::uno::Reference< css::awt::XWindowPeer > xPeer = xToolkit->createWindow( aDescriptor );
262 [ + - ]: 1743 : css::uno::Reference< css::awt::XWindow > xWindow ( xPeer, css::uno::UNO_QUERY );
263 [ - + ]: 1743 : if ( ! xWindow.is())
264 : : throw css::uno::Exception(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TaskCreator service was not able to create suitable frame window.")),
265 [ # # ][ # # ]: 0 : static_cast< ::cppu::OWeakObject* >(this));
[ # # ]
266 [ + - ]: 1743 : if (bTopWindow)
267 [ + - ][ + - ]: 1743 : xPeer->setBackground(::svtools::ColorConfig().GetColorValue(::svtools::APPBACKGROUND).nColor);
[ + - ][ + - ]
[ + - ]
268 : : else
269 [ # # ][ # # ]: 0 : xPeer->setBackground(0xffffffff);
270 : :
271 [ + - ][ + - ]: 1743 : return xWindow;
272 : : }
273 : :
274 : : //-----------------------------------------------
275 : 1745 : css::uno::Reference< css::frame::XFrame > TaskCreatorService::implts_createFrame( const css::uno::Reference< css::frame::XFrame >& xParentFrame ,
276 : : const css::uno::Reference< css::awt::XWindow >& xContainerWindow,
277 : : const ::rtl::OUString& sName )
278 : : {
279 : : // SAFE ->
280 [ + - ]: 1745 : ReadGuard aReadLock( m_aLock );
281 : 1745 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
282 [ + - ]: 1745 : aReadLock.unlock();
283 : : // <- SAFE
284 : :
285 : : // create new frame.
286 [ + - ][ + - ]: 1745 : css::uno::Reference< css::frame::XFrame > xNewFrame( xSMGR->createInstance( SERVICENAME_FRAME ), css::uno::UNO_QUERY_THROW );
[ + - ][ + - ]
287 : :
288 : : // Set window on frame.
289 : : // Do it before calling any other interface methods ...
290 : : // The new created frame must be initialized before you can do anything else there.
291 [ + - ][ + - ]: 1745 : xNewFrame->initialize( xContainerWindow );
292 : :
293 : : // Put frame to the frame tree.
294 : : // Note: The property creator/parent will be set on the new putted frame automaticly ... by the parent container.
295 [ + - ]: 1745 : if (xParentFrame.is())
296 : : {
297 [ + - ]: 1745 : css::uno::Reference< css::frame::XFramesSupplier > xSupplier (xParentFrame, css::uno::UNO_QUERY_THROW);
298 [ + - ][ + - ]: 1745 : css::uno::Reference< css::frame::XFrames > xContainer = xSupplier->getFrames();
299 [ + - ][ + - ]: 1745 : xContainer->append( xNewFrame );
300 : : }
301 : :
302 : : // Set it's API name (if there is one from outside)
303 [ - + ]: 1745 : if (!sName.isEmpty())
304 [ # # ][ # # ]: 0 : xNewFrame->setName( sName );
305 : :
306 [ + - ]: 1745 : return xNewFrame;
307 : : }
308 : :
309 : : //-----------------------------------------------
310 : 1743 : void TaskCreatorService::implts_establishWindowStateListener( const css::uno::Reference< css::frame::XFrame >& xFrame )
311 : : {
312 : : // SAFE ->
313 [ + - ]: 1743 : ReadGuard aReadLock( m_aLock );
314 : 1743 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
315 [ + - ]: 1743 : aReadLock.unlock();
316 : : // <- SAFE
317 : :
318 : : // Special feature: It's allowed for frames using a top level window only!
319 : : // We must create a special listener service and couple it with the new created task frame.
320 : : // He will restore or save the window state of it ...
321 : : // See used classes for further informations too.
322 [ + - ]: 1743 : PersistentWindowState* pPersistentStateHandler = new PersistentWindowState(xSMGR);
323 [ + - ][ + - ]: 1743 : css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pPersistentStateHandler), css::uno::UNO_QUERY_THROW);
324 : :
325 [ + - ]: 1743 : css::uno::Sequence< css::uno::Any > lInitData(1);
326 [ + - ][ + - ]: 1743 : lInitData[0] <<= xFrame;
327 [ + - ][ + - ]: 1743 : xInit->initialize(lInitData);
[ + - ][ + - ]
328 : 1743 : }
329 : :
330 : : //-----------------------------------------------
331 : 1743 : void TaskCreatorService::implts_establishDocModifyListener( const css::uno::Reference< css::frame::XFrame >& xFrame )
332 : : {
333 : : // SAFE ->
334 [ + - ]: 1743 : ReadGuard aReadLock( m_aLock );
335 : 1743 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
336 [ + - ]: 1743 : aReadLock.unlock();
337 : : // <- SAFE
338 : :
339 : : // Special feature: It's allowed for frames using a top level window only!
340 : : // We must create a special listener service and couple it with the new created task frame.
341 : : // It will tag the window as modified if the underlying model was modified ...
342 [ + - ]: 1743 : TagWindowAsModified* pTag = new TagWindowAsModified(xSMGR);
343 [ + - ][ + - ]: 1743 : css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pTag), css::uno::UNO_QUERY_THROW);
344 : :
345 [ + - ]: 1743 : css::uno::Sequence< css::uno::Any > lInitData(1);
346 [ + - ][ + - ]: 1743 : lInitData[0] <<= xFrame;
347 [ + - ][ + - ]: 1743 : xInit->initialize(lInitData);
[ + - ][ + - ]
348 : 1743 : }
349 : :
350 : : //-----------------------------------------------
351 : 1745 : void TaskCreatorService::implts_establishTitleBarUpdate( const css::uno::Reference< css::frame::XFrame >& xFrame )
352 : : {
353 : : // SAFE ->
354 [ + - ]: 1745 : ReadGuard aReadLock( m_aLock );
355 : 1745 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
356 [ + - ]: 1745 : aReadLock.unlock();
357 : : // <- SAFE
358 : :
359 [ + - ]: 1745 : TitleBarUpdate* pHelper = new TitleBarUpdate (xSMGR);
360 [ + - ][ + - ]: 1745 : css::uno::Reference< css::lang::XInitialization > xInit(static_cast< ::cppu::OWeakObject* >(pHelper), css::uno::UNO_QUERY_THROW);
361 : :
362 [ + - ]: 1745 : css::uno::Sequence< css::uno::Any > lInitData(1);
363 [ + - ][ + - ]: 1745 : lInitData[0] <<= xFrame;
364 [ + - ][ + - ]: 1745 : xInit->initialize(lInitData);
[ + - ][ + - ]
365 : 1745 : }
366 : :
367 : : //-----------------------------------------------
368 : 1745 : ::rtl::OUString TaskCreatorService::impl_filterNames( const ::rtl::OUString& sName )
369 : : {
370 : 1745 : ::rtl::OUString sFiltered;
371 [ + + ][ + - ]: 1745 : if (TargetHelper::isValidNameForFrame(sName))
372 : 2 : sFiltered = sName;
373 : 1745 : return sFiltered;
374 : : }
375 : :
376 : : } // namespace framework
377 : :
378 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|