Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <dispatch/dispatchprovider.hxx>
21 : #include <dispatch/interceptionhelper.hxx>
22 : #include <dispatch/closedispatcher.hxx>
23 : #include <dispatch/windowcommanddispatch.hxx>
24 : #include <loadenv/loadenv.hxx>
25 : #include <helper/oframes.hxx>
26 : #include <framework/titlehelper.hxx>
27 : #include <svtools/openfiledroptargetlistener.hxx>
28 : #include <classes/taskcreator.hxx>
29 : #include <loadenv/targethelper.hxx>
30 : #include <framework/framelistanalyzer.hxx>
31 : #include <helper/dockingareadefaultacceptor.hxx>
32 : #include <dispatch/dispatchinformationprovider.hxx>
33 : #include <classes/framecontainer.hxx>
34 : #include <classes/propertysethelper.hxx>
35 : #include <threadhelp/transactionguard.hxx>
36 : #include <threadhelp/transactionbase.hxx>
37 : #include <general.h>
38 :
39 : #include <pattern/window.hxx>
40 : #include <properties.h>
41 :
42 : #include <com/sun/star/awt/Toolkit.hpp>
43 : #include <com/sun/star/awt/XDevice.hpp>
44 : #include <com/sun/star/awt/XTopWindow.hpp>
45 : #include <com/sun/star/awt/PosSize.hpp>
46 : #include <com/sun/star/beans/PropertyAttribute.hpp>
47 : #include <com/sun/star/beans/PropertyValue.hpp>
48 : #include <com/sun/star/beans/XPropertySet.hpp>
49 : #include <com/sun/star/container/XIndexAccess.hpp>
50 : #include <com/sun/star/datatransfer/dnd/XDropTarget.hpp>
51 : #include <com/sun/star/frame/XFrame2.hpp>
52 : #include <com/sun/star/frame/XModel.hpp>
53 : #include <com/sun/star/frame/XTitleChangeBroadcaster.hpp>
54 : #include <com/sun/star/frame/LayoutManager.hpp>
55 : #include <com/sun/star/frame/XDesktop.hpp>
56 : #include <com/sun/star/frame/FrameSearchFlag.hpp>
57 : #include <com/sun/star/lang/DisposedException.hpp>
58 : #include <com/sun/star/task/StatusIndicatorFactory.hpp>
59 : #include <com/sun/star/task/theJobExecutor.hpp>
60 : #include <com/sun/star/task/XJobExecutor.hpp>
61 : #include <com/sun/star/util/URLTransformer.hpp>
62 : #include <com/sun/star/util/XURLTransformer.hpp>
63 : #include <com/sun/star/util/XCloseable.hpp>
64 : #include <com/sun/star/lang/XServiceInfo.hpp>
65 :
66 : #include <comphelper/sequenceashashmap.hxx>
67 : #include <cppuhelper/basemutex.hxx>
68 : #include <cppuhelper/queryinterface.hxx>
69 : #include <cppuhelper/typeprovider.hxx>
70 : #include <cppuhelper/factory.hxx>
71 : #include <cppuhelper/proptypehlp.hxx>
72 : #include <cppuhelper/interfacecontainer.hxx>
73 : #include <cppuhelper/supportsservice.hxx>
74 : #include <cppuhelper/weak.hxx>
75 : #include <rtl/ref.hxx>
76 : #include <rtl/ustrbuf.hxx>
77 : #include <vcl/window.hxx>
78 : #include <vcl/wrkwin.hxx>
79 : #include <vcl/svapp.hxx>
80 :
81 : #include <toolkit/helper/vclunohelper.hxx>
82 : #include <toolkit/awt/vclxwindow.hxx>
83 : #include <comphelper/processfactory.hxx>
84 : #include <unotools/moduleoptions.hxx>
85 : #include <tools/diagnose_ex.h>
86 : #include <vcl/menu.hxx>
87 : #include <unotools/cmdoptions.hxx>
88 :
89 : using namespace framework;
90 :
91 : namespace {
92 :
93 : // This enum can be used to set different active states of frames
94 : enum EActiveState
95 : {
96 : E_INACTIVE , // I'am not a member of active path in tree and i don't have the focus.
97 : E_ACTIVE , // I'am in the middle of an active path in tree and i don't have the focus.
98 : E_FOCUS // I have the focus now. I must a member of an active path!
99 : };
100 :
101 : /*-************************************************************************************************************
102 : @short implements a normal frame of hierarchy
103 : @descr An instance of these class can be a normal node in frame tree. A frame support influencing of his
104 : subtree, find of subframes, activate- and deactivate-mechanism as well as
105 : set/get of a frame window, component or controller.
106 :
107 : @attention This implementation supports three states: a)uninitialized, b)working, c)disposed
108 : If you call wrong methods in modes a) or c) ... you will get some exceptions.
109 : How you should work with this service:
110 : i) create it by using "xServiceManager->createInstance(...)"
111 : ii) call XInitialization::initialize() with a valid window reference or use createInstanceWithArguments() at i)
112 : iii) works with object
113 : iv) dispose object by calling XComponent::dispose()
114 : After iv) all further requests are rejected by exceptions! (DisposedException)
115 :
116 : @base TransactionBase
117 : help to implement unbreakable interface calls
118 : @base OBroadcastHelper
119 : OPropertySetHelper
120 : implements the property set
121 : @base OWeakObject
122 : provides the refcount and XInterface, XWeak
123 :
124 : @devstatus ready to use
125 : @threadsafe yes
126 : *//*-*************************************************************************************************************/
127 : class Frame : // interfaces
128 : public css::lang::XTypeProvider ,
129 : public css::lang::XServiceInfo ,
130 : public css::frame::XFrame2 ,
131 : public css::awt::XWindowListener , // => XEventListener
132 : public css::awt::XTopWindowListener ,
133 : public css::awt::XFocusListener ,
134 : public css::document::XActionLockable ,
135 : public css::util::XCloseable , // => XCloseBroadcaster
136 : public css::frame::XComponentLoader ,
137 : public css::frame::XTitle ,
138 : public css::frame::XTitleChangeBroadcaster ,
139 : // base classes
140 : public TransactionBase ,
141 : private cppu::BaseMutex,
142 : public PropertySetHelper , // helper implements TransactionBase, XPropertySet, XPropertySetInfo
143 : public ::cppu::OWeakObject // helper implements XInterface, XWeak
144 : {
145 : public:
146 :
147 : Frame( const css::uno::Reference< css::uno::XComponentContext >& xContext );
148 : virtual ~Frame();
149 :
150 : /// Initialization function after having acquire()'d.
151 : void initListeners();
152 :
153 : FWK_DECLARE_XINTERFACE
154 : FWK_DECLARE_XTYPEPROVIDER
155 :
156 0 : virtual OUString SAL_CALL getImplementationName()
157 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
158 : {
159 0 : return OUString("com.sun.star.comp.framework.Frame");
160 : }
161 :
162 0 : virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
163 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
164 : {
165 0 : return cppu::supportsService(this, ServiceName);
166 : }
167 :
168 0 : virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
169 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
170 : {
171 0 : css::uno::Sequence< OUString > aSeq(1);
172 0 : aSeq[0] = OUString("com.sun.star.frame.Frame");
173 0 : return aSeq;
174 : }
175 :
176 : // XComponentLoader
177 :
178 : virtual css::uno::Reference< css::lang::XComponent > SAL_CALL loadComponentFromURL(
179 : const OUString& sURL,
180 : const OUString& sTargetFrameName,
181 : sal_Int32 nSearchFlags,
182 : const css::uno::Sequence< css::beans::PropertyValue >& lArguments )
183 : throw( css::io::IOException,
184 : css::lang::IllegalArgumentException,
185 : css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
186 :
187 : // XFramesSupplier
188 :
189 : virtual css::uno::Reference< css::frame::XFrames > SAL_CALL getFrames ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
190 : virtual css::uno::Reference< css::frame::XFrame > SAL_CALL getActiveFrame ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
191 : virtual void SAL_CALL setActiveFrame ( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
192 :
193 : // XFrame
194 :
195 : virtual void SAL_CALL initialize ( const css::uno::Reference< css::awt::XWindow >& xWindow ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
196 : virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getContainerWindow ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
197 : virtual void SAL_CALL setCreator ( const css::uno::Reference< css::frame::XFramesSupplier >& xCreator ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
198 : virtual css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL getCreator ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
199 : virtual OUString SAL_CALL getName ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
200 : virtual void SAL_CALL setName ( const OUString& sName ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
201 : virtual css::uno::Reference< css::frame::XFrame > SAL_CALL findFrame ( const OUString& sTargetFrameName ,
202 : sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
203 : virtual sal_Bool SAL_CALL isTop ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
204 : virtual void SAL_CALL activate ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
205 : virtual void SAL_CALL deactivate ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
206 : virtual sal_Bool SAL_CALL isActive ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
207 : virtual void SAL_CALL contextChanged ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
208 : virtual sal_Bool SAL_CALL setComponent ( const css::uno::Reference< css::awt::XWindow >& xComponentWindow ,
209 : const css::uno::Reference< css::frame::XController >& xController ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
210 : virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getComponentWindow ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
211 : virtual css::uno::Reference< css::frame::XController > SAL_CALL getController ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
212 : virtual void SAL_CALL addFrameActionListener ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
213 : virtual void SAL_CALL removeFrameActionListener ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
214 :
215 : // XComponent
216 :
217 : virtual void SAL_CALL dispose ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
218 : virtual void SAL_CALL addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
219 : virtual void SAL_CALL removeEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
220 :
221 : // XStatusIndicatorFactory
222 :
223 : virtual css::uno::Reference< css::task::XStatusIndicator > SAL_CALL createStatusIndicator ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
224 :
225 : // XDispatchProvider
226 :
227 : virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch ( const css::util::URL& aURL ,
228 : const OUString& sTargetFrameName ,
229 : sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
230 : virtual css::uno::Sequence<
231 : css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches ( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
232 :
233 : // XDispatchProviderInterception
234 :
235 : virtual void SAL_CALL registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
236 : virtual void SAL_CALL releaseDispatchProviderInterceptor ( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
237 :
238 : // XDispatchInformationProvider
239 :
240 : virtual css::uno::Sequence< sal_Int16 > SAL_CALL getSupportedCommandGroups ( ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
241 : virtual css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL getConfigurableDispatchInformation(sal_Int16 nCommandGroup) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
242 :
243 : // XWindowListener
244 : // Attention: windowResized() and windowShown() are implement only! All other are empty!
245 :
246 : virtual void SAL_CALL windowResized ( const css::awt::WindowEvent& aEvent ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
247 11022 : virtual void SAL_CALL windowMoved ( const css::awt::WindowEvent& /*aEvent*/ ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE {};
248 : virtual void SAL_CALL windowShown ( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
249 : virtual void SAL_CALL windowHidden ( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
250 :
251 : // XFocusListener
252 : // Attention: focusLost() not implemented yet!
253 :
254 : virtual void SAL_CALL focusGained ( const css::awt::FocusEvent& aEvent ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
255 1190 : virtual void SAL_CALL focusLost ( const css::awt::FocusEvent& /*aEvent*/ ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE {};
256 :
257 : // XTopWindowListener
258 : // Attention: windowActivated(), windowDeactivated() and windowClosing() are implement only! All other are empty!
259 :
260 : virtual void SAL_CALL windowActivated ( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
261 : virtual void SAL_CALL windowDeactivated ( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
262 10980 : virtual void SAL_CALL windowOpened ( const css::lang::EventObject& /*aEvent*/ ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE {};
263 : virtual void SAL_CALL windowClosing ( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
264 10 : virtual void SAL_CALL windowClosed ( const css::lang::EventObject& /*aEvent*/ ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE {};
265 0 : virtual void SAL_CALL windowMinimized ( const css::lang::EventObject& /*aEvent*/ ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE {};
266 0 : virtual void SAL_CALL windowNormalized ( const css::lang::EventObject& /*aEvent*/ ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE {};
267 :
268 : // XEventListener
269 :
270 : virtual void SAL_CALL disposing ( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
271 :
272 : // XActionLockable
273 :
274 : virtual sal_Bool SAL_CALL isActionLocked ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
275 : virtual void SAL_CALL addActionLock ( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
276 : virtual void SAL_CALL removeActionLock( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
277 : virtual void SAL_CALL setActionLocks ( sal_Int16 nLock ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
278 : virtual sal_Int16 SAL_CALL resetActionLocks( ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
279 :
280 : // XCloseable
281 :
282 : virtual void SAL_CALL close( sal_Bool bDeliverOwnership ) throw( css::util::CloseVetoException,
283 : css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
284 :
285 : // XCloseBroadcaster
286 :
287 : virtual void SAL_CALL addCloseListener ( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
288 : virtual void SAL_CALL removeCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
289 :
290 : // XTitle
291 :
292 : virtual OUString SAL_CALL getTitle( ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
293 : virtual void SAL_CALL setTitle( const OUString& sTitle ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
294 :
295 : // XTitleChangeBroadcaster
296 :
297 : virtual void SAL_CALL addTitleChangeListener ( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
298 : virtual void SAL_CALL removeTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListenr ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
299 :
300 : // XFrame2 attributes
301 :
302 : virtual css::uno::Reference<css::container::XNameContainer> SAL_CALL getUserDefinedAttributes() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
303 :
304 : virtual css::uno::Reference<css::frame::XDispatchRecorderSupplier> SAL_CALL getDispatchRecorderSupplier() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
305 : virtual void SAL_CALL setDispatchRecorderSupplier(const css::uno::Reference<css::frame::XDispatchRecorderSupplier>&) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
306 :
307 : virtual css::uno::Reference<css::uno::XInterface> SAL_CALL getLayoutManager() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
308 : virtual void SAL_CALL setLayoutManager(const css::uno::Reference<css::uno::XInterface>&) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
309 :
310 : // PropertySetHelper => XPropertySet, XPropertySetInfo
311 :
312 : private:
313 :
314 : void impl_initializePropInfo();
315 :
316 : virtual void SAL_CALL impl_setPropertyValue(const OUString& sProperty,
317 : sal_Int32 nHandle ,
318 : const css::uno::Any& aValue ) SAL_OVERRIDE;
319 :
320 : virtual css::uno::Any SAL_CALL impl_getPropertyValue(const OUString& sProperty,
321 : sal_Int32 nHandle ) SAL_OVERRIDE;
322 :
323 :
324 : private:
325 :
326 : /*-****************************************************************************************************
327 : @short helper methods
328 : @descr Follow methods are needed at different points of our code (more than ones!).
329 :
330 : @attention Threadsafe methods are signed by "implts_..."!
331 : *//*-*****************************************************************************************************/
332 :
333 : // threadsafe
334 : void implts_sendFrameActionEvent ( const css::frame::FrameAction& aAction );
335 : void implts_resizeComponentWindow ( );
336 : void implts_setIconOnWindow ( );
337 : void implts_startWindowListening ( );
338 : void implts_stopWindowListening ( );
339 : void implts_checkSuicide ( );
340 : void implts_forgetSubFrames ( );
341 :
342 : // non threadsafe
343 : void impl_checkMenuCloser ( );
344 : void impl_setCloser ( const css::uno::Reference< css::frame::XFrame2 >& xFrame , bool bState );
345 : void impl_disposeContainerWindow ( css::uno::Reference< css::awt::XWindow >& xWindow );
346 :
347 : // debug methods
348 : // (should be private everyway!)
349 :
350 : /*-****************************************************************************************************
351 : @short debug-method to check incoming parameter of some other mehods of this class
352 : @descr The following methods are used to check parameters for other methods
353 : of this class. The return value is used directly for an ASSERT(...).
354 :
355 : @attention This methods are static and can't use our member directly! It's better for threadsafe code...
356 : because we call it with references or pointer to check variables ... and must make it safe
357 : by himself!
358 :
359 : @seealso ASSERTs in implementation!
360 :
361 : @param references to checking variables
362 : @return sal_True ,on invalid parameter
363 : @return sal_False ,otherwise
364 :
365 : @onerror We return sal_True
366 : *//*-*****************************************************************************************************/
367 :
368 : private:
369 :
370 : static bool implcp_setActiveFrame ( const css::uno::Reference< css::frame::XFrame >& xFrame );
371 : static bool implcp_addFrameActionListener ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener );
372 : static bool implcp_removeFrameActionListener ( const css::uno::Reference< css::frame::XFrameActionListener >& xListener );
373 : static bool implcp_addEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener );
374 : static bool implcp_removeEventListener ( const css::uno::Reference< css::lang::XEventListener >& xListener );
375 : static bool implcp_windowResized ( const css::awt::WindowEvent& aEvent );
376 : static bool implcp_focusGained ( const css::awt::FocusEvent& aEvent );
377 : static bool implcp_windowActivated ( const css::lang::EventObject& aEvent );
378 : static bool implcp_windowDeactivated ( const css::lang::EventObject& aEvent );
379 : static bool implcp_disposing ( const css::lang::EventObject& aEvent );
380 :
381 : // variables
382 : // -threadsafe by SolarMutex
383 :
384 : private:
385 :
386 : css::uno::Reference< css::uno::XComponentContext > m_xContext; /// reference to factory, which has create this instance
387 : css::uno::Reference< css::task::XStatusIndicatorFactory > m_xIndicatorFactoryHelper; /// reference to factory helper to create status indicator objects
388 : css::uno::WeakReference< css::task::XStatusIndicator > m_xIndicatorInterception; /// points to an external set progress, which should be used instead of the internal one.
389 : css::uno::Reference< css::frame::XDispatchProvider > m_xDispatchHelper; /// helper for XDispatch/Provider and interception interfaces
390 : css::uno::Reference< css::frame::XFrames > m_xFramesHelper; /// helper for XFrames, XIndexAccess and XElementAccess interfaces
391 : ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer; /// container for ALL Listener
392 : css::uno::Reference< css::frame::XFramesSupplier > m_xParent; /// parent of this frame
393 : css::uno::Reference< css::awt::XWindow > m_xContainerWindow; /// containerwindow of this frame for embedded components
394 : css::uno::Reference< css::awt::XWindow > m_xComponentWindow; /// window of the actual component
395 : css::uno::Reference< css::frame::XController > m_xController; /// controller of the actual frame
396 : css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > m_xDropTargetListener; /// listen to drag & drop
397 : EActiveState m_eActiveState; /// state, if i'am a member of active path in tree or i have the focus or ...
398 : OUString m_sName; /// name of this frame
399 : bool m_bIsFrameTop; /// frame has no parent or the parent is a taskor the desktop
400 : bool m_bConnected; /// due to FrameActionEvent
401 : sal_Int16 m_nExternalLockCount;
402 : css::uno::Reference< css::frame::XDispatchRecorderSupplier > m_xDispatchRecorderSupplier; /// is used for dispatch recording and will be set/get from outside. Frame provide it only!
403 : SvtCommandOptions m_aCommandOptions; /// ref counted class to support disabling commands defined by configuration file
404 : bool m_bSelfClose; /// in case of CloseVetoException on method close() wqs thrown by ourself - we must close ourself later if no internal processes are running
405 : bool m_bIsHidden; /// indicates, if this frame is used in hidden mode or not
406 : static css::uno::WeakReference< css::frame::XFrame2 > m_xCloserFrame; /// holds the only frame, which must show the special closer menu item (can be NULL!)
407 : css::uno::Reference< css::frame::XLayoutManager2 > m_xLayoutManager; /// is used to layout the child windows of the frame.
408 : css::uno::Reference< css::frame::XDispatchInformationProvider > m_xDispatchInfoHelper;
409 : css::uno::Reference< css::frame::XTitle > m_xTitleHelper;
410 :
411 : WindowCommandDispatch* m_pWindowCommandDispatch;
412 :
413 : protected:
414 :
415 : FrameContainer m_aChildFrameContainer; /// array of child frames
416 : };
417 :
418 317 : css::uno::WeakReference< css::frame::XFrame2 > Frame::m_xCloserFrame = css::uno::WeakReference< css::frame::XFrame2 >();
419 :
420 : // XInterface, XTypeProvider, XServiceInfo
421 :
422 22185848 : DEFINE_XINTERFACE_22 ( Frame ,
423 : OWeakObject ,
424 : DIRECT_INTERFACE(css::lang::XTypeProvider ),
425 : DIRECT_INTERFACE(css::lang::XServiceInfo ),
426 : DIRECT_INTERFACE(css::frame::XFrame2 ),
427 : DIRECT_INTERFACE(css::frame::XFramesSupplier ),
428 : DIRECT_INTERFACE(css::frame::XFrame ),
429 : DIRECT_INTERFACE(css::task::XStatusIndicatorFactory ),
430 : DIRECT_INTERFACE(css::frame::XDispatchProvider ),
431 : DIRECT_INTERFACE(css::frame::XDispatchInformationProvider ),
432 : DIRECT_INTERFACE(css::frame::XDispatchProviderInterception ),
433 : DIRECT_INTERFACE(css::lang::XComponent ),
434 : DIRECT_INTERFACE(css::beans::XPropertySet ),
435 : DIRECT_INTERFACE(css::beans::XPropertySetInfo ),
436 : DIRECT_INTERFACE(css::awt::XWindowListener ),
437 : DIRECT_INTERFACE(css::awt::XTopWindowListener ),
438 : DIRECT_INTERFACE(css::awt::XFocusListener ),
439 : DERIVED_INTERFACE(css::lang::XEventListener, css::awt::XWindowListener ),
440 : DIRECT_INTERFACE(css::document::XActionLockable ),
441 : DIRECT_INTERFACE(css::util::XCloseable ),
442 : DIRECT_INTERFACE(css::util::XCloseBroadcaster ),
443 : DIRECT_INTERFACE(css::frame::XComponentLoader ),
444 : DIRECT_INTERFACE(css::frame::XTitle ),
445 : DIRECT_INTERFACE(css::frame::XTitleChangeBroadcaster )
446 : )
447 :
448 4 : DEFINE_XTYPEPROVIDER_21 ( Frame ,
449 : css::lang::XTypeProvider ,
450 : css::lang::XServiceInfo ,
451 : css::frame::XFrame2 ,
452 : css::frame::XFramesSupplier ,
453 : css::frame::XFrame ,
454 : css::task::XStatusIndicatorFactory ,
455 : css::frame::XDispatchProvider ,
456 : css::frame::XDispatchInformationProvider ,
457 : css::frame::XDispatchProviderInterception ,
458 : css::lang::XComponent ,
459 : css::beans::XPropertySet ,
460 : css::beans::XPropertySetInfo ,
461 : css::awt::XWindowListener ,
462 : css::awt::XTopWindowListener ,
463 : css::awt::XFocusListener ,
464 : css::lang::XEventListener ,
465 : css::util::XCloseable ,
466 : css::util::XCloseBroadcaster ,
467 : css::frame::XComponentLoader ,
468 : css::frame::XTitle ,
469 : css::frame::XTitleChangeBroadcaster
470 : )
471 :
472 : /*-****************************************************************************************************
473 : @short standard constructor to create instance by factory
474 : @descr This constructor initialize a new instance of this class by valid factory,
475 : and will be set valid values on his member and baseclasses.
476 :
477 : @attention a) Don't use your own reference during an UNO-Service-ctor! There is no guarantee, that you
478 : will get over this. (e.g. using of your reference as parameter to initialize some member)
479 : Do such things in DEFINE_INIT_SERVICE() method, which is called automatically after your ctor!!!
480 : b) Baseclass OBroadcastHelper is a typedef in namespace cppu!
481 : The microsoft compiler has some problems to handle it right BY using namespace explicitly ::cppu::OBroadcastHelper.
482 : If we write it without a namespace or expand the typedef to OBrodcastHelperVar<...> -> it will be OK!?
483 : I don't know why! (other compiler not tested .. but it works!)
484 :
485 : @seealso method DEFINE_INIT_SERVICE()
486 :
487 : @param xContext is the multi service manager, which creates this instance.
488 : The value must be different from NULL!
489 : @onerror ASSERT in debug version or nothing in relaese version.
490 : *//*-*****************************************************************************************************/
491 5574 : Frame::Frame( const css::uno::Reference< css::uno::XComponentContext >& xContext )
492 : : TransactionBase ( )
493 : , PropertySetHelper ( m_aMutex,
494 : &m_aTransactionManager,
495 : false) // sal_False => dont release shared mutex on calling us!
496 : // init member
497 : , m_xContext ( xContext )
498 : , m_aListenerContainer ( m_aMutex )
499 : , m_xParent ( )
500 : , m_xContainerWindow ( )
501 : , m_xComponentWindow ( )
502 : , m_xController ( )
503 : , m_eActiveState ( E_INACTIVE )
504 : , m_sName ( )
505 : , m_bIsFrameTop ( true ) // I think we are top without a parent ... and there is no parent yet!
506 : , m_bConnected ( false ) // There exist no component inside of use => sal_False, we are not connected!
507 : , m_nExternalLockCount ( 0 )
508 : , m_bSelfClose ( false ) // Important!
509 : , m_bIsHidden ( true )
510 : , m_xTitleHelper ( )
511 : , m_pWindowCommandDispatch ( 0 )
512 5574 : , m_aChildFrameContainer ( )
513 : {
514 5574 : }
515 :
516 5574 : void Frame::initListeners()
517 : {
518 5574 : css::uno::Reference< css::uno::XInterface > xThis(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY_THROW);
519 :
520 : // Initialize a new dispatchhelper-object to handle dispatches.
521 : // We use these helper as slave for our interceptor helper ... not directly!
522 : // But he is event listener on THIS instance!
523 5574 : DispatchProvider* pDispatchHelper = new DispatchProvider( m_xContext, this );
524 11148 : css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( static_cast< ::cppu::OWeakObject* >(pDispatchHelper), css::uno::UNO_QUERY );
525 :
526 5574 : DispatchInformationProvider* pInfoHelper = new DispatchInformationProvider(m_xContext, this);
527 5574 : m_xDispatchInfoHelper = css::uno::Reference< css::frame::XDispatchInformationProvider >( static_cast< ::cppu::OWeakObject* >(pInfoHelper), css::uno::UNO_QUERY );
528 :
529 : // Initialize a new interception helper object to handle dispatches and implement an interceptor mechanism.
530 : // Set created dispatch provider as slowest slave of it.
531 : // Hold interception helper by reference only - not by pointer!
532 : // So it's easier to destroy it.
533 5574 : InterceptionHelper* pInterceptionHelper = new InterceptionHelper( this, xDispatchProvider );
534 5574 : m_xDispatchHelper = css::uno::Reference< css::frame::XDispatchProvider >( static_cast< ::cppu::OWeakObject* >(pInterceptionHelper), css::uno::UNO_QUERY );
535 :
536 : // Initialize a new XFrames-helper-object to handle XIndexAccess and XElementAccess.
537 : // We hold member as reference ... not as pointer too!
538 : // Attention: We share our frame container with this helper. Container is threadsafe himself ... So I think we can do that.
539 : // But look on dispose() for right order of deinitialization.
540 5574 : OFrames* pFramesHelper = new OFrames( this, &m_aChildFrameContainer );
541 5574 : m_xFramesHelper = css::uno::Reference< css::frame::XFrames >( static_cast< ::cppu::OWeakObject* >(pFramesHelper), css::uno::UNO_QUERY );
542 :
543 : // Initialize a the drop target listener.
544 : // We hold member as reference ... not as pointer too!
545 5574 : OpenFileDropTargetListener* pDropListener = new OpenFileDropTargetListener( m_xContext, this );
546 5574 : m_xDropTargetListener = css::uno::Reference< css::datatransfer::dnd::XDropTargetListener >( static_cast< ::cppu::OWeakObject* >(pDropListener), css::uno::UNO_QUERY );
547 :
548 : // Safe impossible cases
549 : // We can't work without these helpers!
550 : SAL_WARN_IF( !xDispatchProvider.is(), "fwk", "Frame::Frame(): Slowest slave for dispatch- and interception helper isn't valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!" );
551 : SAL_WARN_IF( !m_xDispatchHelper.is(), "fwk", "Frame::Frame(): Interception helper isn't valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!" );
552 : SAL_WARN_IF( !m_xFramesHelper.is(), "fwk", "Frame::Frame(): Frames helper isn't valid. XFrames, XIndexAccess and XElementAcces are not supported!" );
553 : SAL_WARN_IF( !m_xDropTargetListener.is(), "fwk", "Frame::Frame(): DropTarget helper isn't valid. Drag and drop without functionality!" );
554 :
555 : // establish notifies for changing of "disabled commands" configuration during runtime
556 5574 : m_aCommandOptions.EstablisFrameCallback(this);
557 :
558 : // Create an initial layout manager
559 : // Create layout manager and connect it to the newly created frame
560 5574 : m_xLayoutManager = css::frame::LayoutManager::create(m_xContext);
561 :
562 : // set information about all supported properties at the base class helper PropertySetHelper
563 11148 : impl_initializePropInfo();
564 5574 : }
565 :
566 : /*-****************************************************************************************************
567 : @short standard destructor
568 : @descr This one do NOTHING! Use dispose() instaed of this.
569 :
570 : @seealso method dispose()
571 : *//*-*****************************************************************************************************/
572 11056 : Frame::~Frame()
573 : {
574 : SAL_WARN_IF( m_aTransactionManager.getWorkingMode()!=E_CLOSE, "fwk", "Frame::~Frame(): Who forgot to dispose this service?" );
575 11056 : }
576 :
577 : /*-************************************************************************************************************
578 : @interface XComponentLoader
579 : @short try to load given URL into a task
580 : @descr You can give us some information about the content, which you will load into a frame.
581 : We search or create this target for you, make a type detection of given URL and try to load it.
582 : As result of this operation we return the new created component or nothing, if loading failed.
583 : @param "sURL" , URL, which represant the content
584 : @param "sTargetFrameName" , name of target frame or special value like "_self", "_blank" ...
585 : @param "nSearchFlags" , optional arguments for frame search, if target isn't a special one
586 : @param "lArguments" , optional arguments for loading
587 : @return A valid component reference, if loading was successfully.
588 : A null reference otherwise.
589 :
590 : @onerror We return a null reference.
591 : @threadsafe yes
592 : *//*-*************************************************************************************************************/
593 50 : css::uno::Reference< css::lang::XComponent > SAL_CALL Frame::loadComponentFromURL( const OUString& sURL ,
594 : const OUString& sTargetFrameName,
595 : sal_Int32 nSearchFlags ,
596 : const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::io::IOException ,
597 : css::lang::IllegalArgumentException ,
598 : css::uno::RuntimeException, std::exception )
599 : {
600 : {
601 : // If the frame is closed the call might lead to crash even with target "_blank",
602 : // so the DisposedException should be thrown in this case
603 : // It still looks to be too dangerous to set the transaction for the whole loading process
604 : // so the guard is used in scopes to let the standard check be used
605 :
606 50 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
607 : }
608 :
609 50 : SolarMutexClearableGuard aReadLock;
610 100 : css::uno::Reference< css::frame::XComponentLoader > xThis(static_cast< css::frame::XComponentLoader* >(this), css::uno::UNO_QUERY);
611 100 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
612 50 : aReadLock.clear();
613 :
614 100 : return LoadEnv::loadComponentFromURL(xThis, xContext, sURL, sTargetFrameName, nSearchFlags, lArguments);
615 : }
616 :
617 : /*-****************************************************************************************************
618 : @short return access to append or remove children on desktop
619 : @descr We don't implement these interface directly. We use a helper class to do this.
620 : If you wish to add or delete children to/from the container, call these method to get
621 : a reference to the helper.
622 :
623 : @seealso class OFrames
624 : @return A reference to the helper which answer your queries.
625 :
626 : @onerror A null reference is returned.
627 : *//*-*****************************************************************************************************/
628 186 : css::uno::Reference< css::frame::XFrames > SAL_CALL Frame::getFrames() throw( css::uno::RuntimeException, std::exception )
629 : {
630 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
631 : // Register transaction and reject wrong calls.
632 :
633 : /*TODO
634 : This is a temp. HACK!
635 : Our parent (a Task!) stand in close/dispose and set working mode to E_BEFOERECLOSE
636 : and call dispose on us! We tra to get this xFramesHelper and are reject by an "already closed" pranet instance ....
637 : => We use SOFTEXCEPTIONS here ... but we should make it right in further times ....
638 : */
639 :
640 186 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
641 :
642 372 : SolarMutexGuard g;
643 : // Return access to all child frames to caller.
644 : // Our childframe container is implemented in helper class OFrames and used as a reference m_xFramesHelper!
645 372 : return m_xFramesHelper;
646 : }
647 :
648 : /*-****************************************************************************************************
649 : @short get the current active child frame
650 : @descr It must be a frameto. Direct children of a frame are frames only! No task or desktop is accepted.
651 : We don't save this information directly in this class. We use our container-helper
652 : to do that.
653 :
654 : @seealso class OFrameContainer
655 : @seealso method setActiveFrame()
656 : @return A reference to our current active childframe, if anyone exist.
657 : @return A null reference, if nobody is active.
658 :
659 : @onerror A null reference is returned.
660 : *//*-*****************************************************************************************************/
661 586 : css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::getActiveFrame() throw( css::uno::RuntimeException, std::exception )
662 : {
663 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
664 : // Register transaction and reject wrong calls.
665 586 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
666 :
667 1172 : SolarMutexGuard g;
668 : // Return current active frame.
669 : // This information is available on the container.
670 1172 : return m_aChildFrameContainer.getActive();
671 : }
672 :
673 : /*-****************************************************************************************************
674 : @short set the new active direct child frame
675 : @descr It must be a frame to. Direct children of frame are frames only! No task or desktop is accepted.
676 : We don't save this information directly in this class. We use our container-helper
677 : to do that.
678 :
679 : @seealso class OFrameContainer
680 : @seealso method getActiveFrame()
681 :
682 : @param "xFrame", reference to new active child. It must be an already existing child!
683 : @onerror An assertion is thrown and element is ignored, if given frame is'nt already a child of us.
684 : *//*-*****************************************************************************************************/
685 17967 : void SAL_CALL Frame::setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame ) throw( css::uno::RuntimeException, std::exception )
686 : {
687 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
688 : // Check incoming parameters.
689 : SAL_WARN_IF( implcp_setActiveFrame( xFrame ), "fwk", "Frame::setActiveFrame(): Invalid parameter detected!" );
690 : // Look for rejected calls!
691 17967 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
692 :
693 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
694 35934 : SolarMutexResettableGuard aWriteLock;
695 :
696 : // Copy necessary member for threadsafe access!
697 : // m_aChildFrameContainer is threadsafe himself and he live if we live!!!
698 : // ...and our transaction is non breakable too ...
699 35934 : css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive();
700 17967 : EActiveState eActiveState = m_eActiveState;
701 :
702 17967 : aWriteLock.clear();
703 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
704 :
705 : // Don't work, if "new" active frame is'nt different from current one!
706 : // (xFrame==NULL is allowed to UNSET it!)
707 17967 : if( xActiveChild != xFrame )
708 : {
709 : // ... otherwise set new and deactivate old one.
710 4 : m_aChildFrameContainer.setActive( xFrame );
711 4 : if (
712 8 : ( eActiveState != E_INACTIVE ) &&
713 4 : xActiveChild.is()
714 : )
715 : {
716 2 : xActiveChild->deactivate();
717 : }
718 : }
719 :
720 17967 : if( xFrame.is() )
721 : {
722 : // If last active frame had focus ...
723 : // ... reset state to ACTIVE and send right FrameActionEvent for focus lost.
724 4 : if( eActiveState == E_FOCUS )
725 : {
726 2 : aWriteLock.reset();
727 2 : eActiveState = E_ACTIVE;
728 2 : m_eActiveState = eActiveState;
729 2 : aWriteLock.clear();
730 2 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
731 : }
732 :
733 : // If last active frame was active ...
734 : // but new one isn't it ...
735 : // ... set it as active one.
736 4 : if (
737 8 : ( eActiveState == E_ACTIVE ) &&
738 4 : ( xFrame->isActive() == sal_False )
739 : )
740 : {
741 2 : xFrame->activate();
742 : }
743 : }
744 : else
745 : // If this frame is active and has no active subframe anymore it is UI active too
746 17963 : if( eActiveState == E_ACTIVE )
747 : {
748 2 : aWriteLock.reset();
749 2 : eActiveState = E_FOCUS;
750 2 : m_eActiveState = eActiveState;
751 2 : aWriteLock.clear();
752 2 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
753 17967 : }
754 17967 : }
755 :
756 : /*-****************************************************************************************************
757 : initialize new created layout manager
758 : **/
759 5572 : void lcl_enableLayoutManager(const css::uno::Reference< css::frame::XLayoutManager2 >& xLayoutManager,
760 : const css::uno::Reference< css::frame::XFrame >& xFrame )
761 : {
762 : // Provide container window to our layout manager implementation
763 5572 : xLayoutManager->attachFrame(xFrame);
764 :
765 5572 : xFrame->addFrameActionListener(xLayoutManager);
766 :
767 5572 : DockingAreaDefaultAcceptor* pAcceptor = new DockingAreaDefaultAcceptor(xFrame);
768 5572 : css::uno::Reference< css::ui::XDockingAreaAcceptor > xDockingAreaAcceptor( static_cast< ::cppu::OWeakObject* >(pAcceptor), css::uno::UNO_QUERY_THROW);
769 5572 : xLayoutManager->setDockingAreaAcceptor(xDockingAreaAcceptor);
770 5572 : }
771 :
772 : /*-****************************************************************************************************
773 : deinitialize layout manager
774 : **/
775 5568 : void lcl_disableLayoutManager(const css::uno::Reference< css::frame::XLayoutManager2 >& xLayoutManager,
776 : const css::uno::Reference< css::frame::XFrame >& xFrame )
777 : {
778 5568 : xFrame->removeFrameActionListener(xLayoutManager);
779 5568 : xLayoutManager->setDockingAreaAcceptor(css::uno::Reference< css::ui::XDockingAreaAcceptor >());
780 5568 : xLayoutManager->attachFrame(css::uno::Reference< css::frame::XFrame >());
781 5568 : }
782 :
783 : /*-****************************************************************************************************
784 : @short initialize frame instance
785 : @descr A frame needs a window. This method set a new one ... but should called one times only!
786 : We use this window to listen for window events and forward it to our set component.
787 : Its used as parent of component window too.
788 :
789 : @seealso method getContainerWindow()
790 : @seealso method setComponent()
791 : @seealso member m_xContainerWindow
792 :
793 : @param "xWindow", reference to new container window - must be valid!
794 : @onerror We do nothing.
795 : *//*-*****************************************************************************************************/
796 5572 : void SAL_CALL Frame::initialize( const css::uno::Reference< css::awt::XWindow >& xWindow ) throw( css::uno::RuntimeException, std::exception )
797 : {
798 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
799 5572 : if (!xWindow.is())
800 : throw css::uno::RuntimeException(
801 : "Frame::initialize() called without a valid container window reference.",
802 0 : static_cast< css::frame::XFrame* >(this));
803 :
804 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
805 5572 : SolarMutexResettableGuard aWriteLock;
806 :
807 5572 : if ( m_xContainerWindow.is() )
808 : throw css::uno::RuntimeException(
809 : "Frame::initialized() is called more than once, which isnt useful nor allowed.",
810 0 : static_cast< css::frame::XFrame* >(this));
811 :
812 : // Look for rejected calls first!
813 11144 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
814 :
815 : // Enable object for real working ... so follow impl methods don't must handle it special! (e.g. E_SOFTEXCEPTIONS for rejected calls)
816 5572 : m_aTransactionManager.setWorkingMode( E_WORK );
817 :
818 : // This must be the first call of this method!
819 : // We should initialize our object and open it for working.
820 : // Set the new window.
821 : SAL_WARN_IF( m_xContainerWindow.is(), "fwk", "Frame::initialize(): Leak detected! This state should never occur ..." );
822 5572 : m_xContainerWindow = xWindow;
823 :
824 : // if window is initially visible, we will never get a windowShowing event
825 5572 : vcl::Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
826 5572 : if (pWindow && pWindow->IsVisible())
827 2 : m_bIsHidden = false;
828 :
829 11144 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
830 11144 : css::uno::Reference< css::frame::XLayoutManager2 > xLayoutManager = m_xLayoutManager;
831 :
832 : // Release lock ... because we call some impl methods, which are threadsafe by himself.
833 : // If we hold this lock - we will produce our own deadlock!
834 5572 : aWriteLock.clear();
835 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
836 :
837 5572 : if (xLayoutManager.is())
838 5572 : lcl_enableLayoutManager(xLayoutManager, this);
839 :
840 : // create progress helper
841 11144 : css::uno::Reference< css::frame::XFrame > xThis (static_cast< css::frame::XFrame* >(this) , css::uno::UNO_QUERY_THROW);
842 : css::uno::Reference< css::task::XStatusIndicatorFactory > xIndicatorFactory =
843 11144 : css::task::StatusIndicatorFactory::createWithFrame(xContext, xThis, sal_False/*DisableReschedule*/, sal_True/*AllowParentShow*/ );
844 :
845 : // SAFE -> ----------------------------------
846 5572 : aWriteLock.reset();
847 5572 : m_xIndicatorFactoryHelper = xIndicatorFactory;
848 5572 : aWriteLock.clear();
849 : // <- SAFE ----------------------------------
850 :
851 : // Start listening for events after setting it on helper class ...
852 : // So superflous messages are filtered to NULL :-)
853 5572 : implts_startWindowListening();
854 :
855 5572 : impl_enablePropertySet();
856 :
857 5572 : m_pWindowCommandDispatch = new WindowCommandDispatch(xContext, this);
858 :
859 : // Initialize title functionality
860 5572 : TitleHelper* pTitleHelper = new TitleHelper( xContext );
861 5572 : m_xTitleHelper = css::uno::Reference< css::frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pTitleHelper), css::uno::UNO_QUERY_THROW);
862 11144 : pTitleHelper->setOwner(xThis);
863 5572 : }
864 :
865 : /*-****************************************************************************************************
866 : @short returns current set container window
867 : @descr The ContainerWindow property is used as a container for the component
868 : in this frame. So this object implements a container interface too.
869 : The instantiation of the container window is done by the user of this class.
870 : The frame is the owner of its container window.
871 :
872 : @seealso method initialize()
873 : @return A reference to current set containerwindow.
874 :
875 : @onerror A null reference is returned.
876 : *//*-*****************************************************************************************************/
877 242570 : css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getContainerWindow() throw( css::uno::RuntimeException, std::exception )
878 : {
879 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
880 : // Register transaction and reject wrong calls.
881 242570 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
882 :
883 485140 : SolarMutexGuard g;
884 485140 : return m_xContainerWindow;
885 : }
886 :
887 : /*-****************************************************************************************************
888 : @short set parent frame
889 : @descr We need a parent to support some functionality! e.g. findFrame()
890 : By the way we use the chance to set an internal information about our top state.
891 : So we must not check this information during every isTop() call.
892 : We are top, if our parent is the desktop instance or we havent any parent.
893 :
894 : @seealso getCreator()
895 : @seealso findFrame()
896 : @seealso isTop()
897 : @seealos m_bIsFrameTop
898 :
899 : @param xCreator
900 : valid reference to our new owner frame, which should implement a supplier interface
901 :
902 : @threadsafe yes
903 : *//*-*****************************************************************************************************/
904 5572 : void SAL_CALL Frame::setCreator( const css::uno::Reference< css::frame::XFramesSupplier >& xCreator ) throw( css::uno::RuntimeException, std::exception )
905 : {
906 5572 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
907 :
908 : /* SAFE { */
909 11144 : SolarMutexClearableGuard aWriteLock;
910 5572 : m_xParent = xCreator;
911 5572 : aWriteLock.clear();
912 : /* } SAFE */
913 :
914 11144 : css::uno::Reference< css::frame::XDesktop > xIsDesktop( xCreator, css::uno::UNO_QUERY );
915 11144 : m_bIsFrameTop = ( xIsDesktop.is() || ! xCreator.is() );
916 5572 : }
917 :
918 : /*-****************************************************************************************************
919 : @short returns current parent frame
920 : @descr The Creator is the parent frame container. If it is NULL, the frame is the uppermost one.
921 :
922 : @seealso method setCreator()
923 : @return A reference to current set parent frame container.
924 :
925 : @onerror A null reference is returned.
926 : *//*-*****************************************************************************************************/
927 9083 : css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL Frame::getCreator() throw( css::uno::RuntimeException, std::exception )
928 : {
929 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
930 : // Register transaction and reject wrong calls.
931 9083 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
932 :
933 18166 : SolarMutexGuard g;
934 18166 : return m_xParent;
935 : }
936 :
937 : /*-****************************************************************************************************
938 : @short returns current set name of frame
939 : @descr This name is used to find target of findFrame() or queryDispatch() calls.
940 :
941 : @seealso method setName()
942 : @return Current set name of frame.
943 :
944 : @onerror An empty string is returned.
945 : *//*-*****************************************************************************************************/
946 29151 : OUString SAL_CALL Frame::getName() throw( css::uno::RuntimeException, std::exception )
947 : {
948 29151 : SolarMutexGuard g;
949 29151 : return m_sName;
950 : }
951 :
952 : /*-****************************************************************************************************
953 : @short set new name for frame
954 : @descr This name is used to find target of findFrame() or queryDispatch() calls.
955 :
956 : @attention Special names like "_blank", "_self" aren't allowed ...
957 : "_beamer" or "_menubar" excepts this rule!
958 :
959 : @seealso method getName()
960 :
961 : @param "sName", new frame name.
962 : @onerror We do nothing.
963 : *//*-*****************************************************************************************************/
964 38 : void SAL_CALL Frame::setName( const OUString& sName ) throw( css::uno::RuntimeException, std::exception )
965 : {
966 38 : SolarMutexGuard g;
967 : // Set new name ... but look for invalid special target names!
968 : // They are not allowed to set.
969 38 : if (TargetHelper::isValidNameForFrame(sName))
970 38 : m_sName = sName;
971 38 : }
972 :
973 : /*-****************************************************************************************************
974 : @short search for frames
975 : @descr This method searches for a frame with the specified name.
976 : Frames may contain other frames (e.g. a frameset) and may
977 : be contained in other frames. This hierarchy is searched by
978 : this method.
979 : First some special names are taken into account, i.e. "",
980 : "_self", "_top", "_blank" etc. The nSearchFlags are ignored
981 : when comparing these names with sTargetFrameName, further steps are
982 : controlled by the search flags. If allowed, the name of the frame
983 : itself is compared with the desired one, then ( again if allowed )
984 : the method findFrame() is called for all children, for siblings
985 : and as last for the parent frame.
986 : If no frame with the given name is found until the top frames container,
987 : a new top one is created, if this is allowed by a special
988 : flag. The new frame also gets the desired name.
989 :
990 : @param sTargetFrameName
991 : special names (_blank, _self) or real name of target frame
992 : @param nSearchFlags
993 : optional flags which regulate search for non special target frames
994 :
995 : @return A reference to found or may be new created frame.
996 : @threadsafe yes
997 : *//*-*****************************************************************************************************/
998 4774 : css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::findFrame( const OUString& sTargetFrameName,
999 : sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException, std::exception )
1000 : {
1001 4774 : css::uno::Reference< css::frame::XFrame > xTarget;
1002 :
1003 : // 0) Ignore wrong parameter!
1004 : // We don't support search for following special targets.
1005 : // If we reject this requests - we mustnt check for such names
1006 : // in following code again and again. If we do not so -wrong
1007 : // search results can occur!
1008 :
1009 9548 : if (
1010 23870 : (sTargetFrameName==SPECIALTARGET_DEFAULT ) || // valid for dispatches - not for findFrame()!
1011 14322 : (sTargetFrameName==SPECIALTARGET_MENUBAR ) // valid for dispatches - not for findFrame()!
1012 : )
1013 : {
1014 0 : return NULL;
1015 : }
1016 :
1017 : // I) check for special defined targets first which must be handled exclusive.
1018 : // force using of "if() else if() ..."
1019 :
1020 : // get threadsafe some necessary member which are necessary for following functionality
1021 : /* SAFE { */
1022 9548 : SolarMutexResettableGuard aReadLock;
1023 9548 : css::uno::Reference< css::frame::XFrame > xParent ( m_xParent, css::uno::UNO_QUERY );
1024 9548 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
1025 4774 : bool bIsTopFrame = m_bIsFrameTop;
1026 4774 : bool bIsTopWindow = WindowHelper::isTopWindow(m_xContainerWindow);
1027 4774 : aReadLock.clear();
1028 : /* } SAFE */
1029 :
1030 : // I.I) "_blank"
1031 : // Not allowed for a normal frame - but for the desktop.
1032 : // Use helper class to do so. It use the desktop automatically.
1033 :
1034 4774 : if ( sTargetFrameName==SPECIALTARGET_BLANK )
1035 : {
1036 0 : TaskCreator aCreator(xContext);
1037 0 : xTarget = aCreator.createTask(sTargetFrameName,false);
1038 : }
1039 :
1040 : // I.II) "_parent"
1041 : // It doesn't matter if we have a valid parent or not. User ask for him and get it.
1042 : // An empty result is a valid result too.
1043 :
1044 4774 : else if ( sTargetFrameName==SPECIALTARGET_PARENT )
1045 : {
1046 2 : xTarget = xParent;
1047 : }
1048 :
1049 : // I.III) "_top"
1050 : // If we are not the top frame in this hierarchy, we must forward request to our parent.
1051 : // Otherwhise we must return ourself.
1052 :
1053 4772 : else if ( sTargetFrameName==SPECIALTARGET_TOP )
1054 : {
1055 0 : if (bIsTopFrame)
1056 0 : xTarget = this;
1057 0 : else if (xParent.is()) // If we are not top - the parent MUST exist. But may it's better to check it again .-)
1058 0 : xTarget = xParent->findFrame(SPECIALTARGET_TOP,0);
1059 : }
1060 :
1061 : // I.IV) "_self", ""
1062 : // This mean this frame in every case.
1063 :
1064 9544 : else if (
1065 19036 : ( sTargetFrameName==SPECIALTARGET_SELF ) ||
1066 4720 : ( sTargetFrameName.isEmpty() )
1067 : )
1068 : {
1069 52 : xTarget = this;
1070 : }
1071 :
1072 : // I.V) "_beamer"
1073 : // This is a special sub frame of any task. We must return it if we found it on our direct children
1074 : // or create it there if it not already exists.
1075 : // Note: Such beamer exists for task(top) frames only!
1076 :
1077 4720 : else if ( sTargetFrameName==SPECIALTARGET_BEAMER )
1078 : {
1079 : // We are a task => search or create the beamer
1080 4720 : if (bIsTopWindow)
1081 : {
1082 4718 : xTarget = m_aChildFrameContainer.searchOnDirectChildrens(SPECIALTARGET_BEAMER);
1083 4718 : if ( ! xTarget.is() )
1084 : {
1085 : /* TODO
1086 : Creation not supported yet!
1087 : Wait for new layout manager service because we can't plug it
1088 : inside already opened document of this frame ...
1089 : */
1090 : }
1091 : }
1092 : // We arent a task => forward request to our parent or ignore it.
1093 2 : else if (xParent.is())
1094 2 : xTarget = xParent->findFrame(SPECIALTARGET_BEAMER,0);
1095 : }
1096 :
1097 : else
1098 : {
1099 :
1100 : // II) otherwise use optional given search flags
1101 : // force using of combinations of such flags. means no "else" part of use if() statements.
1102 : // But we ust break further searches if target was already found.
1103 : // Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
1104 : // TASK and CREATE are handled special.
1105 :
1106 : // get threadsafe some necessary member which are necessary for following functionality
1107 : /* SAFE { */
1108 0 : aReadLock.reset();
1109 0 : OUString sOwnName = m_sName;
1110 0 : aReadLock.clear();
1111 : /* } SAFE */
1112 :
1113 : // II.I) SELF
1114 : // Check for right name. If it's the searched one return ourself - otherwise
1115 : // ignore this flag.
1116 :
1117 0 : if (
1118 0 : (nSearchFlags & css::frame::FrameSearchFlag::SELF) &&
1119 0 : (sOwnName == sTargetFrameName )
1120 : )
1121 : {
1122 0 : xTarget = this;
1123 : }
1124 :
1125 : // II.II) CHILDREN
1126 : // Search on all children for the given target name.
1127 : // An empty name value can't occur here - because it must be already handled as "_self"
1128 : // before. Used helper function of container doesn't create any frame.
1129 : // It makes a deep search only.
1130 :
1131 0 : if (
1132 0 : ( ! xTarget.is() ) &&
1133 0 : (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
1134 : )
1135 : {
1136 0 : xTarget = m_aChildFrameContainer.searchOnAllChildrens(sTargetFrameName);
1137 : }
1138 :
1139 : // II.III) TASKS
1140 : // This is a special flag. It regulate search on this task tree only or allow search on
1141 : // all other ones (which are sibling trees of us) too.
1142 : // Upper search must stop at this frame if we are the topest one and the TASK flag isn't set
1143 : // or we can ignore it if we have no valid parent.
1144 :
1145 0 : if (
1146 0 : ( bIsTopFrame && (nSearchFlags & css::frame::FrameSearchFlag::TASKS) ) ||
1147 0 : ( ! bIsTopFrame )
1148 : )
1149 : {
1150 :
1151 : // II.III.I) SIBLINGS
1152 : // Search on all our direct siblings - means all children of our parent.
1153 : // Use this flag in combination with TASK. We must supress such upper search if
1154 : // user has not set it and if we are a top frame.
1155 : // Attention: Don't forward this request to our parent as a findFrame() call.
1156 : // In such case we must protect us against recursive calls.
1157 : // Use snapshot of our parent. But don't use queryFrames() of XFrames interface.
1158 : // Because it's return all siblings and all her children including our children too
1159 : // if we call it with the CHILDREN flag. We don't need that - we need the direct container
1160 : // items of our parent only to start searches there. So we must use the container interface
1161 : // XIndexAccess instead of XFrames.
1162 :
1163 0 : if (
1164 0 : ( ! xTarget.is() ) &&
1165 0 : (nSearchFlags & css::frame::FrameSearchFlag::SIBLINGS) &&
1166 0 : ( xParent.is() ) // search on siblings is impossible without a parent
1167 : )
1168 : {
1169 0 : css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
1170 0 : if (xSupplier.is())
1171 : {
1172 0 : css::uno::Reference< css::container::XIndexAccess > xContainer( xSupplier->getFrames(), css::uno::UNO_QUERY );
1173 0 : if (xContainer.is())
1174 : {
1175 0 : sal_Int32 nCount = xContainer->getCount();
1176 0 : for( sal_Int32 i=0; i<nCount; ++i )
1177 : {
1178 0 : css::uno::Reference< css::frame::XFrame > xSibling;
1179 0 : if (
1180 0 : ( !(xContainer->getByIndex(i)>>=xSibling) ) || // control unpacking
1181 0 : ( ! xSibling.is() ) || // check for valid items
1182 0 : ( xSibling==static_cast< ::cppu::OWeakObject* >(this) ) // ignore ourself! (We are a part of this container too - but search on our children was already done.)
1183 : )
1184 : {
1185 0 : continue;
1186 : }
1187 :
1188 : // Don't allow upper search here! Use right flags to regulate it.
1189 : // And allow deep search on children only - if it was allowed for us too.
1190 0 : sal_Int32 nRightFlags = css::frame::FrameSearchFlag::SELF;
1191 0 : if (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
1192 0 : nRightFlags |= css::frame::FrameSearchFlag::CHILDREN;
1193 0 : xTarget = xSibling->findFrame(sTargetFrameName, nRightFlags );
1194 : // perform search be breaking further search if a result exist.
1195 0 : if (xTarget.is())
1196 0 : break;
1197 0 : }
1198 0 : }
1199 0 : }
1200 : }
1201 :
1202 : // II.III.II) PARENT
1203 : // Forward search to our parent (if he exists.)
1204 : // To prevent us against recursive and superflous calls (which can occur if we allow him
1205 : // to search on his children too) we must change used search flags.
1206 :
1207 0 : if (
1208 0 : ( ! xTarget.is() ) &&
1209 0 : (nSearchFlags & css::frame::FrameSearchFlag::PARENT) &&
1210 0 : ( xParent.is() )
1211 : )
1212 : {
1213 0 : if (xParent->getName() == sTargetFrameName)
1214 0 : xTarget = xParent;
1215 : else
1216 : {
1217 0 : sal_Int32 nRightFlags = nSearchFlags;
1218 0 : nRightFlags &= ~css::frame::FrameSearchFlag::CHILDREN;
1219 0 : xTarget = xParent->findFrame(sTargetFrameName, nRightFlags);
1220 : }
1221 : }
1222 : }
1223 :
1224 : // II.IV) CREATE
1225 : // If we haven't found any valid target frame by using normal flags - but user allowed us to create
1226 : // a new one ... we should do that. Used TaskCreator use Desktop instance automatically as parent!
1227 :
1228 0 : if (
1229 0 : ( ! xTarget.is() ) &&
1230 0 : (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
1231 : )
1232 : {
1233 0 : TaskCreator aCreator(xContext);
1234 0 : xTarget = aCreator.createTask(sTargetFrameName,false);
1235 0 : }
1236 : }
1237 :
1238 9548 : return xTarget;
1239 : }
1240 :
1241 : /*-****************************************************************************************************
1242 : @descr Returns sal_True, if this frame is a "top frame", otherwise sal_False.
1243 : The "m_bIsFrameTop" member must be set in the ctor or setCreator() method.
1244 : A top frame is a member of the top frame container or a member of the
1245 : task frame container. Both containers can create new frames if the findFrame()
1246 : method of their css::frame::XFrame interface is called with a frame name not yet known.
1247 :
1248 : @seealso ctor
1249 : @seealso method setCreator()
1250 : @seealso method findFrame()
1251 : @return true, if is it a top frame ... false otherwise.
1252 :
1253 : @onerror No error should occur!
1254 : *//*-*****************************************************************************************************/
1255 27601 : sal_Bool SAL_CALL Frame::isTop() throw( css::uno::RuntimeException, std::exception )
1256 : {
1257 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1258 : // Register transaction and reject wrong calls.
1259 27601 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1260 :
1261 55202 : SolarMutexGuard g;
1262 : // This information is set in setCreator().
1263 : // We are top, if our parent is a task or the desktop or if no parent exist!
1264 55202 : return m_bIsFrameTop;
1265 : }
1266 :
1267 : /*-****************************************************************************************************
1268 : @short activate frame in hierarchy
1269 : @descr This feature is used to mark active paths in our frame hierarchy.
1270 : You can be a listener for this event to react for it ... change some internal states or something else.
1271 :
1272 : @seealso method deactivate()
1273 : @seealso method isActivate()
1274 : @seealso enum EActiveState
1275 : @seealso listener mechanism
1276 : *//*-*****************************************************************************************************/
1277 5038 : void SAL_CALL Frame::activate() throw( css::uno::RuntimeException, std::exception )
1278 : {
1279 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1280 : // Register transaction and reject wrong calls.
1281 5038 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1282 :
1283 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1284 10076 : SolarMutexResettableGuard aWriteLock;
1285 :
1286 : // Copy necessary member and free the lock.
1287 : // It's not necessary for m_aChildFrameContainer ... because
1288 : // he is threadsafe himself and live if we live.
1289 : // We use a registered transaction to prevent us against
1290 : // breaks during this operation!
1291 10076 : css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive();
1292 10076 : css::uno::Reference< css::frame::XFramesSupplier > xParent ( m_xParent, css::uno::UNO_QUERY );
1293 10076 : css::uno::Reference< css::frame::XFrame > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1294 10076 : css::uno::Reference< css::awt::XWindow > xComponentWindow( m_xComponentWindow, css::uno::UNO_QUERY );
1295 5038 : EActiveState eState = m_eActiveState;
1296 :
1297 5038 : aWriteLock.clear();
1298 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1299 :
1300 : // 1) If I'am not active before ...
1301 5038 : if( eState == E_INACTIVE )
1302 : {
1303 : // ... do it then.
1304 5034 : aWriteLock.reset();
1305 5034 : eState = E_ACTIVE;
1306 5034 : m_eActiveState = eState;
1307 5034 : aWriteLock.clear();
1308 : // Deactivate sibling path and forward activation to parent ... if any parent exist!
1309 5034 : if( xParent.is() )
1310 : {
1311 : // Every time set THIS frame as active child of parent and activate it.
1312 : // We MUST have a valid path from bottom to top as active path!
1313 : // But we must deactivate the old active sibling path first.
1314 :
1315 : // Attention: Deactivation of an active path, deactivate the whole path ... from bottom to top!
1316 : // But we wish to deactivate founded sibling-tree only.
1317 : // [ see deactivate() / step 4) for further information! ]
1318 :
1319 5034 : xParent->setActiveFrame( xThis );
1320 :
1321 : // Then we can activate from here to top.
1322 : // Attention: We are ACTIVE now. And the parent will call activate() at us!
1323 : // But we do nothing then! We are already activated.
1324 5034 : xParent->activate();
1325 : }
1326 : // Its necessary to send event NOW - not before.
1327 : // Activation goes from bottom to top!
1328 : // Thats the reason to activate parent first and send event now.
1329 5034 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_ACTIVATED );
1330 : }
1331 :
1332 : // 2) I was active before or current activated and there is a path from here to bottom, who CAN be active.
1333 : // But our direct child of path is not active yet.
1334 : // (It can be, if activation occur in the middle of a current path!)
1335 : // In these case we activate path to bottom to set focus on right frame!
1336 5038 : if ( eState == E_ACTIVE && xActiveChild.is() && !xActiveChild->isActive() )
1337 : {
1338 0 : xActiveChild->activate();
1339 : }
1340 :
1341 : // 3) I was active before or current activated. But if I have no active child => I will get the focus!
1342 5038 : if ( eState == E_ACTIVE && !xActiveChild.is() )
1343 : {
1344 5034 : aWriteLock.reset();
1345 5034 : eState = E_FOCUS;
1346 5034 : m_eActiveState = eState;
1347 5034 : aWriteLock.clear();
1348 5034 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
1349 5038 : }
1350 5038 : }
1351 :
1352 : /*-****************************************************************************************************
1353 : @short deactivate frame in hierarchy
1354 : @descr This feature is used to deactive paths in our frame hierarchy.
1355 : You can be a listener for this event to react for it ... change some internal states or something else.
1356 :
1357 : @seealso method activate()
1358 : @seealso method isActivate()
1359 : @seealso enum EActiveState
1360 : @seealso listener mechanism
1361 : *//*-*****************************************************************************************************/
1362 44 : void SAL_CALL Frame::deactivate() throw( css::uno::RuntimeException, std::exception )
1363 : {
1364 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1365 : // Register transaction and reject wrong calls.
1366 44 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1367 :
1368 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1369 88 : SolarMutexResettableGuard aWriteLock;
1370 :
1371 : // Copy necessary member and free the lock.
1372 88 : css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive();
1373 88 : css::uno::Reference< css::frame::XFramesSupplier > xParent ( m_xParent, css::uno::UNO_QUERY );
1374 88 : css::uno::Reference< css::frame::XFrame > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1375 44 : EActiveState eState = m_eActiveState;
1376 :
1377 44 : aWriteLock.clear();
1378 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1379 :
1380 : // Work only, if there something to do!
1381 44 : if( eState != E_INACTIVE )
1382 : {
1383 :
1384 : // 1) Deactivate all active children.
1385 44 : if ( xActiveChild.is() && xActiveChild->isActive() )
1386 : {
1387 0 : xActiveChild->deactivate();
1388 : }
1389 :
1390 : // 2) If I have the focus - I will lost it now.
1391 44 : if( eState == E_FOCUS )
1392 : {
1393 : // Set new state INACTIVE(!) and send message to all listener.
1394 : // Don't set ACTIVE as new state. This frame is deactivated for next time - due to activate().
1395 44 : aWriteLock.reset();
1396 44 : eState = E_ACTIVE;
1397 44 : m_eActiveState = eState;
1398 44 : aWriteLock.clear();
1399 44 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
1400 : }
1401 :
1402 : // 3) If I'am active - I will be deactivated now.
1403 44 : if( eState == E_ACTIVE )
1404 : {
1405 : // Set new state and send message to all listener.
1406 44 : aWriteLock.reset();
1407 44 : eState = E_INACTIVE;
1408 44 : m_eActiveState = eState;
1409 44 : aWriteLock.clear();
1410 44 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_DEACTIVATING );
1411 : }
1412 :
1413 : // 4) If there is a path from here to my parent ...
1414 : // ... I'am on the top or in the middle of deactivated subtree and action was started here.
1415 : // I must deactivate all frames from here to top, which are members of current path.
1416 : // Stop, if THESE frame not the active frame of our parent!
1417 44 : if ( xParent.is() && xParent->getActiveFrame() == xThis )
1418 : {
1419 : // We MUST break the path - otherwise we will get the focus - not our parent! ...
1420 : // Attention: Our parent don't call us again - WE ARE NOT ACTIVE YET!
1421 : // [ see step 3 and condition "if ( m_eActiveState!=INACTIVE ) ..." in this method! ]
1422 0 : xParent->deactivate();
1423 : }
1424 44 : }
1425 44 : }
1426 :
1427 : /*-****************************************************************************************************
1428 : @short returns active state
1429 : @descr Call it to get information about current active state of this frame.
1430 :
1431 : @seealso method activate()
1432 : @seealso method deactivate()
1433 : @seealso enum EActiveState
1434 : @return true if active, false otherwise.
1435 :
1436 : @onerror No error should occur.
1437 : *//*-*****************************************************************************************************/
1438 5649 : sal_Bool SAL_CALL Frame::isActive() throw( css::uno::RuntimeException, std::exception )
1439 : {
1440 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1441 : // Register transaction and reject wrong calls.
1442 5649 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1443 :
1444 11298 : SolarMutexGuard g;
1445 : return (
1446 11294 : ( m_eActiveState == E_ACTIVE ) ||
1447 5645 : ( m_eActiveState == E_FOCUS )
1448 11298 : );
1449 : }
1450 :
1451 : /*-****************************************************************************************************
1452 : @short ???
1453 : *//*-*****************************************************************************************************/
1454 10506 : void SAL_CALL Frame::contextChanged() throw( css::uno::RuntimeException, std::exception )
1455 : {
1456 : // Look for rejected calls!
1457 : // Sometimes called during closing object... => soft exceptions
1458 10506 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1459 : // Impl-method is threadsafe himself!
1460 : // Send event to all listener for frame actions.
1461 10506 : implts_sendFrameActionEvent( css::frame::FrameAction_CONTEXT_CHANGED );
1462 10506 : }
1463 :
1464 : /*-****************************************************************************************************
1465 : @short set new component inside the frame
1466 : @descr A frame is a container for a component. Use this method to set, change or realease it!
1467 : We accept null references! The xComponentWindow will be a child of our container window
1468 : and get all window events from us.
1469 :
1470 : @attention (a) A current set component can disagree with the suspend() request!
1471 : We don't set the new one and return with false then.
1472 : (b) It's possible to set:
1473 : (b1) a simple component here which supports the window only - no controller;
1474 : (b2) a full featured component which supports window and controller;
1475 : (b3) or both to NULL if outside code which to forget this component.
1476 :
1477 : @seealso method getComponentWindow()
1478 : @seealso method getController()
1479 :
1480 : @param xComponentWindow
1481 : valid reference to new component window which will be a child of internal container window
1482 : May <NULL/> for releasing.
1483 : @param xController
1484 : reference to new component controller
1485 : (may <NULL/> for relasing or setting of a simple component)
1486 :
1487 : @return <TRUE/> if operation was successful, <FALSE/> otherwise.
1488 :
1489 : @onerror We return <FALSE/>.
1490 : @threadsafe yes
1491 : *//*-*****************************************************************************************************/
1492 11148 : sal_Bool SAL_CALL Frame::setComponent( const css::uno::Reference< css::awt::XWindow >& xComponentWindow ,
1493 : const css::uno::Reference< css::frame::XController >& xController ) throw( css::uno::RuntimeException, std::exception )
1494 : {
1495 :
1496 : // Ignore this HACK of sfx2!
1497 : // He call us with an valid controller without a valid window ... Thats not allowed!
1498 11148 : if ( xController.is() && ! xComponentWindow.is() )
1499 0 : return sal_True;
1500 :
1501 11148 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1502 :
1503 : // Get threadsafe some copies of used members.
1504 : /* SAFE { */
1505 22296 : SolarMutexClearableGuard aReadLock;
1506 22296 : css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
1507 22296 : css::uno::Reference< css::awt::XWindow > xOldComponentWindow = m_xComponentWindow;
1508 22296 : css::uno::Reference< css::frame::XController > xOldController = m_xController;
1509 11148 : vcl::Window* pOwnWindow = VCLUnoHelper::GetWindow( xContainerWindow );
1510 11148 : bool bHadFocus = pOwnWindow->HasChildPathFocus();
1511 11148 : bool bWasConnected = m_bConnected;
1512 11148 : aReadLock.clear();
1513 : /* } SAFE */
1514 :
1515 : // stop listening on old window
1516 : // May it produce some trouble.
1517 : // But don't forget to listen on new window again ... or reactivate listening
1518 : // if we reject this setComponent() request and leave this method without changing the old window.
1519 11148 : implts_stopWindowListening();
1520 :
1521 : // Notify all listener, that this component (if current one exist) will be unloaded.
1522 11148 : if (bWasConnected)
1523 5576 : implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_DETACHING );
1524 :
1525 : // otherwise release old component first
1526 : // Always release controller before releasing window,
1527 : // because controller may want to access its window!
1528 : // But check for real changes - may the new controller is the old one.
1529 11148 : if (
1530 16724 : (xOldController.is() ) &&
1531 5576 : (xOldController != xController)
1532 : )
1533 : {
1534 : /* ATTENTION
1535 : Don't suspend the old controller here. Because the outside caller must do that
1536 : by definition. We have to dispose it here only.
1537 : */
1538 :
1539 : // Before we dispose this controller we should hide it inside this frame instance.
1540 : // We hold it alive for next calls by using xOldController!
1541 : /* SAFE {*/
1542 5576 : SolarMutexClearableGuard aWriteLock;
1543 5576 : m_xController = NULL;
1544 5576 : aWriteLock.clear();
1545 : /* } SAFE */
1546 :
1547 11152 : css::uno::Reference< css::lang::XComponent > xDisposable( xOldController, css::uno::UNO_QUERY );
1548 5576 : if (xDisposable.is())
1549 : {
1550 : try
1551 : {
1552 5576 : xDisposable->dispose();
1553 : }
1554 0 : catch(const css::lang::DisposedException&)
1555 : {}
1556 : }
1557 11152 : xOldController = NULL;
1558 : }
1559 :
1560 : // Now it's time to release the component window.
1561 : // If controller wasn't released successfully - this code line shouldn't be reached.
1562 : // Because in case of "suspend()==false" we return immediately with false ...
1563 : // see before
1564 : // Check for real changes too.
1565 11148 : if (
1566 16724 : (xOldComponentWindow.is() ) &&
1567 5576 : (xOldComponentWindow != xComponentWindow)
1568 : )
1569 : {
1570 : /* SAFE { */
1571 5560 : SolarMutexClearableGuard aWriteLock;
1572 5560 : m_xComponentWindow = NULL;
1573 5560 : aWriteLock.clear();
1574 : /* } SAFE */
1575 :
1576 11120 : css::uno::Reference< css::lang::XComponent > xDisposable( xOldComponentWindow, css::uno::UNO_QUERY );
1577 5560 : if (xDisposable.is())
1578 : {
1579 : try
1580 : {
1581 5560 : xDisposable->dispose();
1582 : }
1583 0 : catch(const css::lang::DisposedException&)
1584 : {
1585 : }
1586 : }
1587 11120 : xOldComponentWindow = NULL;
1588 : }
1589 :
1590 : // Now it's time to set the new component ...
1591 : // By the way - find out our new "load state" - means if we have a valid component inside.
1592 : /* SAFE { */
1593 22296 : SolarMutexResettableGuard aWriteLock;
1594 11148 : m_xComponentWindow = xComponentWindow;
1595 11148 : m_xController = xController;
1596 11148 : m_bConnected = (m_xComponentWindow.is() || m_xController.is());
1597 11148 : bool bIsConnected = m_bConnected;
1598 11148 : aWriteLock.clear();
1599 : /* } SAFE */
1600 :
1601 : // notifies all interest listener, that current component was changed or a new one was loaded
1602 11148 : if (bIsConnected && bWasConnected)
1603 18 : implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_REATTACHED );
1604 11130 : else if (bIsConnected && !bWasConnected)
1605 5564 : implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_ATTACHED );
1606 :
1607 : // A new component window doesn't know anything about current active/focus states.
1608 : // Set this information on it!
1609 11148 : if (
1610 19952 : (bHadFocus ) &&
1611 8804 : (xComponentWindow.is())
1612 : )
1613 : {
1614 3816 : xComponentWindow->setFocus();
1615 : }
1616 :
1617 : // If it was a new component window - we must resize it to fill out
1618 : // our container window.
1619 11148 : implts_resizeComponentWindow();
1620 : // New component should change our current icon ...
1621 11148 : implts_setIconOnWindow();
1622 : // OK - start listening on new window again - or do nothing if it is an empty one.
1623 11148 : implts_startWindowListening();
1624 :
1625 : /* SAFE { */
1626 11148 : aWriteLock.reset();
1627 11148 : impl_checkMenuCloser();
1628 11148 : aWriteLock.clear();
1629 : /* } SAFE */
1630 :
1631 22296 : return sal_True;
1632 : }
1633 :
1634 : /*-****************************************************************************************************
1635 : @short returns current set component window
1636 : @descr Frames are used to display components. The actual displayed component is
1637 : held by the m_xComponentWindow property. If the component implements only a
1638 : XComponent interface, the communication between the frame and the
1639 : component is very restricted. Better integration is achievable through a
1640 : XController interface.
1641 : If the component wants other objects to be able to get information about its
1642 : ResourceDescriptor it has to implement a XModel interface.
1643 : This frame is the owner of the component window.
1644 :
1645 : @seealso method setComponent()
1646 : @return css::uno::Reference to current set component window.
1647 :
1648 : @onerror A null reference is returned.
1649 : *//*-*****************************************************************************************************/
1650 629980 : css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getComponentWindow() throw( css::uno::RuntimeException, std::exception )
1651 : {
1652 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1653 : // Register transaction and reject wrong calls.
1654 629980 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1655 :
1656 1259926 : SolarMutexGuard g;
1657 1259926 : return m_xComponentWindow;
1658 : }
1659 :
1660 : /*-****************************************************************************************************
1661 : @short returns current set controller
1662 : @descr Frames are used to display components. The actual displayed component is
1663 : held by the m_xComponentWindow property. If the component implements only a
1664 : XComponent interface, the communication between the frame and the
1665 : component is very restricted. Better integration is achievable through a
1666 : XController interface.
1667 : If the component wants other objects to be able to get information about its
1668 : ResourceDescriptor it has to implement a XModel interface.
1669 : This frame is the owner of the component window.
1670 :
1671 : @seealso method setComponent()
1672 : @return css::uno::Reference to current set controller.
1673 :
1674 : @onerror A null reference is returned.
1675 : *//*-*****************************************************************************************************/
1676 1359842 : css::uno::Reference< css::frame::XController > SAL_CALL Frame::getController() throw( css::uno::RuntimeException, std::exception )
1677 : {
1678 1359842 : SolarMutexGuard g;
1679 1359842 : return m_xController;
1680 : }
1681 :
1682 : /*-****************************************************************************************************
1683 : @short add/remove listener for activate/deactivate/contextChanged events
1684 : @seealso method activate()
1685 : @seealso method deactivate()
1686 : @seealso method contextChanged()
1687 :
1688 : @param "xListener" reference to your listener object
1689 : @onerror Listener is ignored.
1690 : *//*-*****************************************************************************************************/
1691 104716 : void SAL_CALL Frame::addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
1692 : {
1693 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1694 : // Check incoming parameter.
1695 : SAL_WARN_IF( implcp_addFrameActionListener( xListener ), "fwk", "Frame::addFrameActionListener(): Invalid parameter detected." );
1696 : // Listener container is threadsafe by himself ... but we must look for rejected calls!
1697 : // Our OMenuDispatch-helper (is a member of ODispatchProvider!) is create at startup of this frame BEFORE initialize!
1698 : // => soft exceptions!
1699 104716 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1700 :
1701 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1702 104716 : m_aListenerContainer.addInterface( cppu::UnoType<css::frame::XFrameActionListener>::get(), xListener );
1703 104716 : }
1704 :
1705 93447 : void SAL_CALL Frame::removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
1706 : {
1707 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1708 : // Check incoming parameter.
1709 : SAL_WARN_IF( implcp_removeFrameActionListener( xListener ), "fwk", "Frame::removeFrameActionListener(): Invalid parameter detected." );
1710 : // Listener container is threadsafe by himself ... but we must look for rejected calls after disposing!
1711 : // But we must work with E_SOFTEXCEPTIONS ... because sometimes we are called from our listeners
1712 : // during dispose! Our work mode is E_BEFORECLOSE then ... and E_HARDEXCEPTIONS whould throw a DisposedException.
1713 93447 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1714 :
1715 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1716 93447 : m_aListenerContainer.removeInterface( cppu::UnoType<css::frame::XFrameActionListener>::get(), xListener );
1717 93447 : }
1718 :
1719 : /*-****************************************************************************************************
1720 : @short support two way mechanism to release a frame
1721 : @descr This method ask internal component (controller) if he accept this close request.
1722 : In case of <TRUE/> nothing will be happen (from point of caller of this close method).
1723 : In case of <FALSE/> a CloseVetoException is thrown. After such exception given parameter
1724 : <var>bDeliverOwnership</var> regulate which will be the new owner of this instance.
1725 :
1726 : @attention It's the replacement for XTask::close() which is marked as obsolete method.
1727 :
1728 : @param bDeliverOwnership
1729 : If parameter is set to <FALSE/> the original caller will be the owner after thrown
1730 : veto exception and must try to close this frame at later time again. Otherwhise the
1731 : source of throwed exception is the right one. May it will be the frame himself.
1732 :
1733 : @throws CloseVetoException
1734 : if any internal things willn't be closed
1735 :
1736 : @threadsafe yes
1737 : *//*-*****************************************************************************************************/
1738 5566 : void SAL_CALL Frame::close( sal_Bool bDeliverOwnership ) throw( css::util::CloseVetoException,
1739 : css::uno::RuntimeException, std::exception )
1740 : {
1741 5566 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1742 :
1743 : // At the end of this method may we must dispose ourself ...
1744 : // and may nobody from outside hold a reference to us ...
1745 : // then it's a good idea to do that by ourself.
1746 11132 : css::uno::Reference< css::uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
1747 :
1748 : // Check any close listener before we look for currently running internal processes.
1749 : // Because if a listener disagree with this close() request - we hace time to finish this
1750 : // internal operations too ...
1751 : // Note: container is threadsafe himself.
1752 11132 : css::lang::EventObject aSource (static_cast< ::cppu::OWeakObject*>(this));
1753 5566 : ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<css::util::XCloseListener>::get());
1754 5566 : if (pContainer!=NULL)
1755 : {
1756 5508 : ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
1757 16520 : while (pIterator.hasMoreElements())
1758 : {
1759 : try
1760 : {
1761 5504 : static_cast<css::util::XCloseListener*>(pIterator.next())->queryClosing( aSource, bDeliverOwnership );
1762 : }
1763 0 : catch( const css::uno::RuntimeException& )
1764 : {
1765 0 : pIterator.remove();
1766 : }
1767 5508 : }
1768 : }
1769 :
1770 : // Ok - no listener disagreed with this close() request
1771 : // check if this frame is used for any load process currently
1772 5566 : if (isActionLocked())
1773 : {
1774 0 : if (bDeliverOwnership)
1775 : {
1776 0 : SolarMutexGuard g;
1777 0 : m_bSelfClose = true;
1778 : }
1779 :
1780 0 : throw css::util::CloseVetoException("Frame in use for loading document ...",static_cast< ::cppu::OWeakObject*>(this));
1781 : }
1782 :
1783 5566 : if ( ! setComponent(NULL,NULL) )
1784 0 : throw css::util::CloseVetoException("Component couldn't be deattached ...",static_cast< ::cppu::OWeakObject*>(this));
1785 :
1786 : // If closing is allowed ... inform all istener and dispose this frame!
1787 5566 : pContainer = m_aListenerContainer.getContainer( cppu::UnoType<css::util::XCloseListener>::get());
1788 5566 : if (pContainer!=NULL)
1789 : {
1790 5508 : ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
1791 11016 : while (pIterator.hasMoreElements())
1792 : {
1793 : try
1794 : {
1795 0 : static_cast<css::util::XCloseListener*>(pIterator.next())->notifyClosing( aSource );
1796 : }
1797 0 : catch( const css::uno::RuntimeException& )
1798 : {
1799 0 : pIterator.remove();
1800 : }
1801 5508 : }
1802 : }
1803 :
1804 : /* SAFE { */
1805 11132 : SolarMutexClearableGuard aWriteLock;
1806 5566 : m_bIsHidden = true;
1807 5566 : aWriteLock.clear();
1808 : /* } SAFE */
1809 5566 : impl_checkMenuCloser();
1810 :
1811 : // Attention: We must release our own registered transaction here. Otherwhise following dispose() call
1812 : // wait for us too ....
1813 5566 : aTransaction.stop();
1814 11132 : dispose();
1815 5566 : }
1816 :
1817 : /*-****************************************************************************************************
1818 : @short be a listener for close events!
1819 : @descr Adds/remove a CloseListener at this frame instance. If the close() method is called on
1820 : this object, the such listener are informed and can disagree with that by throwing
1821 : a CloseVetoException.
1822 :
1823 : @seealso Frame::close()
1824 :
1825 : @param xListener
1826 : reference to your listener object
1827 :
1828 : @onerror Listener is ignored.
1829 :
1830 : @threadsafe yes
1831 : *//*-*****************************************************************************************************/
1832 5526 : void SAL_CALL Frame::addCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException, std::exception)
1833 : {
1834 5526 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1835 : // We don't need any lock here ...
1836 : // Container lives if we live and is threadsafe by himself.
1837 5526 : m_aListenerContainer.addInterface( cppu::UnoType<css::util::XCloseListener>::get(), xListener );
1838 5526 : }
1839 :
1840 5524 : void SAL_CALL Frame::removeCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException, std::exception)
1841 : {
1842 : // Use soft exception mode - moslty this method is called during disposing of this frame ...
1843 5524 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1844 : // We don't need any lock here ...
1845 : // Container lives if we live and is threadsafe by himself.
1846 5524 : m_aListenerContainer.removeInterface( cppu::UnoType<css::util::XCloseListener>::get(), xListener );
1847 5524 : }
1848 :
1849 16836 : OUString SAL_CALL Frame::getTitle()
1850 : throw (css::uno::RuntimeException, std::exception)
1851 : {
1852 16836 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1853 :
1854 : // SAFE ->
1855 33672 : SolarMutexClearableGuard aReadLock;
1856 33672 : css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1857 16836 : aReadLock.clear();
1858 : // <- SAFE
1859 :
1860 33672 : return xTitle->getTitle();
1861 : }
1862 :
1863 2 : void SAL_CALL Frame::setTitle( const OUString& sTitle )
1864 : throw (css::uno::RuntimeException, std::exception)
1865 : {
1866 2 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1867 :
1868 : // SAFE ->
1869 4 : SolarMutexClearableGuard aReadLock;
1870 4 : css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1871 2 : aReadLock.clear();
1872 : // <- SAFE
1873 :
1874 4 : xTitle->setTitle(sTitle);
1875 2 : }
1876 :
1877 5566 : void SAL_CALL Frame::addTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener)
1878 : throw (css::uno::RuntimeException, std::exception)
1879 : {
1880 5566 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1881 :
1882 : // SAFE ->
1883 11132 : SolarMutexClearableGuard aReadLock;
1884 11132 : css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1885 5566 : aReadLock.clear();
1886 : // <- SAFE
1887 :
1888 11132 : xTitle->addTitleChangeListener(xListener);
1889 5566 : }
1890 :
1891 0 : void SAL_CALL Frame::removeTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener )
1892 : throw (css::uno::RuntimeException, std::exception)
1893 : {
1894 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1895 :
1896 : // SAFE ->
1897 0 : SolarMutexClearableGuard aReadLock;
1898 0 : css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1899 0 : aReadLock.clear();
1900 : // <- SAFE
1901 :
1902 0 : xTitle->removeTitleChangeListener(xListener);
1903 0 : }
1904 :
1905 0 : css::uno::Reference<css::container::XNameContainer> SAL_CALL Frame::getUserDefinedAttributes() throw (css::uno::RuntimeException, std::exception)
1906 : {
1907 : // optional attribute
1908 0 : return 0;
1909 : }
1910 :
1911 0 : css::uno::Reference<css::frame::XDispatchRecorderSupplier> SAL_CALL Frame::getDispatchRecorderSupplier() throw (css::uno::RuntimeException, std::exception)
1912 : {
1913 0 : SolarMutexGuard g;
1914 0 : return m_xDispatchRecorderSupplier;
1915 : }
1916 :
1917 0 : void SAL_CALL Frame::setDispatchRecorderSupplier(const css::uno::Reference<css::frame::XDispatchRecorderSupplier>& p) throw (css::uno::RuntimeException, std::exception)
1918 : {
1919 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1920 :
1921 0 : SolarMutexGuard g;
1922 0 : m_xDispatchRecorderSupplier.set(p);
1923 0 : }
1924 :
1925 2 : css::uno::Reference<css::uno::XInterface> SAL_CALL Frame::getLayoutManager() throw (css::uno::RuntimeException, std::exception)
1926 : {
1927 2 : SolarMutexGuard g;
1928 2 : return m_xLayoutManager;
1929 : }
1930 :
1931 0 : void SAL_CALL Frame::setLayoutManager(const css::uno::Reference<css::uno::XInterface>& p1) throw (css::uno::RuntimeException, std::exception)
1932 : {
1933 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1934 :
1935 0 : SolarMutexGuard g;
1936 0 : m_xLayoutManager.set(p1, css::uno::UNO_QUERY);
1937 0 : }
1938 :
1939 : /*-****************************************************************************************************/
1940 5568 : void Frame::implts_forgetSubFrames()
1941 : {
1942 : // SAFE ->
1943 5568 : SolarMutexClearableGuard aReadLock;
1944 11136 : css::uno::Reference< css::container::XIndexAccess > xContainer(m_xFramesHelper, css::uno::UNO_QUERY_THROW);
1945 5568 : aReadLock.clear();
1946 : // <- SAFE
1947 :
1948 5568 : sal_Int32 c = xContainer->getCount();
1949 5568 : sal_Int32 i = 0;
1950 :
1951 5568 : for (i=0; i<c; ++i)
1952 : {
1953 : try
1954 : {
1955 0 : css::uno::Reference< css::frame::XFrame > xFrame;
1956 0 : xContainer->getByIndex(i) >>= xFrame;
1957 0 : if (xFrame.is())
1958 0 : xFrame->setCreator(css::uno::Reference< css::frame::XFramesSupplier >());
1959 : }
1960 0 : catch(const css::uno::Exception&)
1961 : {
1962 : // Ignore errors here.
1963 : // Nobody can guarantee a stable index in multi threaded environments .-)
1964 : }
1965 : }
1966 :
1967 11136 : SolarMutexGuard g;
1968 5568 : m_xFramesHelper.clear(); // clear uno reference
1969 11136 : m_aChildFrameContainer.clear(); // clear container content
1970 5568 : }
1971 :
1972 : /*-****************************************************************************************************
1973 : @short destroy instance
1974 : @descr The owner of this object calles the dispose method if the object
1975 : should be destroyed. All other objects and components, that are registered
1976 : as an EventListener are forced to release their references to this object.
1977 : Furthermore this frame is removed from its parent frame container to release
1978 : this reference. The reference attributes are disposed and released also.
1979 :
1980 : @attention Look for globale description at beginning of file too!
1981 : (DisposedException, FairRWLock ..., initialize, dispose)
1982 :
1983 : @seealso method initialize()
1984 : @seealso baseclass FairRWLockBase!
1985 : *//*-*****************************************************************************************************/
1986 5572 : void SAL_CALL Frame::dispose() throw( css::uno::RuntimeException, std::exception )
1987 : {
1988 : // We should hold a reference to ourself ...
1989 : // because our owner dispose us and release our reference ...
1990 : // May be we will die before we could finish this method ...
1991 5572 : css::uno::Reference< css::frame::XFrame > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1992 :
1993 : SAL_INFO("fwk.frame", "[Frame] " << m_sName << " send dispose event to listener");
1994 :
1995 : // First operation should be ... "stopp all listening for window events on our container window".
1996 : // These events are superflous but can make trouble!
1997 : // We will die, die and die ...
1998 5572 : implts_stopWindowListening();
1999 :
2000 5568 : if (m_xLayoutManager.is())
2001 5568 : lcl_disableLayoutManager(m_xLayoutManager, this);
2002 :
2003 5568 : delete m_pWindowCommandDispatch;
2004 :
2005 : // Send message to all listener and forget her references.
2006 11136 : css::lang::EventObject aEvent( xThis );
2007 5568 : m_aListenerContainer.disposeAndClear( aEvent );
2008 :
2009 : // set "end of live" for our property set helper
2010 5568 : impl_disablePropertySet();
2011 :
2012 : // interception/dispatch chain must be destructed explicitly
2013 : // Otherwhise some dispatches and/or interception objects wont die.
2014 11136 : css::uno::Reference< css::lang::XEventListener > xDispatchHelper(m_xDispatchHelper, css::uno::UNO_QUERY_THROW);
2015 5568 : xDispatchHelper->disposing(aEvent);
2016 5568 : xDispatchHelper.clear();
2017 :
2018 : // Disable this instance for further work.
2019 : // This will wait for all current running ones ...
2020 : // and reject all further requests!
2021 5568 : m_aTransactionManager.setWorkingMode( E_BEFORECLOSE );
2022 :
2023 : // Don't show any dialogs, errors or something else any more!
2024 : // If somewhere called dispose() whitout close() before - normally no dialogs
2025 : // should exist. Otherwhise it's the problem of the outside caller.
2026 : // Note:
2027 : // (a) Do it after stopWindowListening(). May that force some active/deactive
2028 : // notifications which we don't need here really.
2029 : // (b) Don't forget to save the old value of IsDialogCancelEnabled() to
2030 : // restore it afterwards (to not kill headless mode).
2031 5568 : Application::DialogCancelMode old = Application::GetDialogCancelMode();
2032 5568 : Application::SetDialogCancelMode( Application::DIALOG_CANCEL_SILENT );
2033 :
2034 : // We should be alone for ever and further dispose calls are rejected by lines before ...
2035 : // I hope it :-)
2036 :
2037 : // Free references of our frame tree.
2038 : // Force parent container to forget this frame too ...
2039 : // ( It's contained in m_xParent and so no css::lang::XEventListener for m_xParent! )
2040 : // It's important to do that before we free some other internal structures.
2041 : // Because if our parent gets an activate and found us as last possible active frame
2042 : // he try to deactivate us ... and we run into some trouble (DisposedExceptions!).
2043 5568 : if( m_xParent.is() )
2044 : {
2045 5566 : m_xParent->getFrames()->remove( xThis );
2046 5566 : m_xParent = css::uno::Reference< css::frame::XFramesSupplier >();
2047 : }
2048 :
2049 : /* } SAFE */
2050 : // Forget our internal component and her window first.
2051 : // So we can release our container window later without problems.
2052 : // Because this container window is the parent of the component window ...
2053 : // Note: Dispose it hard - because suspending must be done inside close() call!
2054 : // But try to dispose the controller first before you destroy the window.
2055 : // Because the window is used by the controller too ...
2056 5568 : if (m_xController.is())
2057 : {
2058 0 : css::uno::Reference< css::lang::XComponent > xDisposable( m_xController, css::uno::UNO_QUERY );
2059 0 : if (xDisposable.is())
2060 0 : xDisposable->dispose();
2061 : }
2062 :
2063 5568 : if (m_xComponentWindow.is())
2064 : {
2065 0 : css::uno::Reference< css::lang::XComponent > xDisposable( m_xComponentWindow, css::uno::UNO_QUERY );
2066 0 : if (xDisposable.is())
2067 0 : xDisposable->dispose();
2068 : }
2069 :
2070 5568 : impl_checkMenuCloser();
2071 :
2072 5568 : impl_disposeContainerWindow( m_xContainerWindow );
2073 :
2074 : /*ATTENTION
2075 : Clear container after successful removing from parent container ...
2076 : because our parent could be the desktop which stand in dispose too!
2077 : If we have already cleared our own container we lost our child before this could be
2078 : remove himself at this instance ...
2079 : Release m_xFramesHelper after that ... it's the same problem between parent and child!
2080 : "m_xParent->getFrames()->remove( xThis );" needs this helper ...
2081 : Otherwise we get a null reference and could finish removing successfully.
2082 : => You see: Order of calling operations is important!!!
2083 : */
2084 5568 : implts_forgetSubFrames();
2085 :
2086 : // Release some other references.
2087 : // This calls should be easy ... I hope it :-)
2088 5568 : m_xDispatchHelper.clear();
2089 5568 : m_xContext.clear();
2090 5568 : m_xDropTargetListener.clear();
2091 5568 : m_xDispatchRecorderSupplier.clear();
2092 5568 : m_xLayoutManager.clear();
2093 5568 : m_xIndicatorFactoryHelper.clear();
2094 :
2095 : // It's important to set default values here!
2096 : // If may be later somewhere change the disposed-behaviour of this implementation
2097 : // and doesn't throw any DisposedExceptions we must guarantee best matching default values ...
2098 5568 : m_eActiveState = E_INACTIVE;
2099 5568 : m_sName = OUString();
2100 5568 : m_bIsFrameTop = false;
2101 5568 : m_bConnected = false;
2102 5568 : m_nExternalLockCount = 0;
2103 5568 : m_bSelfClose = false;
2104 5568 : m_bIsHidden = true;
2105 :
2106 : // Disable this instance for further working really!
2107 5568 : m_aTransactionManager.setWorkingMode( E_CLOSE );
2108 :
2109 : // Don't forget it restore old value -
2110 : // otherwise no dialogs can be shown anymore in other frames.
2111 11140 : Application::SetDialogCancelMode( old );
2112 5568 : }
2113 :
2114 : /*-****************************************************************************************************
2115 : @short Be a listener for dispose events!
2116 : @descr Adds/remove an EventListener to this object. If the dispose method is called on
2117 : this object, the disposing method of the listener is called.
2118 : @param "xListener" reference to your listener object.
2119 : @onerror Listener is ignored.
2120 : *//*-*****************************************************************************************************/
2121 5998 : void SAL_CALL Frame::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
2122 : {
2123 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2124 : // Check incoming parameter.
2125 : SAL_WARN_IF( implcp_addEventListener( xListener ), "fwk", "Frame::addEventListener(): Invalid parameter detected." );
2126 : // Look for rejected calls only!
2127 : // Container is threadsafe.
2128 5998 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2129 :
2130 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2131 5998 : m_aListenerContainer.addInterface( cppu::UnoType<css::lang::XEventListener>::get(), xListener );
2132 5998 : }
2133 :
2134 5996 : void SAL_CALL Frame::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
2135 : {
2136 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2137 : // Check incoming parameter.
2138 : SAL_WARN_IF( implcp_removeEventListener( xListener ), "fwk", "Frame::removeEventListener(): Invalid parameter detected." );
2139 : // Look for rejected calls only!
2140 : // Container is threadsafe.
2141 : // Use E_SOFTEXCEPTIONS to allow removing listeners during dispose call!
2142 5996 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2143 :
2144 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2145 5996 : m_aListenerContainer.removeInterface( cppu::UnoType<css::lang::XEventListener>::get(), xListener );
2146 5996 : }
2147 :
2148 : /*-****************************************************************************************************
2149 : @short create new status indicator
2150 : @descr Use returned status indicator to show progresses and some text information.
2151 : All created objects share the same dialog! Only the last one can show his information.
2152 :
2153 : @seealso class StatusIndicatorFactory
2154 : @seealso class StatusIndicator
2155 : @return A reference to created object.
2156 :
2157 : @onerror We return a null reference.
2158 : *//*-*****************************************************************************************************/
2159 5504 : css::uno::Reference< css::task::XStatusIndicator > SAL_CALL Frame::createStatusIndicator() throw( css::uno::RuntimeException, std::exception )
2160 : {
2161 : /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
2162 : // Look for rejected calls!
2163 5504 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2164 :
2165 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2166 11008 : SolarMutexClearableGuard aReadLock;
2167 :
2168 : // Make snapshot of necessary member and define default return value.
2169 11008 : css::uno::Reference< css::task::XStatusIndicator > xExternal(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
2170 11008 : css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory = m_xIndicatorFactoryHelper;
2171 :
2172 5504 : aReadLock.clear();
2173 : /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
2174 :
2175 : // Was set from outside to intercept any progress activities!
2176 5504 : if (xExternal.is())
2177 0 : return xExternal;
2178 :
2179 : // Or use our own factory as fallback, to create such progress.
2180 5504 : if (xFactory.is())
2181 5504 : return xFactory->createStatusIndicator();
2182 :
2183 5504 : return css::uno::Reference< css::task::XStatusIndicator >();
2184 : }
2185 :
2186 : /*-****************************************************************************************************
2187 : @short search for target to load URL
2188 : @descr This method searches for a dispatch for the specified DispatchDescriptor.
2189 : The FrameSearchFlags and the FrameName of the DispatchDescriptor are
2190 : treated as described for findFrame.
2191 :
2192 : @seealso method findFrame()
2193 : @seealso method queryDispatches()
2194 : @seealso method set/getName()
2195 : @seealso class TargetFinder
2196 :
2197 : @param "aURL" , URL for loading
2198 : @param "sTargetFrameName" , name of target frame
2199 : @param "nSearchFlags" , additional flags to regulate search if sTargetFrameName isn't clear
2200 : @return css::uno::Reference to dispatch handler.
2201 :
2202 : @onerror A null reference is returned.
2203 : *//*-*****************************************************************************************************/
2204 289952 : css::uno::Reference< css::frame::XDispatch > SAL_CALL Frame::queryDispatch( const css::util::URL& aURL ,
2205 : const OUString& sTargetFrameName,
2206 : sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException, std::exception )
2207 : {
2208 289952 : const char UNO_PROTOCOL[] = ".uno:";
2209 :
2210 : // Don't check incoming parameter here! Our helper do it for us and it isn't a good idea to do it more than ones!
2211 : // But look for rejected calls!
2212 289952 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2213 :
2214 : // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
2215 : // in our hash map. All other protocols are stored with the protocol part.
2216 579904 : OUString aCommand( aURL.Main );
2217 289952 : if ( aURL.Protocol.equalsIgnoreAsciiCaseAsciiL( UNO_PROTOCOL, sizeof( UNO_PROTOCOL )-1 ))
2218 242868 : aCommand = aURL.Path;
2219 :
2220 : // Make boost::unordered_map lookup if the current URL is in the disabled list
2221 289952 : if ( m_aCommandOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aCommand ) )
2222 0 : return css::uno::Reference< css::frame::XDispatch >();
2223 : else
2224 : {
2225 : // We use a helper to support these interface and an interceptor mechanism.
2226 : // Our helper is threadsafe by himself!
2227 289952 : return m_xDispatchHelper->queryDispatch( aURL, sTargetFrameName, nSearchFlags );
2228 289952 : }
2229 : }
2230 :
2231 : /*-****************************************************************************************************
2232 : @short handle more than ones dispatches at same call
2233 : @descr Returns a sequence of dispatches. For details see the queryDispatch method.
2234 : For failed dispatches we return empty items in list!
2235 :
2236 : @seealso method queryDispatch()
2237 :
2238 : @param "lDescriptor" list of dispatch arguments for queryDispatch()!
2239 : @return List of dispatch references. Some elements can be NULL!
2240 :
2241 : @onerror An empty list is returned.
2242 : *//*-*****************************************************************************************************/
2243 0 : css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL Frame::queryDispatches( const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor ) throw( css::uno::RuntimeException, std::exception )
2244 : {
2245 : // Don't check incoming parameter here! Our helper do it for us and it isn't a good idea to do it more than ones!
2246 : // But look for rejected calls!
2247 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2248 :
2249 : // We use a helper to support these interface and an interceptor mechanism.
2250 : // Our helper is threadsafe by himself!
2251 0 : return m_xDispatchHelper->queryDispatches( lDescriptor );
2252 : }
2253 :
2254 : /*-****************************************************************************************************
2255 : @short register/unregister interceptor for dispatch calls
2256 : @descr If you wish to handle some dispatches by himself ... you should be
2257 : an interceptor for it. Please see class OInterceptionHelper for further information.
2258 :
2259 : @seealso class OInterceptionHelper
2260 :
2261 : @param "xInterceptor", reference to your interceptor implementation.
2262 : @onerror Interceptor is ignored.
2263 : *//*-*****************************************************************************************************/
2264 5254 : void SAL_CALL Frame::registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException, std::exception )
2265 : {
2266 : // We use a helper to support these interface and an interceptor mechanism.
2267 : // This helper is threadsafe himself and check incoming parameter too.
2268 : // I think we don't need any lock here!
2269 : // But we must look for rejected calls.
2270 5254 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2271 :
2272 10508 : css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
2273 10508 : xInterceptionHelper->registerDispatchProviderInterceptor( xInterceptor );
2274 5254 : }
2275 :
2276 5252 : void SAL_CALL Frame::releaseDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException, std::exception )
2277 : {
2278 : // We use a helper to support these interface and an interceptor mechanism.
2279 : // This helper is threadsafe himself and check incoming parameter too.
2280 : // I think we don't need any lock here!
2281 : // But we must look for rejected calls ...
2282 : // Sometimes we are called during our dispose() method ... => soft exceptions!
2283 5252 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2284 :
2285 10504 : css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
2286 10504 : xInterceptionHelper->releaseDispatchProviderInterceptor( xInterceptor );
2287 5252 : }
2288 :
2289 : /*-****************************************************************************************************
2290 : @short provides information about all possible dispatch functions
2291 : inside the currnt frame environment
2292 : *//*-*****************************************************************************************************/
2293 0 : css::uno::Sequence< sal_Int16 > SAL_CALL Frame::getSupportedCommandGroups()
2294 : throw(css::uno::RuntimeException, std::exception)
2295 : {
2296 0 : return m_xDispatchInfoHelper->getSupportedCommandGroups();
2297 : }
2298 :
2299 0 : css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL Frame::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
2300 : throw(css::uno::RuntimeException, std::exception)
2301 : {
2302 0 : return m_xDispatchInfoHelper->getConfigurableDispatchInformation(nCommandGroup);
2303 : }
2304 :
2305 : /*-****************************************************************************************************
2306 : @short notifications for window events
2307 : @descr We are a listener on our container window to forward it to our component window.
2308 :
2309 : @seealso method setComponent()
2310 : @seealso member m_xContainerWindow
2311 : @seealso member m_xComponentWindow
2312 :
2313 : @param "aEvent" describe source of detected event
2314 : *//*-*****************************************************************************************************/
2315 13174 : void SAL_CALL Frame::windowResized( const css::awt::WindowEvent& aEvent ) throw( css::uno::RuntimeException, std::exception )
2316 : {
2317 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2318 : // Check incoming parameter.
2319 : (void) aEvent;
2320 : SAL_WARN_IF( implcp_windowResized( aEvent ), "fwk", "Frame::windowResized(): Invalid parameter detected." );
2321 : // Look for rejected calls.
2322 : // Part of dispose-mechanism => soft exceptions
2323 13174 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2324 :
2325 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2326 : // Impl-method is threadsafe!
2327 : // If we have a current component window - we must resize it!
2328 13174 : implts_resizeComponentWindow();
2329 13174 : }
2330 :
2331 4988 : void SAL_CALL Frame::focusGained( const css::awt::FocusEvent& aEvent ) throw( css::uno::RuntimeException, std::exception )
2332 : {
2333 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2334 : // Check incoming parameter.
2335 : (void) aEvent;
2336 : SAL_WARN_IF( implcp_focusGained( aEvent ), "fwk", "Frame::focusGained(): Invalid parameter detected." );
2337 : // Look for rejected calls.
2338 : // Part of dispose() mechanism ... => soft exceptions!
2339 4988 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2340 :
2341 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2342 9976 : SolarMutexClearableGuard aReadLock;
2343 : // Make snapshot of member!
2344 9976 : css::uno::Reference< css::awt::XWindow > xComponentWindow = m_xComponentWindow;
2345 4988 : aReadLock.clear();
2346 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2347 :
2348 4988 : if( xComponentWindow.is() )
2349 : {
2350 1190 : xComponentWindow->setFocus();
2351 4988 : }
2352 4988 : }
2353 :
2354 : /*-****************************************************************************************************
2355 : @short notifications for window events
2356 : @descr We are a listener on our container window to forward it to our component window ...
2357 : but a XTopWindowListener we are only if we are a top frame!
2358 :
2359 : @seealso method setComponent()
2360 : @seealso member m_xContainerWindow
2361 : @seealso member m_xComponentWindow
2362 :
2363 : @param "aEvent" describe source of detected event
2364 : *//*-*****************************************************************************************************/
2365 6242 : void SAL_CALL Frame::windowActivated( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception )
2366 : {
2367 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2368 : // Check incoming parameter.
2369 : (void) aEvent;
2370 : SAL_WARN_IF( implcp_windowActivated( aEvent ), "fwk", "Frame::windowActivated(): Invalid parameter detected." );
2371 : // Look for rejected calls.
2372 6242 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2373 :
2374 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2375 12484 : SolarMutexClearableGuard aReadLock;
2376 : // Make snapshot of member!
2377 6242 : EActiveState eState = m_eActiveState;
2378 6242 : aReadLock.clear();
2379 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2380 : // Activate the new active path from here to top.
2381 6242 : if( eState == E_INACTIVE )
2382 : {
2383 5032 : setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
2384 5032 : activate();
2385 6242 : }
2386 6242 : }
2387 :
2388 174 : void SAL_CALL Frame::windowDeactivated( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception )
2389 : {
2390 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2391 : // Check incoming parameter.
2392 : (void) aEvent;
2393 : SAL_WARN_IF( implcp_windowDeactivated( aEvent ), "fwk", "Frame::windowDeactivated(): Invalid parameter detected." );
2394 : // Look for rejected calls.
2395 : // Sometimes called during dispose() => soft exceptions
2396 174 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2397 :
2398 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2399 348 : SolarMutexClearableGuard aReadLock;
2400 :
2401 348 : css::uno::Reference< css::frame::XFrame > xParent ( m_xParent, css::uno::UNO_QUERY );
2402 348 : css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
2403 174 : EActiveState eActiveState = m_eActiveState;
2404 :
2405 174 : aReadLock.clear();
2406 :
2407 174 : if( eActiveState != E_INACTIVE )
2408 : {
2409 : // Deactivation is always done implicitly by activation of another frame.
2410 : // Only if no activation is done, deactivations have to be processed if the activated window
2411 : // is a parent window of the last active Window!
2412 174 : SolarMutexClearableGuard aSolarGuard;
2413 174 : vcl::Window* pFocusWindow = Application::GetFocusWindow();
2414 696 : if ( xContainerWindow.is() && xParent.is() &&
2415 696 : !css::uno::Reference< css::frame::XDesktop >( xParent, css::uno::UNO_QUERY ).is()
2416 : )
2417 : {
2418 0 : css::uno::Reference< css::awt::XWindow > xParentWindow = xParent->getContainerWindow();
2419 0 : vcl::Window* pParentWindow = VCLUnoHelper::GetWindow( xParentWindow );
2420 : //#i70261#: dialogs opened from an OLE object will cause a deactivate on the frame of the OLE object
2421 : // on Solaris/Linux at that time pFocusWindow is still NULL because the focus handling is different; right after
2422 : // the deactivation the focus will be set into the dialog!
2423 : // currently I see no case where a sub frame could get a deactivate with pFocusWindow being NULL permanently
2424 : // so for now this case is omitted from handled deactivations
2425 0 : if( pFocusWindow && pParentWindow->IsChild( pFocusWindow ) )
2426 : {
2427 0 : css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
2428 0 : if( xSupplier.is() )
2429 : {
2430 0 : aSolarGuard.clear();
2431 0 : xSupplier->setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
2432 0 : }
2433 0 : }
2434 174 : }
2435 174 : }
2436 174 : }
2437 :
2438 0 : void SAL_CALL Frame::windowClosing( const css::lang::EventObject& ) throw( css::uno::RuntimeException, std::exception )
2439 : {
2440 : /* #i62088#
2441 : Some interceptor objects intercept our "internally asynchronous implemented" dispatch call.
2442 : And they close this frame directly (means synchronous then).
2443 : Means: Frame::windowClosing()->Frame::close()
2444 : In such situation its not a good idea to hold this transaction count alive .-)
2445 : */
2446 : {
2447 : // Look for rejected calls.
2448 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2449 : // deactivate this frame ...
2450 0 : deactivate();
2451 : }
2452 :
2453 : // ... and try to close it
2454 : // But do it asynchron inside the main thread.
2455 : // VCL has no fun to do such things outside his main thread :-(
2456 : // Note: The used dispatch make it asynchronous for us .-)
2457 :
2458 : /*ATTENTION!
2459 : Don't try to suspend the controller here! Because it's done inside used dispatch().
2460 : Otherwhise the dialog "would you save your changes?" will be shown more than once ...
2461 : */
2462 :
2463 : /* SAFE */
2464 0 : SolarMutexClearableGuard aReadLock;
2465 0 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
2466 0 : aReadLock.clear();
2467 : /* SAFE */
2468 :
2469 0 : css::util::URL aURL;
2470 0 : aURL.Complete = ".uno:CloseFrame";
2471 0 : css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(xContext));
2472 0 : xParser->parseStrict(aURL);
2473 :
2474 0 : css::uno::Reference< css::frame::XDispatch > xCloser = queryDispatch(aURL, SPECIALTARGET_SELF, 0);
2475 0 : if (xCloser.is())
2476 0 : xCloser->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >());
2477 :
2478 : // Attention: If this dispatch works synchronous ... and full fill its job ...
2479 : // this line of code will never be reached ...
2480 : // Or if it will be reached it will be for sure that all your member are gone .-)
2481 0 : }
2482 :
2483 : /*-****************************************************************************************************
2484 : @short react for a show event for the internal container window
2485 : @descr Normally we don't need this information really. But we can use it to
2486 : implement the special feature "trigger first visible task".
2487 :
2488 : Algorithm: - first we have to check if we are a top (task) frame
2489 : It's not enough to be a top frame! Because we MUST have the desktop as parent.
2490 : But frames without a parent are top too. So it's not possible to check isTop() here!
2491 : We have to look for the type of our parent.
2492 : - if we are a task frame, then we have to check if we are the first one.
2493 : We use a static variable to do so. They will be reset to afterwards be sure
2494 : that further calls of this method doesn't do anything then.
2495 : - Then we have to trigger the right event string on the global job executor.
2496 :
2497 : @seealso css::task::JobExecutor
2498 :
2499 : @param aEvent
2500 : describes the source of this event
2501 : We are not interested on this information. We are interested on the visible state only.
2502 :
2503 : @threadsafe yes
2504 : *//*-*****************************************************************************************************/
2505 10980 : void SAL_CALL Frame::windowShown( const css::lang::EventObject& ) throw(css::uno::RuntimeException, std::exception)
2506 : {
2507 : static bool bFirstVisibleTask = true;
2508 10980 : static osl::Mutex aFirstVisibleLock;
2509 :
2510 : /* SAFE { */
2511 10980 : SolarMutexClearableGuard aReadLock;
2512 21960 : css::uno::Reference< css::frame::XDesktop > xDesktopCheck( m_xParent, css::uno::UNO_QUERY );
2513 21960 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
2514 10980 : m_bIsHidden = false;
2515 10980 : aReadLock.clear();
2516 : /* } SAFE */
2517 :
2518 10980 : impl_checkMenuCloser();
2519 :
2520 10980 : if (xDesktopCheck.is())
2521 : {
2522 10976 : osl::ClearableMutexGuard aGuard(aFirstVisibleLock);
2523 10976 : bool bMustBeTriggered = bFirstVisibleTask;
2524 10976 : bFirstVisibleTask = false;
2525 10976 : aGuard.clear();
2526 :
2527 10976 : if (bMustBeTriggered)
2528 : {
2529 : css::uno::Reference< css::task::XJobExecutor > xExecutor
2530 152 : = css::task::theJobExecutor::get( xContext );
2531 152 : xExecutor->trigger( "onFirstVisibleTask" );
2532 10976 : }
2533 10980 : }
2534 10980 : }
2535 :
2536 10 : void SAL_CALL Frame::windowHidden( const css::lang::EventObject& ) throw(css::uno::RuntimeException, std::exception)
2537 : {
2538 : /* SAFE { */
2539 10 : SolarMutexClearableGuard aReadLock;
2540 10 : m_bIsHidden = true;
2541 10 : aReadLock.clear();
2542 : /* } SAFE */
2543 :
2544 10 : impl_checkMenuCloser();
2545 10 : }
2546 :
2547 : /*-****************************************************************************************************
2548 : @short called by dispose of our windows!
2549 : @descr This object is forced to release all references to the interfaces given
2550 : by the parameter source. We are a listener at our container window and
2551 : should listen for his diposing.
2552 :
2553 : @seealso XWindowListener
2554 : @seealso XTopWindowListener
2555 : @seealso XFocusListener
2556 : *//*-*****************************************************************************************************/
2557 0 : void SAL_CALL Frame::disposing( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception )
2558 : {
2559 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2560 : // Check incoming parameter.
2561 : SAL_WARN_IF( implcp_disposing( aEvent ), "fwk", "Frame::disposing(): Invalid parameter detected." );
2562 : // Look for rejected calls.
2563 : // May be we are called during releasing our windows in our in dispose call!? => soft exceptions
2564 0 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2565 :
2566 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2567 0 : SolarMutexResettableGuard aWriteLock;
2568 :
2569 0 : if( aEvent.Source == m_xContainerWindow )
2570 : {
2571 : // NECESSARY: Impl-method is threadsafe by himself!
2572 0 : aWriteLock.clear();
2573 0 : implts_stopWindowListening();
2574 0 : aWriteLock.reset();
2575 0 : m_xContainerWindow = css::uno::Reference< css::awt::XWindow >();
2576 0 : }
2577 0 : }
2578 :
2579 : /*-************************************************************************************************************
2580 : @interface com.sun.star.document.XActionLockable
2581 : @short implement locking of frame/task from outside
2582 : @descr Sometimes we have problems to decide if closing of task is allowed. Because; frame/task
2583 : could be used for pending loading jobs. So you can lock this object from outside and
2584 : prevent instance against closing during using! But - don't do it in a wrong or expensive manner.
2585 : Otherwise task couldn't die anymore!!!
2586 :
2587 : @seealso interface XActionLockable
2588 : @seeelso method BaseDispatcher::implts_loadIt()
2589 : @seeelso method Desktop::loadComponentFromURL()
2590 : @return true if frame/task is locked
2591 : false otherwise
2592 : @threadsafe yes
2593 : *//*-*************************************************************************************************************/
2594 11144 : sal_Bool SAL_CALL Frame::isActionLocked() throw( css::uno::RuntimeException, std::exception )
2595 : {
2596 11144 : SolarMutexGuard g;
2597 11144 : return( m_nExternalLockCount!=0);
2598 : }
2599 :
2600 5576 : void SAL_CALL Frame::addActionLock() throw( css::uno::RuntimeException, std::exception )
2601 : {
2602 5576 : SolarMutexGuard g;
2603 5576 : ++m_nExternalLockCount;
2604 5576 : }
2605 :
2606 5576 : void SAL_CALL Frame::removeActionLock() throw( css::uno::RuntimeException, std::exception )
2607 : {
2608 : // Register no transaction here! Otherwhise we wait for ever inside possible
2609 : // implts_checkSuicide()/dispose() request ...
2610 :
2611 : {
2612 5576 : SolarMutexGuard g;
2613 : SAL_WARN_IF( m_nExternalLockCount<=0, "fwk", "Frame::removeActionLock(): Frame isn't locked! Possible multithreading problem detected." );
2614 5576 : --m_nExternalLockCount;
2615 : }
2616 :
2617 5576 : implts_checkSuicide();
2618 5576 : }
2619 :
2620 0 : void SAL_CALL Frame::setActionLocks( sal_Int16 nLock ) throw( css::uno::RuntimeException, std::exception )
2621 : {
2622 0 : SolarMutexGuard g;
2623 : // Attention: If somewhere called resetActionLocks() before and get e.g. 5 locks ...
2624 : // and tried to set these 5 ones here after his operations ...
2625 : // we can't ignore setted requests during these two calls!
2626 : // So we must add(!) these 5 locks here.
2627 0 : m_nExternalLockCount = m_nExternalLockCount + nLock;
2628 0 : }
2629 :
2630 0 : sal_Int16 SAL_CALL Frame::resetActionLocks() throw( css::uno::RuntimeException, std::exception )
2631 : {
2632 : // Register no transaction here! Otherwhise we wait for ever inside possible
2633 : // implts_checkSuicide()/dispose() request ...
2634 :
2635 0 : sal_Int16 nCurrentLocks = 0;
2636 : {
2637 0 : SolarMutexGuard g;
2638 0 : nCurrentLocks = m_nExternalLockCount;
2639 0 : m_nExternalLockCount = 0;
2640 : }
2641 :
2642 : // Attention:
2643 : // external lock count is 0 here every time ... but if
2644 : // member m_bSelfClose is set to true too .... we call our own close()/dispose().
2645 : // See close() for further information
2646 0 : implts_checkSuicide();
2647 :
2648 0 : return nCurrentLocks;
2649 : }
2650 :
2651 5574 : void Frame::impl_initializePropInfo()
2652 : {
2653 5574 : impl_setPropertyChangeBroadcaster(static_cast< css::frame::XFrame* >(this));
2654 :
2655 : impl_addPropertyInfo(
2656 : css::beans::Property(
2657 : FRAME_PROPNAME_DISPATCHRECORDERSUPPLIER,
2658 : FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER,
2659 5574 : cppu::UnoType<css::frame::XDispatchRecorderSupplier>::get(),
2660 11148 : css::beans::PropertyAttribute::TRANSIENT));
2661 :
2662 : impl_addPropertyInfo(
2663 : css::beans::Property(
2664 : FRAME_PROPNAME_INDICATORINTERCEPTION,
2665 : FRAME_PROPHANDLE_INDICATORINTERCEPTION,
2666 5574 : cppu::UnoType<css::task::XStatusIndicator>::get(),
2667 11148 : css::beans::PropertyAttribute::TRANSIENT));
2668 :
2669 : impl_addPropertyInfo(
2670 : css::beans::Property(
2671 : FRAME_PROPNAME_ISHIDDEN,
2672 : FRAME_PROPHANDLE_ISHIDDEN,
2673 5574 : ::getBooleanCppuType(),
2674 11148 : css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY));
2675 :
2676 : impl_addPropertyInfo(
2677 : css::beans::Property(
2678 : FRAME_PROPNAME_LAYOUTMANAGER,
2679 : FRAME_PROPHANDLE_LAYOUTMANAGER,
2680 5574 : cppu::UnoType<com::sun::star::frame::XLayoutManager>::get(),
2681 11148 : css::beans::PropertyAttribute::TRANSIENT));
2682 :
2683 : impl_addPropertyInfo(
2684 : css::beans::Property(
2685 : FRAME_PROPNAME_TITLE,
2686 : FRAME_PROPHANDLE_TITLE,
2687 5574 : cppu::UnoType<OUString>::get(),
2688 11148 : css::beans::PropertyAttribute::TRANSIENT));
2689 5574 : }
2690 :
2691 4 : void SAL_CALL Frame::impl_setPropertyValue(const OUString& /*sProperty*/,
2692 : sal_Int32 nHandle ,
2693 : const css::uno::Any& aValue )
2694 :
2695 : {
2696 : /* There is no need to lock any mutex here. Because we share the
2697 : solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
2698 : see ctor of PropertySetHelper for further information.
2699 : */
2700 :
2701 : /* Attention: You can use nHandle only, if you are sure that all supported
2702 : properties has an unique handle. That must be guaranteed
2703 : inside method impl_initializePropInfo()!
2704 : */
2705 4 : switch (nHandle)
2706 : {
2707 : case FRAME_PROPHANDLE_TITLE :
2708 : {
2709 2 : OUString sExternalTitle;
2710 2 : aValue >>= sExternalTitle;
2711 2 : setTitle (sExternalTitle);
2712 : }
2713 2 : break;
2714 :
2715 : case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
2716 2 : aValue >>= m_xDispatchRecorderSupplier;
2717 2 : break;
2718 :
2719 : case FRAME_PROPHANDLE_LAYOUTMANAGER :
2720 : {
2721 0 : css::uno::Reference< css::frame::XLayoutManager2 > xOldLayoutManager = m_xLayoutManager;
2722 0 : css::uno::Reference< css::frame::XLayoutManager2 > xNewLayoutManager;
2723 0 : aValue >>= xNewLayoutManager;
2724 :
2725 0 : if (xOldLayoutManager != xNewLayoutManager)
2726 : {
2727 0 : m_xLayoutManager = xNewLayoutManager;
2728 0 : if (xOldLayoutManager.is())
2729 0 : lcl_disableLayoutManager(xOldLayoutManager, this);
2730 0 : if (xNewLayoutManager.is())
2731 0 : lcl_enableLayoutManager(xNewLayoutManager, this);
2732 0 : }
2733 : }
2734 0 : break;
2735 :
2736 : case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
2737 : {
2738 0 : css::uno::Reference< css::task::XStatusIndicator > xProgress;
2739 0 : aValue >>= xProgress;
2740 0 : m_xIndicatorInterception = xProgress;
2741 : }
2742 0 : break;
2743 :
2744 : default :
2745 : SAL_INFO("fwk", "Frame::setFastPropertyValue_NoBroadcast(): Invalid handle detected!" );
2746 0 : break;
2747 : }
2748 4 : }
2749 :
2750 126570 : css::uno::Any SAL_CALL Frame::impl_getPropertyValue(const OUString& /*sProperty*/,
2751 : sal_Int32 nHandle )
2752 : {
2753 : /* There is no need to lock any mutex here. Because we share the
2754 : solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
2755 : see ctor of PropertySetHelper for further information.
2756 : */
2757 :
2758 : /* Attention: You can use nHandle only, if you are sure that all supported
2759 : properties has an unique handle. That must be guaranteed
2760 : inside method impl_initializePropInfo()!
2761 : */
2762 126570 : css::uno::Any aValue;
2763 126570 : switch (nHandle)
2764 : {
2765 : case FRAME_PROPHANDLE_TITLE :
2766 58 : aValue <<= getTitle ();
2767 58 : break;
2768 :
2769 : case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
2770 1094 : aValue <<= m_xDispatchRecorderSupplier;
2771 1094 : break;
2772 :
2773 : case FRAME_PROPHANDLE_ISHIDDEN :
2774 29127 : aValue <<= m_bIsHidden;
2775 29127 : break;
2776 :
2777 : case FRAME_PROPHANDLE_LAYOUTMANAGER :
2778 96291 : aValue <<= m_xLayoutManager;
2779 96291 : break;
2780 :
2781 : case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
2782 : {
2783 0 : css::uno::Reference< css::task::XStatusIndicator > xProgress(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
2784 0 : aValue = css::uno::makeAny(xProgress);
2785 : }
2786 0 : break;
2787 :
2788 : default :
2789 : SAL_INFO("fwk", "Frame::getFastPropertyValue(): Invalid handle detected!" );
2790 0 : break;
2791 : }
2792 :
2793 126570 : return aValue;
2794 : }
2795 :
2796 : /*-****************************************************************************************************
2797 : @short dispose old container window and forget his reference
2798 : @descr Sometimes we must repair our "modal dialog parent mechanism" too!
2799 : @param "xWindow", reference to old container window to dispose it
2800 : @return An empty reference.
2801 : @threadsafe NO!
2802 : *//*-*****************************************************************************************************/
2803 5568 : void Frame::impl_disposeContainerWindow( css::uno::Reference< css::awt::XWindow >& xWindow )
2804 : {
2805 5568 : if( xWindow.is() )
2806 : {
2807 5566 : xWindow->setVisible( sal_False );
2808 : // All VclComponents are XComponents; so call dispose before discarding
2809 : // a css::uno::Reference< XVclComponent >, because this frame is the owner of the window
2810 5566 : xWindow->dispose();
2811 5566 : xWindow = css::uno::Reference< css::awt::XWindow >();
2812 : }
2813 5568 : }
2814 :
2815 : /*-****************************************************************************************************
2816 : @short send frame action event to our listener
2817 : @descr This method is threadsafe AND can be called by our dispose method too!
2818 : @param "aAction", describe the event for sending
2819 : *//*-*****************************************************************************************************/
2820 31824 : void Frame::implts_sendFrameActionEvent( const css::frame::FrameAction& aAction )
2821 : {
2822 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2823 : // Sometimes used by dispose() => soft exceptions!
2824 31824 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2825 :
2826 : // Log information about order of events to file!
2827 : // (only activated in debug version!)
2828 : SAL_INFO( "fwk.frame",
2829 : "[Frame] " << m_sName << " send event " <<
2830 : (aAction == css::frame::FrameAction_COMPONENT_ATTACHED ? OUString("COMPONENT ATTACHED") :
2831 : (aAction == css::frame::FrameAction_COMPONENT_DETACHING ? OUString("COMPONENT DETACHING") :
2832 : (aAction == css::frame::FrameAction_COMPONENT_REATTACHED ? OUString("COMPONENT REATTACHED") :
2833 : (aAction == css::frame::FrameAction_FRAME_ACTIVATED ? OUString("FRAME ACTIVATED") :
2834 : (aAction == css::frame::FrameAction_FRAME_DEACTIVATING ? OUString("FRAME DEACTIVATING") :
2835 : (aAction == css::frame::FrameAction_CONTEXT_CHANGED ? OUString("CONTEXT CHANGED") :
2836 : (aAction == css::frame::FrameAction_FRAME_UI_ACTIVATED ? OUString("FRAME UI ACTIVATED") :
2837 : (aAction == css::frame::FrameAction_FRAME_UI_DEACTIVATING ? OUString("FRAME UI DEACTIVATING") :
2838 : (aAction == css::frame::FrameAction_MAKE_FIXED_SIZE ? OUString("MAKE_FIXED_SIZE") :
2839 : OUString("*invalid*")))))))))));
2840 :
2841 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2842 : // Send css::frame::FrameAction event to all listener.
2843 : // Get container for right listener.
2844 : // FOLLOW LINES ARE THREADSAFE!!!
2845 : // ( OInterfaceContainerHelper is synchronized with m_aListenerContainer! )
2846 31824 : ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<css::frame::XFrameActionListener>::get());
2847 :
2848 31824 : if( pContainer != NULL )
2849 : {
2850 : // Build action event.
2851 31824 : css::frame::FrameActionEvent aFrameActionEvent( static_cast< ::cppu::OWeakObject* >(this), this, aAction );
2852 :
2853 : // Get iterator for access to listener.
2854 63648 : ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
2855 : // Send message to all listener.
2856 414309 : while( aIterator.hasMoreElements() )
2857 : {
2858 : try
2859 : {
2860 350661 : static_cast<css::frame::XFrameActionListener*>(aIterator.next())->frameAction( aFrameActionEvent );
2861 : }
2862 8 : catch( const css::uno::RuntimeException& )
2863 : {
2864 8 : aIterator.remove();
2865 : }
2866 31824 : }
2867 31824 : }
2868 31824 : }
2869 :
2870 : /*-****************************************************************************************************
2871 : @short helper to resize our component window
2872 : @descr A frame contains 2 windows - a container ~ and a component window.
2873 : This method resize inner component window to full size of outer container window.
2874 : This method is threadsafe AND can be called by our dispose method too!
2875 : *//*-*****************************************************************************************************/
2876 24322 : void Frame::implts_resizeComponentWindow()
2877 : {
2878 : // usually the LayoutManager does the resizing
2879 : // in case there is no LayoutManager resizing has to be done here
2880 24322 : if ( !m_xLayoutManager.is() )
2881 : {
2882 0 : css::uno::Reference< css::awt::XWindow > xComponentWindow( getComponentWindow() );
2883 0 : if( xComponentWindow.is() )
2884 : {
2885 0 : css::uno::Reference< css::awt::XDevice > xDevice( getContainerWindow(), css::uno::UNO_QUERY );
2886 :
2887 : // Convert relativ size to output size.
2888 0 : css::awt::Rectangle aRectangle = getContainerWindow()->getPosSize();
2889 0 : css::awt::DeviceInfo aInfo = xDevice->getInfo();
2890 0 : css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
2891 0 : aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
2892 :
2893 : // Resize our component window.
2894 0 : xComponentWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE );
2895 0 : }
2896 : }
2897 24322 : }
2898 :
2899 : /*-****************************************************************************************************
2900 : @short helper to set icon on our container window (if it is a system window!)
2901 : @descr We use our internal set controller (if it exist) to specify which factory he represanted.
2902 : These information can be used to find right icon. But our controller can say it us directly
2903 : too ... we should ask his optional property set first ...
2904 :
2905 : @seealso method Window::SetIcon()
2906 : @onerror We do nothing.
2907 : *//*-*****************************************************************************************************/
2908 11148 : void Frame::implts_setIconOnWindow()
2909 : {
2910 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2911 : // Look for rejected calls.
2912 11148 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2913 :
2914 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2915 : // Make snapshot of necessary members and release lock.
2916 22296 : SolarMutexClearableGuard aReadLock;
2917 22296 : css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow, css::uno::UNO_QUERY );
2918 22296 : css::uno::Reference< css::frame::XController > xController ( m_xController , css::uno::UNO_QUERY );
2919 11148 : aReadLock.clear();
2920 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2921 :
2922 11148 : if( xContainerWindow.is() && xController.is() )
2923 : {
2924 :
2925 : // a) set default value to an invalid one. So we can start further searches for right icon id, if
2926 : // first steps failed!
2927 : // We must reset it to any fallback value - if no search step returns a valid result.
2928 5582 : sal_Int32 nIcon = -1;
2929 :
2930 : // b) try to find information on controller propertyset directly
2931 : // Don't forget to catch possible exceptions - because these property is an optional one!
2932 5582 : css::uno::Reference< css::beans::XPropertySet > xSet( xController, css::uno::UNO_QUERY );
2933 5582 : if( xSet.is() )
2934 : {
2935 : try
2936 : {
2937 5466 : css::uno::Reference< css::beans::XPropertySetInfo > const xPSI( xSet->getPropertySetInfo(), css::uno::UNO_SET_THROW );
2938 5466 : if ( xPSI->hasPropertyByName( "IconId" ) )
2939 0 : xSet->getPropertyValue( "IconId" ) >>= nIcon;
2940 : }
2941 0 : catch( css::uno::Exception& )
2942 : {
2943 : DBG_UNHANDLED_EXCEPTION();
2944 : }
2945 : }
2946 :
2947 : // c) if b) failed ... analyze argument list of currently loaded document insde the frame to find the filter.
2948 : // He can be used to detect right factory - and these can be used to match factory to icon ...
2949 5582 : if( nIcon == -1 )
2950 : {
2951 5582 : css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
2952 5582 : if( xModel.is() )
2953 : {
2954 5574 : SvtModuleOptions::EFactory eFactory = SvtModuleOptions::ClassifyFactoryByModel(xModel);
2955 5574 : if (eFactory != SvtModuleOptions::E_UNKNOWN_FACTORY)
2956 5574 : nIcon = SvtModuleOptions().GetFactoryIcon( eFactory );
2957 5582 : }
2958 : }
2959 :
2960 : // d) if all steps failed - use fallback!
2961 5582 : if( nIcon == -1 )
2962 : {
2963 8 : nIcon = 0;
2964 : }
2965 :
2966 : // e) set icon on container window now
2967 : // Don't forget SolarMutex! We use vcl directly :-(
2968 : // Check window pointer for right WorkWindow class too!!!
2969 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2970 : {
2971 5582 : SolarMutexGuard aSolarGuard;
2972 5582 : vcl::Window* pWindow = (VCLUnoHelper::GetWindow( xContainerWindow ));
2973 5582 : if(
2974 11164 : ( pWindow != NULL ) &&
2975 5582 : ( pWindow->GetType() == WINDOW_WORKWINDOW )
2976 : )
2977 : {
2978 5574 : WorkWindow* pWorkWindow = static_cast<WorkWindow*>(pWindow);
2979 5574 : pWorkWindow->SetIcon( (sal_uInt16)nIcon );
2980 5582 : }
2981 5582 : }
2982 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2983 11148 : }
2984 11148 : }
2985 :
2986 : /*-************************************************************************************************************
2987 : @short helper to start/stop listeneing for window events on container window
2988 : @descr If we get a new container window, we must set it on internal member ...
2989 : and stop listening at old one ... and start listening on new one!
2990 : But sometimes (in dispose() call!) it's necessary to stop listeneing without starting
2991 : on new connections. So we split this functionality to make it easier at use.
2992 :
2993 : @seealso method initialize()
2994 : @seealso method dispose()
2995 : @onerror We do nothing!
2996 : @threadsafe yes
2997 : *//*-*************************************************************************************************************/
2998 16720 : void Frame::implts_startWindowListening()
2999 : {
3000 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
3001 16720 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
3002 :
3003 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3004 : // Make snapshot of necessary member!
3005 33440 : SolarMutexClearableGuard aReadLock;
3006 33440 : css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
3007 33440 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
3008 33440 : css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > xDragDropListener = m_xDropTargetListener;
3009 33440 : css::uno::Reference< css::awt::XWindowListener > xWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3010 33440 : css::uno::Reference< css::awt::XFocusListener > xFocusListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3011 33440 : css::uno::Reference< css::awt::XTopWindowListener > xTopWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3012 16720 : aReadLock.clear();
3013 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
3014 :
3015 16720 : if( xContainerWindow.is() )
3016 : {
3017 16720 : xContainerWindow->addWindowListener( xWindowListener);
3018 16720 : xContainerWindow->addFocusListener ( xFocusListener );
3019 :
3020 16720 : css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
3021 16720 : if( xTopWindow.is() )
3022 : {
3023 16720 : xTopWindow->addTopWindowListener( xTopWindowListener );
3024 :
3025 16720 : css::uno::Reference< css::awt::XToolkit2 > xToolkit = css::awt::Toolkit::create( xContext );
3026 33440 : css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xToolkit->getDropTarget( xContainerWindow );
3027 16720 : if( xDropTarget.is() )
3028 : {
3029 16720 : xDropTarget->addDropTargetListener( xDragDropListener );
3030 16720 : xDropTarget->setActive( sal_True );
3031 16720 : }
3032 16720 : }
3033 16720 : }
3034 16720 : }
3035 :
3036 16720 : void Frame::implts_stopWindowListening()
3037 : {
3038 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
3039 : // Sometimes used by dispose() => soft exceptions!
3040 16720 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
3041 :
3042 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3043 : // Make snapshot of necessary member!
3044 33440 : SolarMutexClearableGuard aReadLock;
3045 33440 : css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
3046 33440 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
3047 33440 : css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > xDragDropListener = m_xDropTargetListener;
3048 33440 : css::uno::Reference< css::awt::XWindowListener > xWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3049 33440 : css::uno::Reference< css::awt::XFocusListener > xFocusListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3050 33440 : css::uno::Reference< css::awt::XTopWindowListener > xTopWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3051 16720 : aReadLock.clear();
3052 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
3053 :
3054 16720 : if( xContainerWindow.is() )
3055 : {
3056 16718 : xContainerWindow->removeWindowListener( xWindowListener);
3057 16718 : xContainerWindow->removeFocusListener ( xFocusListener );
3058 :
3059 16718 : css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
3060 16718 : if( xTopWindow.is() )
3061 : {
3062 16718 : xTopWindow->removeTopWindowListener( xTopWindowListener );
3063 :
3064 16718 : css::uno::Reference< css::awt::XToolkit2 > xToolkit = css::awt::Toolkit::create( xContext );
3065 33428 : css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xToolkit->getDropTarget( xContainerWindow );
3066 16714 : if( xDropTarget.is() )
3067 : {
3068 16714 : xDropTarget->removeDropTargetListener( xDragDropListener );
3069 16714 : xDropTarget->setActive( sal_False );
3070 16714 : }
3071 16718 : }
3072 16720 : }
3073 16716 : }
3074 :
3075 : /*-****************************************************************************************************
3076 : @short helper to force breaked close() request again
3077 : @descr If we self disagree with a close() request, and detect that all external locks are gone ...
3078 : then we must try to close this frame again.
3079 :
3080 : @seealso XCloseable::close()
3081 : @seealso Frame::close()
3082 : @seealso Frame::removeActionLock()
3083 : @seealso Frame::resetActionLock()
3084 : @seealso m_bSelfClose
3085 : @seealso m_nExternalLockCount
3086 :
3087 : @threadsafe yes
3088 : *//*-*****************************************************************************************************/
3089 5576 : void Frame::implts_checkSuicide()
3090 : {
3091 : /* SAFE */
3092 5576 : SolarMutexClearableGuard aReadLock;
3093 : // in case of lock==0 and safed state of previous close() request m_bSelfClose
3094 : // we must force close() again. Because we had disagreed with that before.
3095 5576 : bool bSuicide = (m_nExternalLockCount==0 && m_bSelfClose);
3096 5576 : m_bSelfClose = false;
3097 5576 : aReadLock.clear();
3098 : /* } SAFE */
3099 : // force close and deliver owner ship to source of possible throwed veto exception
3100 : // Attention: Because this method isn't designed to throw such exception we must suppress
3101 : // it for outside code!
3102 : try
3103 : {
3104 5576 : if (bSuicide)
3105 0 : close(sal_True);
3106 : }
3107 0 : catch(const css::util::CloseVetoException&)
3108 : {}
3109 0 : catch(const css::lang::DisposedException&)
3110 5576 : {}
3111 5576 : }
3112 :
3113 : /** little helper to enable/disable the menu closer at the menubar of the given frame.
3114 :
3115 : @param xFrame
3116 : we use its layout manager to set/reset a special callback.
3117 : Its existence regulate visibility of this closer item.
3118 :
3119 : @param bState
3120 : <TRUE/> enable; <FALSE/> disable this state
3121 : */
3122 :
3123 10976 : void Frame::impl_setCloser( /*IN*/ const css::uno::Reference< css::frame::XFrame2 >& xFrame ,
3124 : /*IN*/ bool bState )
3125 : {
3126 : // Note: If start module isn't installed - no closer has to be shown!
3127 10976 : if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE))
3128 10976 : return;
3129 :
3130 : try
3131 : {
3132 10976 : css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY_THROW);
3133 21952 : css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
3134 10976 : xFrameProps->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
3135 21952 : css::uno::Reference< css::beans::XPropertySet > xLayoutProps(xLayoutManager, css::uno::UNO_QUERY_THROW);
3136 21952 : xLayoutProps->setPropertyValue(LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, css::uno::makeAny(bState));
3137 : }
3138 0 : catch(const css::uno::RuntimeException&)
3139 0 : { throw; }
3140 0 : catch(const css::uno::Exception&)
3141 : {}
3142 : }
3143 :
3144 : /** it checks, which of the top level task frames must have the special menu closer for
3145 : switching to the backing window mode.
3146 :
3147 : It analyze the current list of visible top level frames. Only the last real document
3148 : frame can have this symbol. Not the help frame nor the backing task itself.
3149 : Here we do anything related to this closer. We remove it from the old frame and set it
3150 : for the new one.
3151 : */
3152 :
3153 33272 : void Frame::impl_checkMenuCloser()
3154 : {
3155 : /* SAFE { */
3156 33272 : SolarMutexClearableGuard aReadLock;
3157 :
3158 : // only top frames, which are part of our desktop hierarchy, can
3159 : // do so! By the way - we need the desktop instance to have access
3160 : // to all other top level frames too.
3161 60958 : css::uno::Reference< css::frame::XDesktop > xDesktop (m_xParent, css::uno::UNO_QUERY);
3162 60958 : css::uno::Reference< css::frame::XFramesSupplier > xTaskSupplier(xDesktop , css::uno::UNO_QUERY);
3163 33272 : if ( !xDesktop.is() || !xTaskSupplier.is() )
3164 38858 : return;
3165 :
3166 27686 : aReadLock.clear();
3167 : /* } SAFE */
3168 :
3169 : // analyze the list of current open tasks
3170 : // Suppress search for other views to the same model ...
3171 : // It's not needed here and can be very expensive.
3172 : FrameListAnalyzer aAnalyzer(
3173 : xTaskSupplier,
3174 : this,
3175 55372 : FrameListAnalyzer::E_HIDDEN | FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);
3176 :
3177 : // specify the new frame, which must have this special state ...
3178 55372 : css::uno::Reference< css::frame::XFrame2 > xNewCloserFrame;
3179 :
3180 : // a)
3181 : // If there exist ate least one other frame - there are two frames currently open.
3182 : // But we can enable this closer only, if one of these two tasks includes the help module.
3183 : // The "other frame" couldn't be the help. Because then it wouldn't be part of this "other list".
3184 : // In such case it will be separated to the reference aAnalyzer.m_xHelp!
3185 : // But we must check, if weself includes the help ...
3186 : // Check aAnalyzer.m_bReferenceIsHelp!
3187 27686 : if (
3188 27938 : (aAnalyzer.m_lOtherVisibleFrames.getLength()==1) &&
3189 : (
3190 548 : (aAnalyzer.m_bReferenceIsHelp ) ||
3191 : (aAnalyzer.m_bReferenceIsHidden)
3192 : )
3193 : )
3194 : {
3195 : // others[0] can't be the backing component!
3196 : // Because it's set at the special member aAnalyzer.m_xBackingComponent ... :-)
3197 252 : xNewCloserFrame.set( aAnalyzer.m_lOtherVisibleFrames[0], css::uno::UNO_QUERY_THROW );
3198 : }
3199 :
3200 : // b)
3201 : // There is no other frame ... means no other document frame. The help module
3202 : // will be handled separately and must(!) be ignored here ... excepting weself includes the help.
3203 27434 : else if (
3204 54572 : (aAnalyzer.m_lOtherVisibleFrames.getLength()==0) &&
3205 54276 : (!aAnalyzer.m_bReferenceIsHelp ) &&
3206 74548 : (!aAnalyzer.m_bReferenceIsHidden ) &&
3207 19976 : (!aAnalyzer.m_bReferenceIsBacking )
3208 : )
3209 : {
3210 19974 : xNewCloserFrame = this;
3211 : }
3212 :
3213 : // Look for necessary actions ...
3214 : // Only if the closer state must be moved from one frame to another one
3215 : // or must be enabled/disabled at all.
3216 55372 : SolarMutexGuard aGuard;
3217 :
3218 55372 : css::uno::Reference< css::frame::XFrame2 > xCloserFrame (m_xCloserFrame.get(), css::uno::UNO_QUERY);
3219 27686 : if (xCloserFrame!=xNewCloserFrame)
3220 : {
3221 10976 : if (xCloserFrame.is())
3222 5486 : impl_setCloser(xCloserFrame, false);
3223 10976 : if (xNewCloserFrame.is())
3224 5490 : impl_setCloser(xNewCloserFrame, true);
3225 10976 : m_xCloserFrame = xNewCloserFrame;
3226 27686 : }
3227 : }
3228 :
3229 : // debug methods
3230 :
3231 : // Its allowed to reset the active frame membervariable with a NULL-css::uno::Reference but not with a NULL-pointer!
3232 : // And we accept frames only! No tasks and desktops!
3233 0 : bool Frame::implcp_setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame )
3234 : {
3235 0 : return css::uno::Reference< css::frame::XDesktop >( xFrame, css::uno::UNO_QUERY ).is();
3236 : }
3237 :
3238 0 : bool Frame::implcp_addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
3239 : {
3240 0 : return !xListener.is();
3241 : }
3242 :
3243 0 : bool Frame::implcp_removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
3244 : {
3245 0 : return !xListener.is();
3246 : }
3247 :
3248 0 : bool Frame::implcp_addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
3249 : {
3250 0 : return !xListener.is();
3251 : }
3252 :
3253 0 : bool Frame::implcp_removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
3254 : {
3255 0 : return !xListener.is();
3256 : }
3257 :
3258 0 : bool Frame::implcp_windowResized( const css::awt::WindowEvent& aEvent )
3259 : {
3260 0 : return !aEvent.Source.is();
3261 : }
3262 :
3263 0 : bool Frame::implcp_focusGained( const css::awt::FocusEvent& aEvent )
3264 : {
3265 0 : return !aEvent.Source.is();
3266 : }
3267 :
3268 0 : bool Frame::implcp_windowActivated( const css::lang::EventObject& aEvent )
3269 : {
3270 0 : return !aEvent.Source.is();
3271 : }
3272 :
3273 0 : bool Frame::implcp_windowDeactivated( const css::lang::EventObject& aEvent )
3274 : {
3275 0 : return !aEvent.Source.is();
3276 : }
3277 :
3278 0 : bool Frame::implcp_disposing( const css::lang::EventObject& aEvent )
3279 : {
3280 0 : return !aEvent.Source.is();
3281 : }
3282 :
3283 : }
3284 :
3285 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
3286 5574 : com_sun_star_comp_framework_Frame_get_implementation(
3287 : css::uno::XComponentContext *context,
3288 : css::uno::Sequence<css::uno::Any> const &)
3289 : {
3290 5574 : Frame *inst = new Frame(context);
3291 5574 : css::uno::XInterface *acquired_inst = cppu::acquire(inst);
3292 :
3293 5574 : inst->initListeners();
3294 :
3295 5574 : return acquired_inst;
3296 951 : }
3297 :
3298 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|