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 1 : virtual OUString SAL_CALL getImplementationName()
157 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
158 : {
159 1 : 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 1 : virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
169 : throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
170 : {
171 1 : css::uno::Sequence< OUString > aSeq(1);
172 1 : aSeq[0] = "com.sun.star.frame.Frame";
173 1 : 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 6383 : 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 659 : 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 6344 : 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 5 : virtual void SAL_CALL windowClosed ( const css::lang::EventObject& /*aEvent*/ ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE {};
265 4 : virtual void SAL_CALL windowMinimized ( const css::lang::EventObject& /*aEvent*/ ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE {};
266 2 : 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 216 : css::uno::WeakReference< css::frame::XFrame2 > Frame::m_xCloserFrame;
419 :
420 : // XInterface, XTypeProvider, XServiceInfo
421 :
422 13396492 : 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 2 : 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 release version.
490 : *//*-*****************************************************************************************************/
491 3283 : 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 3283 : , m_aChildFrameContainer ( )
513 : {
514 3283 : }
515 :
516 3283 : void Frame::initListeners()
517 : {
518 3283 : 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 3283 : DispatchProvider* pDispatchHelper = new DispatchProvider( m_xContext, this );
524 6566 : css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider( static_cast< ::cppu::OWeakObject* >(pDispatchHelper), css::uno::UNO_QUERY );
525 :
526 3283 : DispatchInformationProvider* pInfoHelper = new DispatchInformationProvider(m_xContext, this);
527 3283 : 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 3283 : InterceptionHelper* pInterceptionHelper = new InterceptionHelper( this, xDispatchProvider );
534 3283 : 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 3283 : OFrames* pFramesHelper = new OFrames( this, &m_aChildFrameContainer );
541 3283 : 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 3283 : OpenFileDropTargetListener* pDropListener = new OpenFileDropTargetListener( m_xContext, this );
546 3283 : 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 is not valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!" );
551 : SAL_WARN_IF( !m_xDispatchHelper.is(), "fwk", "Frame::Frame(): Interception helper is not valid. XDispatchProvider, XDispatch, XDispatchProviderInterception are not full supported!" );
552 : SAL_WARN_IF( !m_xFramesHelper.is(), "fwk", "Frame::Frame(): Frames helper is not valid. XFrames, XIndexAccess and XElementAcces are not supported!" );
553 : SAL_WARN_IF( !m_xDropTargetListener.is(), "fwk", "Frame::Frame(): DropTarget helper is not valid. Drag and drop without functionality!" );
554 :
555 : // establish notifies for changing of "disabled commands" configuration during runtime
556 3283 : m_aCommandOptions.EstablisFrameCallback(this);
557 :
558 : // Create an initial layout manager
559 : // Create layout manager and connect it to the newly created frame
560 3283 : m_xLayoutManager = css::frame::LayoutManager::create(m_xContext);
561 :
562 : // set information about all supported properties at the base class helper PropertySetHelper
563 6566 : impl_initializePropInfo();
564 3283 : }
565 :
566 : /*-****************************************************************************************************
567 : @short standard destructor
568 : @descr This one do NOTHING! Use dispose() instaed of this.
569 :
570 : @seealso method dispose()
571 : *//*-*****************************************************************************************************/
572 5512 : Frame::~Frame()
573 : {
574 : SAL_WARN_IF( m_aTransactionManager.getWorkingMode()!=E_CLOSE, "fwk", "Frame::~Frame(): Who forgot to dispose this service?" );
575 5512 : }
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 represent 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 is not 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 83 : 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 83 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
607 : }
608 :
609 83 : SolarMutexClearableGuard aReadLock;
610 166 : css::uno::Reference< css::frame::XComponentLoader > xThis(static_cast< css::frame::XComponentLoader* >(this), css::uno::UNO_QUERY);
611 166 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
612 83 : aReadLock.clear();
613 :
614 166 : 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 97 : 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 97 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
641 :
642 194 : 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 194 : 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 359 : 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 359 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
666 :
667 718 : SolarMutexGuard g;
668 : // Return current active frame.
669 : // This information is available on the container.
670 718 : 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 isn't already a child of us.
684 : *//*-*****************************************************************************************************/
685 10325 : 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 10325 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
692 :
693 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
694 20650 : 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 20650 : css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive();
700 10325 : EActiveState eActiveState = m_eActiveState;
701 :
702 10325 : aWriteLock.clear();
703 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
704 :
705 : // Don't work, if "new" active frame isn't different from current one!
706 : // (xFrame==NULL is allowed to UNSET it!)
707 10325 : if( xActiveChild != xFrame )
708 : {
709 : // ... otherwise set new and deactivate old one.
710 2 : m_aChildFrameContainer.setActive( xFrame );
711 2 : if (
712 4 : ( eActiveState != E_INACTIVE ) &&
713 2 : xActiveChild.is()
714 : )
715 : {
716 1 : xActiveChild->deactivate();
717 : }
718 : }
719 :
720 10325 : if( xFrame.is() )
721 : {
722 : // If last active frame had focus ...
723 : // ... reset state to ACTIVE and send right FrameActionEvent for focus lost.
724 2 : if( eActiveState == E_FOCUS )
725 : {
726 1 : aWriteLock.reset();
727 1 : eActiveState = E_ACTIVE;
728 1 : m_eActiveState = eActiveState;
729 1 : aWriteLock.clear();
730 1 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
731 : }
732 :
733 : // If last active frame was active ...
734 : // but new one is not it ...
735 : // ... set it as active one.
736 2 : if (
737 4 : ( eActiveState == E_ACTIVE ) &&
738 2 : ( xFrame->isActive() == sal_False )
739 : )
740 : {
741 1 : xFrame->activate();
742 : }
743 : }
744 : else
745 : // If this frame is active and has no active subframe anymore it is UI active too
746 10323 : if( eActiveState == E_ACTIVE )
747 : {
748 1 : aWriteLock.reset();
749 1 : eActiveState = E_FOCUS;
750 1 : m_eActiveState = eActiveState;
751 1 : aWriteLock.clear();
752 1 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
753 10325 : }
754 10325 : }
755 :
756 : /*-****************************************************************************************************
757 : initialize new created layout manager
758 : **/
759 3282 : 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 3282 : xLayoutManager->attachFrame(xFrame);
764 :
765 3282 : xFrame->addFrameActionListener(xLayoutManager);
766 :
767 3282 : DockingAreaDefaultAcceptor* pAcceptor = new DockingAreaDefaultAcceptor(xFrame);
768 3282 : css::uno::Reference< css::ui::XDockingAreaAcceptor > xDockingAreaAcceptor( static_cast< ::cppu::OWeakObject* >(pAcceptor), css::uno::UNO_QUERY_THROW);
769 3282 : xLayoutManager->setDockingAreaAcceptor(xDockingAreaAcceptor);
770 3282 : }
771 :
772 : /*-****************************************************************************************************
773 : deinitialize layout manager
774 : **/
775 3274 : void lcl_disableLayoutManager(const css::uno::Reference< css::frame::XLayoutManager2 >& xLayoutManager,
776 : const css::uno::Reference< css::frame::XFrame >& xFrame )
777 : {
778 3274 : xFrame->removeFrameActionListener(xLayoutManager);
779 3274 : xLayoutManager->setDockingAreaAcceptor(css::uno::Reference< css::ui::XDockingAreaAcceptor >());
780 3274 : xLayoutManager->attachFrame(css::uno::Reference< css::frame::XFrame >());
781 3274 : }
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 3282 : void SAL_CALL Frame::initialize( const css::uno::Reference< css::awt::XWindow >& xWindow ) throw( css::uno::RuntimeException, std::exception )
797 : {
798 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
799 3282 : 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 3282 : SolarMutexResettableGuard aWriteLock;
806 :
807 3282 : if ( m_xContainerWindow.is() )
808 : throw css::uno::RuntimeException(
809 : "Frame::initialized() is called more than once, which is not useful nor allowed.",
810 0 : static_cast< css::frame::XFrame* >(this));
811 :
812 : // Look for rejected calls first!
813 6564 : 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 3282 : 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 3282 : m_xContainerWindow = xWindow;
823 :
824 : // if window is initially visible, we will never get a windowShowing event
825 3282 : vcl::Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
826 3282 : if (pWindow && pWindow->IsVisible())
827 1 : m_bIsHidden = false;
828 :
829 6564 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
830 6564 : 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 3282 : aWriteLock.clear();
835 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
836 :
837 3282 : if (xLayoutManager.is())
838 3282 : lcl_enableLayoutManager(xLayoutManager, this);
839 :
840 : // create progress helper
841 6564 : 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 6564 : css::task::StatusIndicatorFactory::createWithFrame(xContext, xThis, sal_False/*DisableReschedule*/, sal_True/*AllowParentShow*/ );
844 :
845 : // SAFE -> ----------------------------------
846 3282 : aWriteLock.reset();
847 3282 : m_xIndicatorFactoryHelper = xIndicatorFactory;
848 3282 : 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 3282 : implts_startWindowListening();
854 :
855 3282 : m_pWindowCommandDispatch = new WindowCommandDispatch(xContext, this);
856 :
857 : // Initialize title functionality
858 3282 : TitleHelper* pTitleHelper = new TitleHelper( xContext );
859 3282 : m_xTitleHelper = css::uno::Reference< css::frame::XTitle >(static_cast< ::cppu::OWeakObject* >(pTitleHelper), css::uno::UNO_QUERY_THROW);
860 6564 : pTitleHelper->setOwner(xThis);
861 3282 : }
862 :
863 : /*-****************************************************************************************************
864 : @short returns current set container window
865 : @descr The ContainerWindow property is used as a container for the component
866 : in this frame. So this object implements a container interface too.
867 : The instantiation of the container window is done by the user of this class.
868 : The frame is the owner of its container window.
869 :
870 : @seealso method initialize()
871 : @return A reference to current set containerwindow.
872 :
873 : @onerror A null reference is returned.
874 : *//*-*****************************************************************************************************/
875 143749 : css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getContainerWindow() throw( css::uno::RuntimeException, std::exception )
876 : {
877 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
878 : // Register transaction and reject wrong calls.
879 143749 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
880 :
881 287498 : SolarMutexGuard g;
882 287498 : return m_xContainerWindow;
883 : }
884 :
885 : /*-****************************************************************************************************
886 : @short set parent frame
887 : @descr We need a parent to support some functionality! e.g. findFrame()
888 : By the way we use the chance to set an internal information about our top state.
889 : So we must not check this information during every isTop() call.
890 : We are top, if our parent is the desktop instance or we havent any parent.
891 :
892 : @seealso getCreator()
893 : @seealso findFrame()
894 : @seealso isTop()
895 : @seealos m_bIsFrameTop
896 :
897 : @param xCreator
898 : valid reference to our new owner frame, which should implement a supplier interface
899 :
900 : @threadsafe yes
901 : *//*-*****************************************************************************************************/
902 3282 : void SAL_CALL Frame::setCreator( const css::uno::Reference< css::frame::XFramesSupplier >& xCreator ) throw( css::uno::RuntimeException, std::exception )
903 : {
904 3282 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
905 :
906 : /* SAFE { */
907 6564 : SolarMutexClearableGuard aWriteLock;
908 3282 : m_xParent = xCreator;
909 3282 : aWriteLock.clear();
910 : /* } SAFE */
911 :
912 6564 : css::uno::Reference< css::frame::XDesktop > xIsDesktop( xCreator, css::uno::UNO_QUERY );
913 6564 : m_bIsFrameTop = ( xIsDesktop.is() || ! xCreator.is() );
914 3282 : }
915 :
916 : /*-****************************************************************************************************
917 : @short returns current parent frame
918 : @descr The Creator is the parent frame container. If it is NULL, the frame is the uppermost one.
919 :
920 : @seealso method setCreator()
921 : @return A reference to current set parent frame container.
922 :
923 : @onerror A null reference is returned.
924 : *//*-*****************************************************************************************************/
925 5534 : css::uno::Reference< css::frame::XFramesSupplier > SAL_CALL Frame::getCreator() throw( css::uno::RuntimeException, std::exception )
926 : {
927 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
928 : // Register transaction and reject wrong calls.
929 5534 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
930 :
931 11068 : SolarMutexGuard g;
932 11068 : return m_xParent;
933 : }
934 :
935 : /*-****************************************************************************************************
936 : @short returns current set name of frame
937 : @descr This name is used to find target of findFrame() or queryDispatch() calls.
938 :
939 : @seealso method setName()
940 : @return Current set name of frame.
941 :
942 : @onerror An empty string is returned.
943 : *//*-*****************************************************************************************************/
944 19065 : OUString SAL_CALL Frame::getName() throw( css::uno::RuntimeException, std::exception )
945 : {
946 19065 : SolarMutexGuard g;
947 19065 : return m_sName;
948 : }
949 :
950 : /*-****************************************************************************************************
951 : @short set new name for frame
952 : @descr This name is used to find target of findFrame() or queryDispatch() calls.
953 :
954 : @attention Special names like "_blank", "_self" aren't allowed ...
955 : "_beamer" or "_menubar" excepts this rule!
956 :
957 : @seealso method getName()
958 :
959 : @param "sName", new frame name.
960 : @onerror We do nothing.
961 : *//*-*****************************************************************************************************/
962 15 : void SAL_CALL Frame::setName( const OUString& sName ) throw( css::uno::RuntimeException, std::exception )
963 : {
964 15 : SolarMutexGuard g;
965 : // Set new name ... but look for invalid special target names!
966 : // They are not allowed to set.
967 15 : if (TargetHelper::isValidNameForFrame(sName))
968 15 : m_sName = sName;
969 15 : }
970 :
971 : /*-****************************************************************************************************
972 : @short search for frames
973 : @descr This method searches for a frame with the specified name.
974 : Frames may contain other frames (e.g. a frameset) and may
975 : be contained in other frames. This hierarchy is searched by
976 : this method.
977 : First some special names are taken into account, i.e. "",
978 : "_self", "_top", "_blank" etc. The nSearchFlags are ignored
979 : when comparing these names with sTargetFrameName, further steps are
980 : controlled by the search flags. If allowed, the name of the frame
981 : itself is compared with the desired one, then ( again if allowed )
982 : the method findFrame() is called for all children, for siblings
983 : and as last for the parent frame.
984 : If no frame with the given name is found until the top frames container,
985 : a new top one is created, if this is allowed by a special
986 : flag. The new frame also gets the desired name.
987 :
988 : @param sTargetFrameName
989 : special names (_blank, _self) or real name of target frame
990 : @param nSearchFlags
991 : optional flags which regulate search for non special target frames
992 :
993 : @return A reference to found or may be new created frame.
994 : @threadsafe yes
995 : *//*-*****************************************************************************************************/
996 2852 : css::uno::Reference< css::frame::XFrame > SAL_CALL Frame::findFrame( const OUString& sTargetFrameName,
997 : sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException, std::exception )
998 : {
999 2852 : css::uno::Reference< css::frame::XFrame > xTarget;
1000 :
1001 : // 0) Ignore wrong parameter!
1002 : // We don't support search for following special targets.
1003 : // If we reject this requests - we mustnt check for such names
1004 : // in following code again and again. If we do not so -wrong
1005 : // search results can occur!
1006 :
1007 2852 : if (
1008 5704 : (sTargetFrameName==SPECIALTARGET_DEFAULT ) || // valid for dispatches - not for findFrame()!
1009 2852 : (sTargetFrameName==SPECIALTARGET_MENUBAR ) // valid for dispatches - not for findFrame()!
1010 : )
1011 : {
1012 0 : return NULL;
1013 : }
1014 :
1015 : // I) check for special defined targets first which must be handled exclusive.
1016 : // force using of "if() else if() ..."
1017 :
1018 : // get threadsafe some necessary member which are necessary for following functionality
1019 : /* SAFE { */
1020 5704 : SolarMutexResettableGuard aReadLock;
1021 5704 : css::uno::Reference< css::frame::XFrame > xParent ( m_xParent, css::uno::UNO_QUERY );
1022 5704 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
1023 2852 : bool bIsTopFrame = m_bIsFrameTop;
1024 2852 : bool bIsTopWindow = WindowHelper::isTopWindow(m_xContainerWindow);
1025 2852 : aReadLock.clear();
1026 : /* } SAFE */
1027 :
1028 : // I.I) "_blank"
1029 : // Not allowed for a normal frame - but for the desktop.
1030 : // Use helper class to do so. It use the desktop automatically.
1031 :
1032 2852 : if ( sTargetFrameName==SPECIALTARGET_BLANK )
1033 : {
1034 0 : TaskCreator aCreator(xContext);
1035 0 : xTarget = aCreator.createTask(sTargetFrameName,false);
1036 : }
1037 :
1038 : // I.II) "_parent"
1039 : // It doesn't matter if we have a valid parent or not. User ask for him and get it.
1040 : // An empty result is a valid result too.
1041 :
1042 2852 : else if ( sTargetFrameName==SPECIALTARGET_PARENT )
1043 : {
1044 1 : xTarget = xParent;
1045 : }
1046 :
1047 : // I.III) "_top"
1048 : // If we are not the top frame in this hierarchy, we must forward request to our parent.
1049 : // Otherwhise we must return ourself.
1050 :
1051 2851 : else if ( sTargetFrameName==SPECIALTARGET_TOP )
1052 : {
1053 0 : if (bIsTopFrame)
1054 0 : xTarget = this;
1055 0 : else if (xParent.is()) // If we are not top - the parent MUST exist. But may it's better to check it again .-)
1056 0 : xTarget = xParent->findFrame(SPECIALTARGET_TOP,0);
1057 : }
1058 :
1059 : // I.IV) "_self", ""
1060 : // This mean this frame in every case.
1061 :
1062 2851 : else if (
1063 5618 : ( sTargetFrameName==SPECIALTARGET_SELF ) ||
1064 2767 : ( sTargetFrameName.isEmpty() )
1065 : )
1066 : {
1067 84 : xTarget = this;
1068 : }
1069 :
1070 : // I.V) "_beamer"
1071 : // This is a special sub frame of any task. We must return it if we found it on our direct children
1072 : // or create it there if it not already exists.
1073 : // Note: Such beamer exists for task(top) frames only!
1074 :
1075 2767 : else if ( sTargetFrameName==SPECIALTARGET_BEAMER )
1076 : {
1077 : // We are a task => search or create the beamer
1078 2767 : if (bIsTopWindow)
1079 : {
1080 2766 : xTarget = m_aChildFrameContainer.searchOnDirectChildrens(SPECIALTARGET_BEAMER);
1081 2766 : if ( ! xTarget.is() )
1082 : {
1083 : /* TODO
1084 : Creation not supported yet!
1085 : Wait for new layout manager service because we can't plug it
1086 : inside already opened document of this frame ...
1087 : */
1088 : }
1089 : }
1090 : // We arent a task => forward request to our parent or ignore it.
1091 1 : else if (xParent.is())
1092 1 : xTarget = xParent->findFrame(SPECIALTARGET_BEAMER,0);
1093 : }
1094 :
1095 : else
1096 : {
1097 :
1098 : // II) otherwise use optional given search flags
1099 : // force using of combinations of such flags. means no "else" part of use if() statements.
1100 : // But we ust break further searches if target was already found.
1101 : // Order of using flags is fix: SELF - CHILDREN - SIBLINGS - PARENT
1102 : // TASK and CREATE are handled special.
1103 :
1104 : // get threadsafe some necessary member which are necessary for following functionality
1105 : /* SAFE { */
1106 0 : aReadLock.reset();
1107 0 : OUString sOwnName = m_sName;
1108 0 : aReadLock.clear();
1109 : /* } SAFE */
1110 :
1111 : // II.I) SELF
1112 : // Check for right name. If it's the searched one return ourself - otherwise
1113 : // ignore this flag.
1114 :
1115 0 : if (
1116 0 : (nSearchFlags & css::frame::FrameSearchFlag::SELF) &&
1117 0 : (sOwnName == sTargetFrameName )
1118 : )
1119 : {
1120 0 : xTarget = this;
1121 : }
1122 :
1123 : // II.II) CHILDREN
1124 : // Search on all children for the given target name.
1125 : // An empty name value can't occur here - because it must be already handled as "_self"
1126 : // before. Used helper function of container doesn't create any frame.
1127 : // It makes a deep search only.
1128 :
1129 0 : if (
1130 0 : ( ! xTarget.is() ) &&
1131 0 : (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
1132 : )
1133 : {
1134 0 : xTarget = m_aChildFrameContainer.searchOnAllChildrens(sTargetFrameName);
1135 : }
1136 :
1137 : // II.III) TASKS
1138 : // This is a special flag. It regulate search on this task tree only or allow search on
1139 : // all other ones (which are sibling trees of us) too.
1140 : // Upper search must stop at this frame if we are the topest one and the TASK flag is not set
1141 : // or we can ignore it if we have no valid parent.
1142 :
1143 0 : if (
1144 0 : ( bIsTopFrame && (nSearchFlags & css::frame::FrameSearchFlag::TASKS) ) ||
1145 0 : ( ! bIsTopFrame )
1146 : )
1147 : {
1148 :
1149 : // II.III.I) SIBLINGS
1150 : // Search on all our direct siblings - means all children of our parent.
1151 : // Use this flag in combination with TASK. We must suppress such upper search if
1152 : // user has not set it and if we are a top frame.
1153 : // Attention: Don't forward this request to our parent as a findFrame() call.
1154 : // In such case we must protect us against recursive calls.
1155 : // Use snapshot of our parent. But don't use queryFrames() of XFrames interface.
1156 : // Because it's return all siblings and all her children including our children too
1157 : // if we call it with the CHILDREN flag. We don't need that - we need the direct container
1158 : // items of our parent only to start searches there. So we must use the container interface
1159 : // XIndexAccess instead of XFrames.
1160 :
1161 0 : if (
1162 0 : ( ! xTarget.is() ) &&
1163 0 : (nSearchFlags & css::frame::FrameSearchFlag::SIBLINGS) &&
1164 0 : ( xParent.is() ) // search on siblings is impossible without a parent
1165 : )
1166 : {
1167 0 : css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
1168 0 : if (xSupplier.is())
1169 : {
1170 0 : css::uno::Reference< css::container::XIndexAccess > xContainer( xSupplier->getFrames(), css::uno::UNO_QUERY );
1171 0 : if (xContainer.is())
1172 : {
1173 0 : sal_Int32 nCount = xContainer->getCount();
1174 0 : for( sal_Int32 i=0; i<nCount; ++i )
1175 : {
1176 0 : css::uno::Reference< css::frame::XFrame > xSibling;
1177 0 : if (
1178 0 : ( !(xContainer->getByIndex(i)>>=xSibling) ) || // control unpacking
1179 0 : ( ! xSibling.is() ) || // check for valid items
1180 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.)
1181 : )
1182 : {
1183 0 : continue;
1184 : }
1185 :
1186 : // Don't allow upper search here! Use right flags to regulate it.
1187 : // And allow deep search on children only - if it was allowed for us too.
1188 0 : sal_Int32 nRightFlags = css::frame::FrameSearchFlag::SELF;
1189 0 : if (nSearchFlags & css::frame::FrameSearchFlag::CHILDREN)
1190 0 : nRightFlags |= css::frame::FrameSearchFlag::CHILDREN;
1191 0 : xTarget = xSibling->findFrame(sTargetFrameName, nRightFlags );
1192 : // perform search be breaking further search if a result exist.
1193 0 : if (xTarget.is())
1194 0 : break;
1195 0 : }
1196 0 : }
1197 0 : }
1198 : }
1199 :
1200 : // II.III.II) PARENT
1201 : // Forward search to our parent (if he exists.)
1202 : // To prevent us against recursive and superflous calls (which can occur if we allow him
1203 : // to search on his children too) we must change used search flags.
1204 :
1205 0 : if (
1206 0 : ( ! xTarget.is() ) &&
1207 0 : (nSearchFlags & css::frame::FrameSearchFlag::PARENT) &&
1208 0 : ( xParent.is() )
1209 : )
1210 : {
1211 0 : if (xParent->getName() == sTargetFrameName)
1212 0 : xTarget = xParent;
1213 : else
1214 : {
1215 0 : sal_Int32 nRightFlags = nSearchFlags;
1216 0 : nRightFlags &= ~css::frame::FrameSearchFlag::CHILDREN;
1217 0 : xTarget = xParent->findFrame(sTargetFrameName, nRightFlags);
1218 : }
1219 : }
1220 : }
1221 :
1222 : // II.IV) CREATE
1223 : // If we haven't found any valid target frame by using normal flags - but user allowed us to create
1224 : // a new one ... we should do that. Used TaskCreator use Desktop instance automatically as parent!
1225 :
1226 0 : if (
1227 0 : ( ! xTarget.is() ) &&
1228 0 : (nSearchFlags & css::frame::FrameSearchFlag::CREATE)
1229 : )
1230 : {
1231 0 : TaskCreator aCreator(xContext);
1232 0 : xTarget = aCreator.createTask(sTargetFrameName,false);
1233 0 : }
1234 : }
1235 :
1236 5704 : return xTarget;
1237 : }
1238 :
1239 : /*-****************************************************************************************************
1240 : @descr Returns sal_True, if this frame is a "top frame", otherwise sal_False.
1241 : The "m_bIsFrameTop" member must be set in the ctor or setCreator() method.
1242 : A top frame is a member of the top frame container or a member of the
1243 : task frame container. Both containers can create new frames if the findFrame()
1244 : method of their css::frame::XFrame interface is called with a frame name not yet known.
1245 :
1246 : @seealso ctor
1247 : @seealso method setCreator()
1248 : @seealso method findFrame()
1249 : @return true, if is it a top frame ... false otherwise.
1250 :
1251 : @onerror No error should occur!
1252 : *//*-*****************************************************************************************************/
1253 16159 : sal_Bool SAL_CALL Frame::isTop() throw( css::uno::RuntimeException, std::exception )
1254 : {
1255 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1256 : // Register transaction and reject wrong calls.
1257 16159 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1258 :
1259 32318 : SolarMutexGuard g;
1260 : // This information is set in setCreator().
1261 : // We are top, if our parent is a task or the desktop or if no parent exist!
1262 32318 : return m_bIsFrameTop;
1263 : }
1264 :
1265 : /*-****************************************************************************************************
1266 : @short activate frame in hierarchy
1267 : @descr This feature is used to mark active paths in our frame hierarchy.
1268 : You can be a listener for this event to react for it ... change some internal states or something else.
1269 :
1270 : @seealso method deactivate()
1271 : @seealso method isActivate()
1272 : @seealso enum EActiveState
1273 : @seealso listener mechanism
1274 : *//*-*****************************************************************************************************/
1275 2886 : void SAL_CALL Frame::activate() throw( css::uno::RuntimeException, std::exception )
1276 : {
1277 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1278 : // Register transaction and reject wrong calls.
1279 2886 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1280 :
1281 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1282 5772 : SolarMutexResettableGuard aWriteLock;
1283 :
1284 : // Copy necessary member and free the lock.
1285 : // It's not necessary for m_aChildFrameContainer ... because
1286 : // he is threadsafe himself and live if we live.
1287 : // We use a registered transaction to prevent us against
1288 : // breaks during this operation!
1289 5772 : css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive();
1290 5772 : css::uno::Reference< css::frame::XFramesSupplier > xParent ( m_xParent, css::uno::UNO_QUERY );
1291 5772 : css::uno::Reference< css::frame::XFrame > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1292 5772 : css::uno::Reference< css::awt::XWindow > xComponentWindow( m_xComponentWindow, css::uno::UNO_QUERY );
1293 2886 : EActiveState eState = m_eActiveState;
1294 :
1295 2886 : aWriteLock.clear();
1296 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1297 :
1298 : // 1) If I'am not active before ...
1299 2886 : if( eState == E_INACTIVE )
1300 : {
1301 : // ... do it then.
1302 2884 : aWriteLock.reset();
1303 2884 : eState = E_ACTIVE;
1304 2884 : m_eActiveState = eState;
1305 2884 : aWriteLock.clear();
1306 : // Deactivate sibling path and forward activation to parent ... if any parent exist!
1307 2884 : if( xParent.is() )
1308 : {
1309 : // Every time set THIS frame as active child of parent and activate it.
1310 : // We MUST have a valid path from bottom to top as active path!
1311 : // But we must deactivate the old active sibling path first.
1312 :
1313 : // Attention: Deactivation of an active path, deactivate the whole path ... from bottom to top!
1314 : // But we wish to deactivate founded sibling-tree only.
1315 : // [ see deactivate() / step 4) for further information! ]
1316 :
1317 2884 : xParent->setActiveFrame( xThis );
1318 :
1319 : // Then we can activate from here to top.
1320 : // Attention: We are ACTIVE now. And the parent will call activate() at us!
1321 : // But we do nothing then! We are already activated.
1322 2884 : xParent->activate();
1323 : }
1324 : // Its necessary to send event NOW - not before.
1325 : // Activation goes from bottom to top!
1326 : // Thats the reason to activate parent first and send event now.
1327 2884 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_ACTIVATED );
1328 : }
1329 :
1330 : // 2) I was active before or current activated and there is a path from here to bottom, who CAN be active.
1331 : // But our direct child of path is not active yet.
1332 : // (It can be, if activation occur in the middle of a current path!)
1333 : // In these case we activate path to bottom to set focus on right frame!
1334 2886 : if ( eState == E_ACTIVE && xActiveChild.is() && !xActiveChild->isActive() )
1335 : {
1336 0 : xActiveChild->activate();
1337 : }
1338 :
1339 : // 3) I was active before or current activated. But if I have no active child => I will get the focus!
1340 2886 : if ( eState == E_ACTIVE && !xActiveChild.is() )
1341 : {
1342 2884 : aWriteLock.reset();
1343 2884 : eState = E_FOCUS;
1344 2884 : m_eActiveState = eState;
1345 2884 : aWriteLock.clear();
1346 2884 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_ACTIVATED );
1347 2886 : }
1348 2886 : }
1349 :
1350 : /*-****************************************************************************************************
1351 : @short deactivate frame in hierarchy
1352 : @descr This feature is used to deactive paths in our frame hierarchy.
1353 : You can be a listener for this event to react for it ... change some internal states or something else.
1354 :
1355 : @seealso method activate()
1356 : @seealso method isActivate()
1357 : @seealso enum EActiveState
1358 : @seealso listener mechanism
1359 : *//*-*****************************************************************************************************/
1360 22 : void SAL_CALL Frame::deactivate() throw( css::uno::RuntimeException, std::exception )
1361 : {
1362 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1363 : // Register transaction and reject wrong calls.
1364 22 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1365 :
1366 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1367 44 : SolarMutexResettableGuard aWriteLock;
1368 :
1369 : // Copy necessary member and free the lock.
1370 44 : css::uno::Reference< css::frame::XFrame > xActiveChild = m_aChildFrameContainer.getActive();
1371 44 : css::uno::Reference< css::frame::XFramesSupplier > xParent ( m_xParent, css::uno::UNO_QUERY );
1372 44 : css::uno::Reference< css::frame::XFrame > xThis ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1373 22 : EActiveState eState = m_eActiveState;
1374 :
1375 22 : aWriteLock.clear();
1376 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1377 :
1378 : // Work only, if there something to do!
1379 22 : if( eState != E_INACTIVE )
1380 : {
1381 :
1382 : // 1) Deactivate all active children.
1383 22 : if ( xActiveChild.is() && xActiveChild->isActive() )
1384 : {
1385 0 : xActiveChild->deactivate();
1386 : }
1387 :
1388 : // 2) If I have the focus - I will lost it now.
1389 22 : if( eState == E_FOCUS )
1390 : {
1391 : // Set new state INACTIVE(!) and send message to all listener.
1392 : // Don't set ACTIVE as new state. This frame is deactivated for next time - due to activate().
1393 22 : aWriteLock.reset();
1394 22 : eState = E_ACTIVE;
1395 22 : m_eActiveState = eState;
1396 22 : aWriteLock.clear();
1397 22 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_UI_DEACTIVATING );
1398 : }
1399 :
1400 : // 3) If I'am active - I will be deactivated now.
1401 22 : if( eState == E_ACTIVE )
1402 : {
1403 : // Set new state and send message to all listener.
1404 22 : aWriteLock.reset();
1405 22 : eState = E_INACTIVE;
1406 22 : m_eActiveState = eState;
1407 22 : aWriteLock.clear();
1408 22 : implts_sendFrameActionEvent( css::frame::FrameAction_FRAME_DEACTIVATING );
1409 : }
1410 :
1411 : // 4) If there is a path from here to my parent ...
1412 : // ... I'am on the top or in the middle of deactivated subtree and action was started here.
1413 : // I must deactivate all frames from here to top, which are members of current path.
1414 : // Stop, if THESE frame not the active frame of our parent!
1415 22 : if ( xParent.is() && xParent->getActiveFrame() == xThis )
1416 : {
1417 : // We MUST break the path - otherwise we will get the focus - not our parent! ...
1418 : // Attention: Our parent don't call us again - WE ARE NOT ACTIVE YET!
1419 : // [ see step 3 and condition "if ( m_eActiveState!=INACTIVE ) ..." in this method! ]
1420 0 : xParent->deactivate();
1421 : }
1422 22 : }
1423 22 : }
1424 :
1425 : /*-****************************************************************************************************
1426 : @short returns active state
1427 : @descr Call it to get information about current active state of this frame.
1428 :
1429 : @seealso method activate()
1430 : @seealso method deactivate()
1431 : @seealso enum EActiveState
1432 : @return true if active, false otherwise.
1433 :
1434 : @onerror No error should occur.
1435 : *//*-*****************************************************************************************************/
1436 3312 : sal_Bool SAL_CALL Frame::isActive() throw( css::uno::RuntimeException, std::exception )
1437 : {
1438 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1439 : // Register transaction and reject wrong calls.
1440 3312 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1441 :
1442 6624 : SolarMutexGuard g;
1443 : return (
1444 6622 : ( m_eActiveState == E_ACTIVE ) ||
1445 3310 : ( m_eActiveState == E_FOCUS )
1446 6624 : );
1447 : }
1448 :
1449 : /*-****************************************************************************************************
1450 : @short ???
1451 : *//*-*****************************************************************************************************/
1452 6211 : void SAL_CALL Frame::contextChanged() throw( css::uno::RuntimeException, std::exception )
1453 : {
1454 : // Look for rejected calls!
1455 : // Sometimes called during closing object... => soft exceptions
1456 6211 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1457 : // Impl-method is threadsafe himself!
1458 : // Send event to all listener for frame actions.
1459 6211 : implts_sendFrameActionEvent( css::frame::FrameAction_CONTEXT_CHANGED );
1460 6211 : }
1461 :
1462 : /*-****************************************************************************************************
1463 : @short set new component inside the frame
1464 : @descr A frame is a container for a component. Use this method to set, change or release it!
1465 : We accept null references! The xComponentWindow will be a child of our container window
1466 : and get all window events from us.
1467 :
1468 : @attention (a) A current set component can disagree with the suspend() request!
1469 : We don't set the new one and return with false then.
1470 : (b) It's possible to set:
1471 : (b1) a simple component here which supports the window only - no controller;
1472 : (b2) a full featured component which supports window and controller;
1473 : (b3) or both to NULL if outside code which to forget this component.
1474 :
1475 : @seealso method getComponentWindow()
1476 : @seealso method getController()
1477 :
1478 : @param xComponentWindow
1479 : valid reference to new component window which will be a child of internal container window
1480 : May <NULL/> for releasing.
1481 : @param xController
1482 : reference to new component controller
1483 : (may <NULL/> for relasing or setting of a simple component)
1484 :
1485 : @return <TRUE/> if operation was successful, <FALSE/> otherwise.
1486 :
1487 : @onerror We return <FALSE/>.
1488 : @threadsafe yes
1489 : *//*-*****************************************************************************************************/
1490 6566 : sal_Bool SAL_CALL Frame::setComponent( const css::uno::Reference< css::awt::XWindow >& xComponentWindow ,
1491 : const css::uno::Reference< css::frame::XController >& xController ) throw( css::uno::RuntimeException, std::exception )
1492 : {
1493 :
1494 : // Ignore this HACK of sfx2!
1495 : // He call us with an valid controller without a valid window ... Thats not allowed!
1496 6566 : if ( xController.is() && ! xComponentWindow.is() )
1497 0 : return sal_True;
1498 :
1499 6566 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1500 :
1501 : // Get threadsafe some copies of used members.
1502 : /* SAFE { */
1503 13132 : SolarMutexClearableGuard aReadLock;
1504 13132 : css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
1505 13132 : css::uno::Reference< css::awt::XWindow > xOldComponentWindow = m_xComponentWindow;
1506 13132 : css::uno::Reference< css::frame::XController > xOldController = m_xController;
1507 6566 : vcl::Window* pOwnWindow = VCLUnoHelper::GetWindow( xContainerWindow );
1508 6566 : bool bHadFocus = pOwnWindow->HasChildPathFocus();
1509 6566 : bool bWasConnected = m_bConnected;
1510 6566 : aReadLock.clear();
1511 : /* } SAFE */
1512 :
1513 : // stop listening on old window
1514 : // May it produce some trouble.
1515 : // But don't forget to listen on new window again ... or reactivate listening
1516 : // if we reject this setComponent() request and leave this method without changing the old window.
1517 6566 : implts_stopWindowListening();
1518 :
1519 : // Notify all listener, that this component (if current one exist) will be unloaded.
1520 6566 : if (bWasConnected)
1521 3284 : implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_DETACHING );
1522 :
1523 : // otherwise release old component first
1524 : // Always release controller before releasing window,
1525 : // because controller may want to access its window!
1526 : // But check for real changes - may the new controller is the old one.
1527 6566 : if (
1528 9850 : (xOldController.is() ) &&
1529 3284 : (xOldController != xController)
1530 : )
1531 : {
1532 : /* ATTENTION
1533 : Don't suspend the old controller here. Because the outside caller must do that
1534 : by definition. We have to dispose it here only.
1535 : */
1536 :
1537 : // Before we dispose this controller we should hide it inside this frame instance.
1538 : // We hold it alive for next calls by using xOldController!
1539 : /* SAFE {*/
1540 3284 : SolarMutexClearableGuard aWriteLock;
1541 3284 : m_xController = NULL;
1542 3284 : aWriteLock.clear();
1543 : /* } SAFE */
1544 :
1545 6568 : css::uno::Reference< css::lang::XComponent > xDisposable( xOldController, css::uno::UNO_QUERY );
1546 3284 : if (xDisposable.is())
1547 : {
1548 : try
1549 : {
1550 3284 : xDisposable->dispose();
1551 : }
1552 0 : catch(const css::lang::DisposedException&)
1553 : {}
1554 : }
1555 6568 : xOldController = NULL;
1556 : }
1557 :
1558 : // Now it's time to release the component window.
1559 : // If controller wasn't released successfully - this code line shouldn't be reached.
1560 : // Because in case of "suspend()==false" we return immediately with false ...
1561 : // see before
1562 : // Check for real changes too.
1563 6566 : if (
1564 9850 : (xOldComponentWindow.is() ) &&
1565 3284 : (xOldComponentWindow != xComponentWindow)
1566 : )
1567 : {
1568 : /* SAFE { */
1569 3269 : SolarMutexClearableGuard aWriteLock;
1570 3269 : m_xComponentWindow = NULL;
1571 3269 : aWriteLock.clear();
1572 : /* } SAFE */
1573 :
1574 6538 : css::uno::Reference< css::lang::XComponent > xDisposable( xOldComponentWindow, css::uno::UNO_QUERY );
1575 3269 : if (xDisposable.is())
1576 : {
1577 : try
1578 : {
1579 3269 : xDisposable->dispose();
1580 : }
1581 0 : catch(const css::lang::DisposedException&)
1582 : {
1583 : }
1584 : }
1585 6538 : xOldComponentWindow = NULL;
1586 : }
1587 :
1588 : // Now it's time to set the new component ...
1589 : // By the way - find out our new "load state" - means if we have a valid component inside.
1590 : /* SAFE { */
1591 13132 : SolarMutexResettableGuard aWriteLock;
1592 6566 : m_xComponentWindow = xComponentWindow;
1593 6566 : m_xController = xController;
1594 6566 : m_bConnected = (m_xComponentWindow.is() || m_xController.is());
1595 6566 : bool bIsConnected = m_bConnected;
1596 6566 : aWriteLock.clear();
1597 : /* } SAFE */
1598 :
1599 : // notifies all interest listener, that current component was changed or a new one was loaded
1600 6566 : if (bIsConnected && bWasConnected)
1601 16 : implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_REATTACHED );
1602 6550 : else if (bIsConnected && !bWasConnected)
1603 3277 : implts_sendFrameActionEvent( css::frame::FrameAction_COMPONENT_ATTACHED );
1604 :
1605 : // A new component window doesn't know anything about current active/focus states.
1606 : // Set this information on it!
1607 6566 : if (
1608 11778 : (bHadFocus ) &&
1609 5212 : (xComponentWindow.is())
1610 : )
1611 : {
1612 2355 : xComponentWindow->setFocus();
1613 : }
1614 :
1615 : // If it was a new component window - we must resize it to fill out
1616 : // our container window.
1617 6566 : implts_resizeComponentWindow();
1618 : // New component should change our current icon ...
1619 6566 : implts_setIconOnWindow();
1620 : // OK - start listening on new window again - or do nothing if it is an empty one.
1621 6566 : implts_startWindowListening();
1622 :
1623 : /* SAFE { */
1624 6566 : aWriteLock.reset();
1625 6566 : impl_checkMenuCloser();
1626 6566 : aWriteLock.clear();
1627 : /* } SAFE */
1628 :
1629 13132 : return sal_True;
1630 : }
1631 :
1632 : /*-****************************************************************************************************
1633 : @short returns current set component window
1634 : @descr Frames are used to display components. The actual displayed component is
1635 : held by the m_xComponentWindow property. If the component implements only a
1636 : XComponent interface, the communication between the frame and the
1637 : component is very restricted. Better integration is achievable through a
1638 : XController interface.
1639 : If the component wants other objects to be able to get information about its
1640 : ResourceDescriptor it has to implement a XModel interface.
1641 : This frame is the owner of the component window.
1642 :
1643 : @seealso method setComponent()
1644 : @return css::uno::Reference to current set component window.
1645 :
1646 : @onerror A null reference is returned.
1647 : *//*-*****************************************************************************************************/
1648 371282 : css::uno::Reference< css::awt::XWindow > SAL_CALL Frame::getComponentWindow() throw( css::uno::RuntimeException, std::exception )
1649 : {
1650 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1651 : // Register transaction and reject wrong calls.
1652 371282 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1653 :
1654 742546 : SolarMutexGuard g;
1655 742546 : return m_xComponentWindow;
1656 : }
1657 :
1658 : /*-****************************************************************************************************
1659 : @short returns current set controller
1660 : @descr Frames are used to display components. The actual displayed component is
1661 : held by the m_xComponentWindow property. If the component implements only a
1662 : XComponent interface, the communication between the frame and the
1663 : component is very restricted. Better integration is achievable through a
1664 : XController interface.
1665 : If the component wants other objects to be able to get information about its
1666 : ResourceDescriptor it has to implement a XModel interface.
1667 : This frame is the owner of the component window.
1668 :
1669 : @seealso method setComponent()
1670 : @return css::uno::Reference to current set controller.
1671 :
1672 : @onerror A null reference is returned.
1673 : *//*-*****************************************************************************************************/
1674 831071 : css::uno::Reference< css::frame::XController > SAL_CALL Frame::getController() throw( css::uno::RuntimeException, std::exception )
1675 : {
1676 831071 : SolarMutexGuard g;
1677 831071 : return m_xController;
1678 : }
1679 :
1680 : /*-****************************************************************************************************
1681 : @short add/remove listener for activate/deactivate/contextChanged events
1682 : @seealso method activate()
1683 : @seealso method deactivate()
1684 : @seealso method contextChanged()
1685 :
1686 : @param "xListener" reference to your listener object
1687 : @onerror Listener is ignored.
1688 : *//*-*****************************************************************************************************/
1689 55161 : void SAL_CALL Frame::addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
1690 : {
1691 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1692 : // Check incoming parameter.
1693 : SAL_WARN_IF( implcp_addFrameActionListener( xListener ), "fwk", "Frame::addFrameActionListener(): Invalid parameter detected." );
1694 : // Listener container is threadsafe by himself ... but we must look for rejected calls!
1695 : // Our OMenuDispatch-helper (is a member of ODispatchProvider!) is create at startup of this frame BEFORE initialize!
1696 : // => soft exceptions!
1697 55161 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1698 :
1699 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1700 55161 : m_aListenerContainer.addInterface( cppu::UnoType<css::frame::XFrameActionListener>::get(), xListener );
1701 55161 : }
1702 :
1703 48482 : void SAL_CALL Frame::removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
1704 : {
1705 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
1706 : // Check incoming parameter.
1707 : SAL_WARN_IF( implcp_removeFrameActionListener( xListener ), "fwk", "Frame::removeFrameActionListener(): Invalid parameter detected." );
1708 : // Listener container is threadsafe by himself ... but we must look for rejected calls after disposing!
1709 : // But we must work with E_SOFTEXCEPTIONS ... because sometimes we are called from our listeners
1710 : // during dispose! Our work mode is E_BEFORECLOSE then ... and E_HARDEXCEPTIONS whould throw a DisposedException.
1711 48482 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1712 :
1713 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1714 48482 : m_aListenerContainer.removeInterface( cppu::UnoType<css::frame::XFrameActionListener>::get(), xListener );
1715 48482 : }
1716 :
1717 : /*-****************************************************************************************************
1718 : @short support two way mechanism to release a frame
1719 : @descr This method ask internal component (controller) if he accept this close request.
1720 : In case of <TRUE/> nothing will be happen (from point of caller of this close method).
1721 : In case of <FALSE/> a CloseVetoException is thrown. After such exception given parameter
1722 : <var>bDeliverOwnership</var> regulate which will be the new owner of this instance.
1723 :
1724 : @attention It's the replacement for XTask::close() which is marked as obsolete method.
1725 :
1726 : @param bDeliverOwnership
1727 : If parameter is set to <FALSE/> the original caller will be the owner after thrown
1728 : veto exception and must try to close this frame at later time again. Otherwhise the
1729 : source of throwed exception is the right one. May it will be the frame himself.
1730 :
1731 : @throws CloseVetoException
1732 : if any internal things willn't be closed
1733 :
1734 : @threadsafe yes
1735 : *//*-*****************************************************************************************************/
1736 3274 : void SAL_CALL Frame::close( sal_Bool bDeliverOwnership ) throw( css::util::CloseVetoException,
1737 : css::uno::RuntimeException, std::exception )
1738 : {
1739 3274 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1740 :
1741 : // At the end of this method may we must dispose ourself ...
1742 : // and may nobody from outside hold a reference to us ...
1743 : // then it's a good idea to do that by ourself.
1744 6548 : css::uno::Reference< css::uno::XInterface > xSelfHold( static_cast< ::cppu::OWeakObject* >(this) );
1745 :
1746 : // Check any close listener before we look for currently running internal processes.
1747 : // Because if a listener disagree with this close() request - we hace time to finish this
1748 : // internal operations too ...
1749 : // Note: container is threadsafe himself.
1750 6548 : css::lang::EventObject aSource (static_cast< ::cppu::OWeakObject*>(this));
1751 3274 : ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<css::util::XCloseListener>::get());
1752 3274 : if (pContainer!=NULL)
1753 : {
1754 3244 : ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
1755 9730 : while (pIterator.hasMoreElements())
1756 : {
1757 : try
1758 : {
1759 3242 : static_cast<css::util::XCloseListener*>(pIterator.next())->queryClosing( aSource, bDeliverOwnership );
1760 : }
1761 0 : catch( const css::uno::RuntimeException& )
1762 : {
1763 0 : pIterator.remove();
1764 : }
1765 3244 : }
1766 : }
1767 :
1768 : // Ok - no listener disagreed with this close() request
1769 : // check if this frame is used for any load process currently
1770 3274 : if (isActionLocked())
1771 : {
1772 1 : if (bDeliverOwnership)
1773 : {
1774 1 : SolarMutexGuard g;
1775 1 : m_bSelfClose = true;
1776 : }
1777 :
1778 1 : throw css::util::CloseVetoException("Frame in use for loading document ...",static_cast< ::cppu::OWeakObject*>(this));
1779 : }
1780 :
1781 3273 : if ( ! setComponent(NULL,NULL) )
1782 0 : throw css::util::CloseVetoException("Component couldn't be deattached ...",static_cast< ::cppu::OWeakObject*>(this));
1783 :
1784 : // If closing is allowed ... inform all istener and dispose this frame!
1785 3273 : pContainer = m_aListenerContainer.getContainer( cppu::UnoType<css::util::XCloseListener>::get());
1786 3273 : if (pContainer!=NULL)
1787 : {
1788 3244 : ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
1789 6488 : while (pIterator.hasMoreElements())
1790 : {
1791 : try
1792 : {
1793 0 : static_cast<css::util::XCloseListener*>(pIterator.next())->notifyClosing( aSource );
1794 : }
1795 0 : catch( const css::uno::RuntimeException& )
1796 : {
1797 0 : pIterator.remove();
1798 : }
1799 3244 : }
1800 : }
1801 :
1802 : /* SAFE { */
1803 6546 : SolarMutexClearableGuard aWriteLock;
1804 3273 : m_bIsHidden = true;
1805 3273 : aWriteLock.clear();
1806 : /* } SAFE */
1807 3273 : impl_checkMenuCloser();
1808 :
1809 : // Attention: We must release our own registered transaction here. Otherwhise following dispose() call
1810 : // wait for us too ....
1811 3273 : aTransaction.stop();
1812 6547 : dispose();
1813 3273 : }
1814 :
1815 : /*-****************************************************************************************************
1816 : @short be a listener for close events!
1817 : @descr Adds/remove a CloseListener at this frame instance. If the close() method is called on
1818 : this object, the such listener are informed and can disagree with that by throwing
1819 : a CloseVetoException.
1820 :
1821 : @seealso Frame::close()
1822 :
1823 : @param xListener
1824 : reference to your listener object
1825 :
1826 : @onerror Listener is ignored.
1827 :
1828 : @threadsafe yes
1829 : *//*-*****************************************************************************************************/
1830 3266 : void SAL_CALL Frame::addCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException, std::exception)
1831 : {
1832 3266 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1833 : // We don't need any lock here ...
1834 : // Container lives if we live and is threadsafe by himself.
1835 3266 : m_aListenerContainer.addInterface( cppu::UnoType<css::util::XCloseListener>::get(), xListener );
1836 3266 : }
1837 :
1838 3259 : void SAL_CALL Frame::removeCloseListener( const css::uno::Reference< css::util::XCloseListener >& xListener ) throw (css::uno::RuntimeException, std::exception)
1839 : {
1840 : // Use soft exception mode - moslty this method is called during disposing of this frame ...
1841 3259 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
1842 : // We don't need any lock here ...
1843 : // Container lives if we live and is threadsafe by himself.
1844 3259 : m_aListenerContainer.removeInterface( cppu::UnoType<css::util::XCloseListener>::get(), xListener );
1845 3259 : }
1846 :
1847 9940 : OUString SAL_CALL Frame::getTitle()
1848 : throw (css::uno::RuntimeException, std::exception)
1849 : {
1850 9940 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1851 :
1852 : // SAFE ->
1853 19880 : SolarMutexClearableGuard aReadLock;
1854 19880 : css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1855 9940 : aReadLock.clear();
1856 : // <- SAFE
1857 :
1858 19880 : return xTitle->getTitle();
1859 : }
1860 :
1861 1 : void SAL_CALL Frame::setTitle( const OUString& sTitle )
1862 : throw (css::uno::RuntimeException, std::exception)
1863 : {
1864 1 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1865 :
1866 : // SAFE ->
1867 2 : SolarMutexClearableGuard aReadLock;
1868 2 : css::uno::Reference< css::frame::XTitle > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1869 1 : aReadLock.clear();
1870 : // <- SAFE
1871 :
1872 2 : xTitle->setTitle(sTitle);
1873 1 : }
1874 :
1875 3279 : void SAL_CALL Frame::addTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener)
1876 : throw (css::uno::RuntimeException, std::exception)
1877 : {
1878 3279 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1879 :
1880 : // SAFE ->
1881 6558 : SolarMutexClearableGuard aReadLock;
1882 6558 : css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1883 3279 : aReadLock.clear();
1884 : // <- SAFE
1885 :
1886 6558 : xTitle->addTitleChangeListener(xListener);
1887 3279 : }
1888 :
1889 0 : void SAL_CALL Frame::removeTitleChangeListener( const css::uno::Reference< css::frame::XTitleChangeListener >& xListener )
1890 : throw (css::uno::RuntimeException, std::exception)
1891 : {
1892 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1893 :
1894 : // SAFE ->
1895 0 : SolarMutexClearableGuard aReadLock;
1896 0 : css::uno::Reference< css::frame::XTitleChangeBroadcaster > xTitle(m_xTitleHelper, css::uno::UNO_QUERY_THROW);
1897 0 : aReadLock.clear();
1898 : // <- SAFE
1899 :
1900 0 : xTitle->removeTitleChangeListener(xListener);
1901 0 : }
1902 :
1903 0 : css::uno::Reference<css::container::XNameContainer> SAL_CALL Frame::getUserDefinedAttributes() throw (css::uno::RuntimeException, std::exception)
1904 : {
1905 : // optional attribute
1906 0 : return 0;
1907 : }
1908 :
1909 0 : css::uno::Reference<css::frame::XDispatchRecorderSupplier> SAL_CALL Frame::getDispatchRecorderSupplier() throw (css::uno::RuntimeException, std::exception)
1910 : {
1911 0 : SolarMutexGuard g;
1912 0 : return m_xDispatchRecorderSupplier;
1913 : }
1914 :
1915 0 : void SAL_CALL Frame::setDispatchRecorderSupplier(const css::uno::Reference<css::frame::XDispatchRecorderSupplier>& p) throw (css::uno::RuntimeException, std::exception)
1916 : {
1917 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1918 :
1919 0 : SolarMutexGuard g;
1920 0 : m_xDispatchRecorderSupplier.set(p);
1921 0 : }
1922 :
1923 1 : css::uno::Reference<css::uno::XInterface> SAL_CALL Frame::getLayoutManager() throw (css::uno::RuntimeException, std::exception)
1924 : {
1925 1 : SolarMutexGuard g;
1926 1 : return m_xLayoutManager;
1927 : }
1928 :
1929 0 : void SAL_CALL Frame::setLayoutManager(const css::uno::Reference<css::uno::XInterface>& p1) throw (css::uno::RuntimeException, std::exception)
1930 : {
1931 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
1932 :
1933 0 : SolarMutexGuard g;
1934 0 : m_xLayoutManager.set(p1, css::uno::UNO_QUERY);
1935 0 : }
1936 :
1937 : /*-****************************************************************************************************/
1938 3274 : void Frame::implts_forgetSubFrames()
1939 : {
1940 : // SAFE ->
1941 3274 : SolarMutexClearableGuard aReadLock;
1942 6548 : css::uno::Reference< css::container::XIndexAccess > xContainer(m_xFramesHelper, css::uno::UNO_QUERY_THROW);
1943 3274 : aReadLock.clear();
1944 : // <- SAFE
1945 :
1946 3274 : sal_Int32 c = xContainer->getCount();
1947 3274 : sal_Int32 i = 0;
1948 :
1949 3274 : for (i=0; i<c; ++i)
1950 : {
1951 : try
1952 : {
1953 0 : css::uno::Reference< css::frame::XFrame > xFrame;
1954 0 : xContainer->getByIndex(i) >>= xFrame;
1955 0 : if (xFrame.is())
1956 0 : xFrame->setCreator(css::uno::Reference< css::frame::XFramesSupplier >());
1957 : }
1958 0 : catch(const css::uno::Exception&)
1959 : {
1960 : // Ignore errors here.
1961 : // Nobody can guarantee a stable index in multi threaded environments .-)
1962 : }
1963 : }
1964 :
1965 6548 : SolarMutexGuard g;
1966 3274 : m_xFramesHelper.clear(); // clear uno reference
1967 6548 : m_aChildFrameContainer.clear(); // clear container content
1968 3274 : }
1969 :
1970 : /*-****************************************************************************************************
1971 : @short destroy instance
1972 : @descr The owner of this object calles the dispose method if the object
1973 : should be destroyed. All other objects and components, that are registered
1974 : as an EventListener are forced to release their references to this object.
1975 : Furthermore this frame is removed from its parent frame container to release
1976 : this reference. The reference attributes are disposed and released also.
1977 :
1978 : @attention Look for globale description at beginning of file too!
1979 : (DisposedException, FairRWLock ..., initialize, dispose)
1980 :
1981 : @seealso method initialize()
1982 : @seealso baseclass FairRWLockBase!
1983 : *//*-*****************************************************************************************************/
1984 3276 : void SAL_CALL Frame::dispose() throw( css::uno::RuntimeException, std::exception )
1985 : {
1986 : // We should hold a reference to ourself ...
1987 : // because our owner dispose us and release our reference ...
1988 : // May be we will die before we could finish this method ...
1989 3276 : css::uno::Reference< css::frame::XFrame > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
1990 :
1991 : SAL_INFO("fwk.frame", "[Frame] " << m_sName << " send dispose event to listener");
1992 :
1993 : // First operation should be ... "stopp all listening for window events on our container window".
1994 : // These events are superflous but can make trouble!
1995 : // We will die, die and die ...
1996 3276 : implts_stopWindowListening();
1997 :
1998 3274 : if (m_xLayoutManager.is())
1999 3274 : lcl_disableLayoutManager(m_xLayoutManager, this);
2000 :
2001 3274 : delete m_pWindowCommandDispatch;
2002 :
2003 : // Send message to all listener and forget her references.
2004 6548 : css::lang::EventObject aEvent( xThis );
2005 3274 : m_aListenerContainer.disposeAndClear( aEvent );
2006 :
2007 : // set "end of live" for our property set helper
2008 3274 : impl_disablePropertySet();
2009 :
2010 : // interception/dispatch chain must be destructed explicitly
2011 : // Otherwhise some dispatches and/or interception objects wont die.
2012 6548 : css::uno::Reference< css::lang::XEventListener > xDispatchHelper(m_xDispatchHelper, css::uno::UNO_QUERY_THROW);
2013 3274 : xDispatchHelper->disposing(aEvent);
2014 3274 : xDispatchHelper.clear();
2015 :
2016 : // Disable this instance for further work.
2017 : // This will wait for all current running ones ...
2018 : // and reject all further requests!
2019 3274 : m_aTransactionManager.setWorkingMode( E_BEFORECLOSE );
2020 :
2021 : // Don't show any dialogs, errors or something else any more!
2022 : // If somewhere called dispose() whitout close() before - normally no dialogs
2023 : // should exist. Otherwhise it's the problem of the outside caller.
2024 : // Note:
2025 : // (a) Do it after stopWindowListening(). May that force some active/deactive
2026 : // notifications which we don't need here really.
2027 : // (b) Don't forget to save the old value of IsDialogCancelEnabled() to
2028 : // restore it afterwards (to not kill headless mode).
2029 3274 : Application::DialogCancelMode old = Application::GetDialogCancelMode();
2030 3274 : Application::SetDialogCancelMode( Application::DIALOG_CANCEL_SILENT );
2031 :
2032 : // We should be alone for ever and further dispose calls are rejected by lines before ...
2033 : // I hope it :-)
2034 :
2035 : // Free references of our frame tree.
2036 : // Force parent container to forget this frame too ...
2037 : // ( It's contained in m_xParent and so no css::lang::XEventListener for m_xParent! )
2038 : // It's important to do that before we free some other internal structures.
2039 : // Because if our parent gets an activate and found us as last possible active frame
2040 : // he try to deactivate us ... and we run into some trouble (DisposedExceptions!).
2041 3274 : if( m_xParent.is() )
2042 : {
2043 3273 : m_xParent->getFrames()->remove( xThis );
2044 3273 : m_xParent = css::uno::Reference< css::frame::XFramesSupplier >();
2045 : }
2046 :
2047 : /* } SAFE */
2048 : // Forget our internal component and her window first.
2049 : // So we can release our container window later without problems.
2050 : // Because this container window is the parent of the component window ...
2051 : // Note: Dispose it hard - because suspending must be done inside close() call!
2052 : // But try to dispose the controller first before you destroy the window.
2053 : // Because the window is used by the controller too ...
2054 3274 : if (m_xController.is())
2055 : {
2056 0 : css::uno::Reference< css::lang::XComponent > xDisposable( m_xController, css::uno::UNO_QUERY );
2057 0 : if (xDisposable.is())
2058 0 : xDisposable->dispose();
2059 : }
2060 :
2061 3274 : if (m_xComponentWindow.is())
2062 : {
2063 0 : css::uno::Reference< css::lang::XComponent > xDisposable( m_xComponentWindow, css::uno::UNO_QUERY );
2064 0 : if (xDisposable.is())
2065 0 : xDisposable->dispose();
2066 : }
2067 :
2068 3274 : impl_checkMenuCloser();
2069 :
2070 3274 : impl_disposeContainerWindow( m_xContainerWindow );
2071 :
2072 : /*ATTENTION
2073 : Clear container after successful removing from parent container ...
2074 : because our parent could be the desktop which stand in dispose too!
2075 : If we have already cleared our own container we lost our child before this could be
2076 : remove himself at this instance ...
2077 : Release m_xFramesHelper after that ... it's the same problem between parent and child!
2078 : "m_xParent->getFrames()->remove( xThis );" needs this helper ...
2079 : Otherwise we get a null reference and could finish removing successfully.
2080 : => You see: Order of calling operations is important!!!
2081 : */
2082 3274 : implts_forgetSubFrames();
2083 :
2084 : // Release some other references.
2085 : // This calls should be easy ... I hope it :-)
2086 3274 : m_xDispatchHelper.clear();
2087 3274 : m_xContext.clear();
2088 3274 : m_xDropTargetListener.clear();
2089 3274 : m_xDispatchRecorderSupplier.clear();
2090 3274 : m_xLayoutManager.clear();
2091 3274 : m_xIndicatorFactoryHelper.clear();
2092 :
2093 : // It's important to set default values here!
2094 : // If may be later somewhere change the disposed-behaviour of this implementation
2095 : // and doesn't throw any DisposedExceptions we must guarantee best matching default values ...
2096 3274 : m_eActiveState = E_INACTIVE;
2097 3274 : m_sName.clear();
2098 3274 : m_bIsFrameTop = false;
2099 3274 : m_bConnected = false;
2100 3274 : m_nExternalLockCount = 0;
2101 3274 : m_bSelfClose = false;
2102 3274 : m_bIsHidden = true;
2103 :
2104 : // Disable this instance for further working really!
2105 3274 : m_aTransactionManager.setWorkingMode( E_CLOSE );
2106 :
2107 : // Don't forget it restore old value -
2108 : // otherwise no dialogs can be shown anymore in other frames.
2109 6550 : Application::SetDialogCancelMode( old );
2110 3274 : }
2111 :
2112 : /*-****************************************************************************************************
2113 : @short Be a listener for dispose events!
2114 : @descr Adds/remove an EventListener to this object. If the dispose method is called on
2115 : this object, the disposing method of the listener is called.
2116 : @param "xListener" reference to your listener object.
2117 : @onerror Listener is ignored.
2118 : *//*-*****************************************************************************************************/
2119 3648 : void SAL_CALL Frame::addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
2120 : {
2121 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2122 : // Check incoming parameter.
2123 : SAL_WARN_IF( implcp_addEventListener( xListener ), "fwk", "Frame::addEventListener(): Invalid parameter detected." );
2124 : // Look for rejected calls only!
2125 : // Container is threadsafe.
2126 3648 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2127 :
2128 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2129 3648 : m_aListenerContainer.addInterface( cppu::UnoType<css::lang::XEventListener>::get(), xListener );
2130 3648 : }
2131 :
2132 3641 : void SAL_CALL Frame::removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener ) throw( css::uno::RuntimeException, std::exception )
2133 : {
2134 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2135 : // Check incoming parameter.
2136 : SAL_WARN_IF( implcp_removeEventListener( xListener ), "fwk", "Frame::removeEventListener(): Invalid parameter detected." );
2137 : // Look for rejected calls only!
2138 : // Container is threadsafe.
2139 : // Use E_SOFTEXCEPTIONS to allow removing listeners during dispose call!
2140 3641 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2141 :
2142 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2143 3641 : m_aListenerContainer.removeInterface( cppu::UnoType<css::lang::XEventListener>::get(), xListener );
2144 3641 : }
2145 :
2146 : /*-****************************************************************************************************
2147 : @short create new status indicator
2148 : @descr Use returned status indicator to show progresses and some text information.
2149 : All created objects share the same dialog! Only the last one can show his information.
2150 :
2151 : @seealso class StatusIndicatorFactory
2152 : @seealso class StatusIndicator
2153 : @return A reference to created object.
2154 :
2155 : @onerror We return a null reference.
2156 : *//*-*****************************************************************************************************/
2157 3188 : css::uno::Reference< css::task::XStatusIndicator > SAL_CALL Frame::createStatusIndicator() throw( css::uno::RuntimeException, std::exception )
2158 : {
2159 : /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
2160 : // Look for rejected calls!
2161 3188 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2162 :
2163 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2164 6376 : SolarMutexClearableGuard aReadLock;
2165 :
2166 : // Make snapshot of necessary member and define default return value.
2167 6376 : css::uno::Reference< css::task::XStatusIndicator > xExternal(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
2168 6376 : css::uno::Reference< css::task::XStatusIndicatorFactory > xFactory = m_xIndicatorFactoryHelper;
2169 :
2170 3188 : aReadLock.clear();
2171 : /* UNSAFE AREA ----------------------------------------------------------------------------------------- */
2172 :
2173 : // Was set from outside to intercept any progress activities!
2174 3188 : if (xExternal.is())
2175 0 : return xExternal;
2176 :
2177 : // Or use our own factory as fallback, to create such progress.
2178 3188 : if (xFactory.is())
2179 3188 : return xFactory->createStatusIndicator();
2180 :
2181 3188 : return css::uno::Reference< css::task::XStatusIndicator >();
2182 : }
2183 :
2184 : /*-****************************************************************************************************
2185 : @short search for target to load URL
2186 : @descr This method searches for a dispatch for the specified DispatchDescriptor.
2187 : The FrameSearchFlags and the FrameName of the DispatchDescriptor are
2188 : treated as described for findFrame.
2189 :
2190 : @seealso method findFrame()
2191 : @seealso method queryDispatches()
2192 : @seealso method set/getName()
2193 : @seealso class TargetFinder
2194 :
2195 : @param "aURL" , URL for loading
2196 : @param "sTargetFrameName" , name of target frame
2197 : @param "nSearchFlags" , additional flags to regulate search if sTargetFrameName is not clear
2198 : @return css::uno::Reference to dispatch handler.
2199 :
2200 : @onerror A null reference is returned.
2201 : *//*-*****************************************************************************************************/
2202 198870 : css::uno::Reference< css::frame::XDispatch > SAL_CALL Frame::queryDispatch( const css::util::URL& aURL ,
2203 : const OUString& sTargetFrameName,
2204 : sal_Int32 nSearchFlags ) throw( css::uno::RuntimeException, std::exception )
2205 : {
2206 : // Don't check incoming parameter here! Our helper do it for us and it is not a good idea to do it more than ones!
2207 : // But look for rejected calls!
2208 198870 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2209 :
2210 : // Remove uno and cmd protocol part as we want to support both of them. We store only the command part
2211 : // in our hash map. All other protocols are stored with the protocol part.
2212 397740 : OUString aCommand( aURL.Main );
2213 198870 : if ( aURL.Protocol.equalsIgnoreAsciiCase(".uno:") )
2214 171278 : aCommand = aURL.Path;
2215 :
2216 : // Make std::unordered_map lookup if the current URL is in the disabled list
2217 198870 : if ( m_aCommandOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, aCommand ) )
2218 0 : return css::uno::Reference< css::frame::XDispatch >();
2219 : else
2220 : {
2221 : // We use a helper to support these interface and an interceptor mechanism.
2222 : // Our helper is threadsafe by himself!
2223 198870 : return m_xDispatchHelper->queryDispatch( aURL, sTargetFrameName, nSearchFlags );
2224 198870 : }
2225 : }
2226 :
2227 : /*-****************************************************************************************************
2228 : @short handle more than ones dispatches at same call
2229 : @descr Returns a sequence of dispatches. For details see the queryDispatch method.
2230 : For failed dispatches we return empty items in list!
2231 :
2232 : @seealso method queryDispatch()
2233 :
2234 : @param "lDescriptor" list of dispatch arguments for queryDispatch()!
2235 : @return List of dispatch references. Some elements can be NULL!
2236 :
2237 : @onerror An empty list is returned.
2238 : *//*-*****************************************************************************************************/
2239 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 )
2240 : {
2241 : // Don't check incoming parameter here! Our helper do it for us and it is not a good idea to do it more than ones!
2242 : // But look for rejected calls!
2243 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2244 :
2245 : // We use a helper to support these interface and an interceptor mechanism.
2246 : // Our helper is threadsafe by himself!
2247 0 : return m_xDispatchHelper->queryDispatches( lDescriptor );
2248 : }
2249 :
2250 : /*-****************************************************************************************************
2251 : @short register/unregister interceptor for dispatch calls
2252 : @descr If you wish to handle some dispatches by himself ... you should be
2253 : an interceptor for it. Please see class OInterceptionHelper for further information.
2254 :
2255 : @seealso class OInterceptionHelper
2256 :
2257 : @param "xInterceptor", reference to your interceptor implementation.
2258 : @onerror Interceptor is ignored.
2259 : *//*-*****************************************************************************************************/
2260 3109 : void SAL_CALL Frame::registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException, std::exception )
2261 : {
2262 : // We use a helper to support these interface and an interceptor mechanism.
2263 : // This helper is threadsafe himself and check incoming parameter too.
2264 : // I think we don't need any lock here!
2265 : // But we must look for rejected calls.
2266 3109 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2267 :
2268 6218 : css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
2269 6218 : xInterceptionHelper->registerDispatchProviderInterceptor( xInterceptor );
2270 3109 : }
2271 :
2272 3102 : void SAL_CALL Frame::releaseDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& xInterceptor ) throw( css::uno::RuntimeException, std::exception )
2273 : {
2274 : // We use a helper to support these interface and an interceptor mechanism.
2275 : // This helper is threadsafe himself and check incoming parameter too.
2276 : // I think we don't need any lock here!
2277 : // But we must look for rejected calls ...
2278 : // Sometimes we are called during our dispose() method ... => soft exceptions!
2279 3102 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2280 :
2281 6204 : css::uno::Reference< css::frame::XDispatchProviderInterception > xInterceptionHelper( m_xDispatchHelper, css::uno::UNO_QUERY );
2282 6204 : xInterceptionHelper->releaseDispatchProviderInterceptor( xInterceptor );
2283 3102 : }
2284 :
2285 : /*-****************************************************************************************************
2286 : @short provides information about all possible dispatch functions
2287 : inside the currnt frame environment
2288 : *//*-*****************************************************************************************************/
2289 0 : css::uno::Sequence< sal_Int16 > SAL_CALL Frame::getSupportedCommandGroups()
2290 : throw(css::uno::RuntimeException, std::exception)
2291 : {
2292 0 : return m_xDispatchInfoHelper->getSupportedCommandGroups();
2293 : }
2294 :
2295 0 : css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL Frame::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
2296 : throw(css::uno::RuntimeException, std::exception)
2297 : {
2298 0 : return m_xDispatchInfoHelper->getConfigurableDispatchInformation(nCommandGroup);
2299 : }
2300 :
2301 : /*-****************************************************************************************************
2302 : @short notifications for window events
2303 : @descr We are a listener on our container window to forward it to our component window.
2304 :
2305 : @seealso method setComponent()
2306 : @seealso member m_xContainerWindow
2307 : @seealso member m_xComponentWindow
2308 :
2309 : @param "aEvent" describe source of detected event
2310 : *//*-*****************************************************************************************************/
2311 7913 : void SAL_CALL Frame::windowResized( const css::awt::WindowEvent& aEvent ) throw( css::uno::RuntimeException, std::exception )
2312 : {
2313 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2314 : // Check incoming parameter.
2315 : (void) aEvent;
2316 : SAL_WARN_IF( implcp_windowResized( aEvent ), "fwk", "Frame::windowResized(): Invalid parameter detected." );
2317 : // Look for rejected calls.
2318 : // Part of dispose-mechanism => soft exceptions
2319 7913 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2320 :
2321 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2322 : // Impl-method is threadsafe!
2323 : // If we have a current component window - we must resize it!
2324 7913 : implts_resizeComponentWindow();
2325 7913 : }
2326 :
2327 2998 : void SAL_CALL Frame::focusGained( const css::awt::FocusEvent& aEvent ) throw( css::uno::RuntimeException, std::exception )
2328 : {
2329 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2330 : // Check incoming parameter.
2331 : (void) aEvent;
2332 : SAL_WARN_IF( implcp_focusGained( aEvent ), "fwk", "Frame::focusGained(): Invalid parameter detected." );
2333 : // Look for rejected calls.
2334 : // Part of dispose() mechanism ... => soft exceptions!
2335 2998 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2336 :
2337 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2338 5996 : SolarMutexClearableGuard aReadLock;
2339 : // Make snapshot of member!
2340 5996 : css::uno::Reference< css::awt::XWindow > xComponentWindow = m_xComponentWindow;
2341 2998 : aReadLock.clear();
2342 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2343 :
2344 2998 : if( xComponentWindow.is() )
2345 : {
2346 659 : xComponentWindow->setFocus();
2347 2998 : }
2348 2998 : }
2349 :
2350 : /*-****************************************************************************************************
2351 : @short notifications for window events
2352 : @descr We are a listener on our container window to forward it to our component window ...
2353 : but a XTopWindowListener we are only if we are a top frame!
2354 :
2355 : @seealso method setComponent()
2356 : @seealso member m_xContainerWindow
2357 : @seealso member m_xComponentWindow
2358 :
2359 : @param "aEvent" describe source of detected event
2360 : *//*-*****************************************************************************************************/
2361 3552 : void SAL_CALL Frame::windowActivated( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception )
2362 : {
2363 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2364 : // Check incoming parameter.
2365 : (void) aEvent;
2366 : SAL_WARN_IF( implcp_windowActivated( aEvent ), "fwk", "Frame::windowActivated(): Invalid parameter detected." );
2367 : // Look for rejected calls.
2368 3552 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2369 :
2370 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2371 7104 : SolarMutexClearableGuard aReadLock;
2372 : // Make snapshot of member!
2373 3552 : EActiveState eState = m_eActiveState;
2374 3552 : aReadLock.clear();
2375 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2376 : // Activate the new active path from here to top.
2377 3552 : if( eState == E_INACTIVE )
2378 : {
2379 2883 : setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
2380 2883 : activate();
2381 3552 : }
2382 3552 : }
2383 :
2384 230 : void SAL_CALL Frame::windowDeactivated( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception )
2385 : {
2386 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2387 : // Check incoming parameter.
2388 : (void) aEvent;
2389 : SAL_WARN_IF( implcp_windowDeactivated( aEvent ), "fwk", "Frame::windowDeactivated(): Invalid parameter detected." );
2390 : // Look for rejected calls.
2391 : // Sometimes called during dispose() => soft exceptions
2392 230 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2393 :
2394 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2395 460 : SolarMutexClearableGuard aReadLock;
2396 :
2397 460 : css::uno::Reference< css::frame::XFrame > xParent ( m_xParent, css::uno::UNO_QUERY );
2398 460 : css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
2399 230 : EActiveState eActiveState = m_eActiveState;
2400 :
2401 230 : aReadLock.clear();
2402 :
2403 230 : if( eActiveState != E_INACTIVE )
2404 : {
2405 : // Deactivation is always done implicitly by activation of another frame.
2406 : // Only if no activation is done, deactivations have to be processed if the activated window
2407 : // is a parent window of the last active Window!
2408 230 : SolarMutexClearableGuard aSolarGuard;
2409 230 : vcl::Window* pFocusWindow = Application::GetFocusWindow();
2410 920 : if ( xContainerWindow.is() && xParent.is() &&
2411 920 : !css::uno::Reference< css::frame::XDesktop >( xParent, css::uno::UNO_QUERY ).is()
2412 : )
2413 : {
2414 0 : css::uno::Reference< css::awt::XWindow > xParentWindow = xParent->getContainerWindow();
2415 0 : vcl::Window* pParentWindow = VCLUnoHelper::GetWindow( xParentWindow );
2416 : //#i70261#: dialogs opened from an OLE object will cause a deactivate on the frame of the OLE object
2417 : // on Solaris/Linux at that time pFocusWindow is still NULL because the focus handling is different; right after
2418 : // the deactivation the focus will be set into the dialog!
2419 : // currently I see no case where a sub frame could get a deactivate with pFocusWindow being NULL permanently
2420 : // so for now this case is omitted from handled deactivations
2421 0 : if( pFocusWindow && pParentWindow->IsChild( pFocusWindow ) )
2422 : {
2423 0 : css::uno::Reference< css::frame::XFramesSupplier > xSupplier( xParent, css::uno::UNO_QUERY );
2424 0 : if( xSupplier.is() )
2425 : {
2426 0 : aSolarGuard.clear();
2427 0 : xSupplier->setActiveFrame( css::uno::Reference< css::frame::XFrame >() );
2428 0 : }
2429 0 : }
2430 230 : }
2431 230 : }
2432 230 : }
2433 :
2434 0 : void SAL_CALL Frame::windowClosing( const css::lang::EventObject& ) throw( css::uno::RuntimeException, std::exception )
2435 : {
2436 : /* #i62088#
2437 : Some interceptor objects intercept our "internally asynchronous implemented" dispatch call.
2438 : And they close this frame directly (means synchronous then).
2439 : Means: Frame::windowClosing()->Frame::close()
2440 : In such situation its not a good idea to hold this transaction count alive .-)
2441 : */
2442 : {
2443 : // Look for rejected calls.
2444 0 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2445 : // deactivate this frame ...
2446 0 : deactivate();
2447 : }
2448 :
2449 : // ... and try to close it
2450 : // But do it asynchron inside the main thread.
2451 : // VCL has no fun to do such things outside his main thread :-(
2452 : // Note: The used dispatch make it asynchronous for us .-)
2453 :
2454 : /*ATTENTION!
2455 : Don't try to suspend the controller here! Because it's done inside used dispatch().
2456 : Otherwhise the dialog "would you save your changes?" will be shown more than once ...
2457 : */
2458 :
2459 : /* SAFE */
2460 0 : SolarMutexClearableGuard aReadLock;
2461 0 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
2462 0 : aReadLock.clear();
2463 : /* SAFE */
2464 :
2465 0 : css::util::URL aURL;
2466 0 : aURL.Complete = ".uno:CloseFrame";
2467 0 : css::uno::Reference< css::util::XURLTransformer > xParser(css::util::URLTransformer::create(xContext));
2468 0 : xParser->parseStrict(aURL);
2469 :
2470 0 : css::uno::Reference< css::frame::XDispatch > xCloser = queryDispatch(aURL, SPECIALTARGET_SELF, 0);
2471 0 : if (xCloser.is())
2472 0 : xCloser->dispatch(aURL, css::uno::Sequence< css::beans::PropertyValue >());
2473 :
2474 : // Attention: If this dispatch works synchronous ... and full fill its job ...
2475 : // this line of code will never be reached ...
2476 : // Or if it will be reached it will be for sure that all your member are gone .-)
2477 0 : }
2478 :
2479 : /*-****************************************************************************************************
2480 : @short react for a show event for the internal container window
2481 : @descr Normally we don't need this information really. But we can use it to
2482 : implement the special feature "trigger first visible task".
2483 :
2484 : Algorithm: - first we have to check if we are a top (task) frame
2485 : It's not enough to be a top frame! Because we MUST have the desktop as parent.
2486 : But frames without a parent are top too. So it's not possible to check isTop() here!
2487 : We have to look for the type of our parent.
2488 : - if we are a task frame, then we have to check if we are the first one.
2489 : We use a static variable to do so. They will be reset to afterwards be sure
2490 : that further calls of this method doesn't do anything then.
2491 : - Then we have to trigger the right event string on the global job executor.
2492 :
2493 : @seealso css::task::JobExecutor
2494 :
2495 : @param aEvent
2496 : describes the source of this event
2497 : We are not interested on this information. We are interested on the visible state only.
2498 :
2499 : @threadsafe yes
2500 : *//*-*****************************************************************************************************/
2501 6344 : void SAL_CALL Frame::windowShown( const css::lang::EventObject& ) throw(css::uno::RuntimeException, std::exception)
2502 : {
2503 : static bool bFirstVisibleTask = true;
2504 6344 : static osl::Mutex aFirstVisibleLock;
2505 :
2506 : /* SAFE { */
2507 6344 : SolarMutexClearableGuard aReadLock;
2508 12688 : css::uno::Reference< css::frame::XDesktop > xDesktopCheck( m_xParent, css::uno::UNO_QUERY );
2509 12688 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
2510 6344 : m_bIsHidden = false;
2511 6344 : aReadLock.clear();
2512 : /* } SAFE */
2513 :
2514 6344 : impl_checkMenuCloser();
2515 :
2516 6344 : if (xDesktopCheck.is())
2517 : {
2518 6342 : osl::ClearableMutexGuard aGuard(aFirstVisibleLock);
2519 6342 : bool bMustBeTriggered = bFirstVisibleTask;
2520 6342 : bFirstVisibleTask = false;
2521 6342 : aGuard.clear();
2522 :
2523 6342 : if (bMustBeTriggered)
2524 : {
2525 : css::uno::Reference< css::task::XJobExecutor > xExecutor
2526 103 : = css::task::theJobExecutor::get( xContext );
2527 103 : xExecutor->trigger( "onFirstVisibleTask" );
2528 6342 : }
2529 6344 : }
2530 6344 : }
2531 :
2532 5 : void SAL_CALL Frame::windowHidden( const css::lang::EventObject& ) throw(css::uno::RuntimeException, std::exception)
2533 : {
2534 : /* SAFE { */
2535 5 : SolarMutexClearableGuard aReadLock;
2536 5 : m_bIsHidden = true;
2537 5 : aReadLock.clear();
2538 : /* } SAFE */
2539 :
2540 5 : impl_checkMenuCloser();
2541 5 : }
2542 :
2543 : /*-****************************************************************************************************
2544 : @short called by dispose of our windows!
2545 : @descr This object is forced to release all references to the interfaces given
2546 : by the parameter source. We are a listener at our container window and
2547 : should listen for his diposing.
2548 :
2549 : @seealso XWindowListener
2550 : @seealso XTopWindowListener
2551 : @seealso XFocusListener
2552 : *//*-*****************************************************************************************************/
2553 0 : void SAL_CALL Frame::disposing( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException, std::exception )
2554 : {
2555 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2556 : // Check incoming parameter.
2557 : SAL_WARN_IF( implcp_disposing( aEvent ), "fwk", "Frame::disposing(): Invalid parameter detected." );
2558 : // Look for rejected calls.
2559 : // May be we are called during releasing our windows in our in dispose call!? => soft exceptions
2560 0 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2561 :
2562 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2563 0 : SolarMutexResettableGuard aWriteLock;
2564 :
2565 0 : if( aEvent.Source == m_xContainerWindow )
2566 : {
2567 : // NECESSARY: Impl-method is threadsafe by himself!
2568 0 : aWriteLock.clear();
2569 0 : implts_stopWindowListening();
2570 0 : aWriteLock.reset();
2571 0 : m_xContainerWindow = css::uno::Reference< css::awt::XWindow >();
2572 0 : }
2573 0 : }
2574 :
2575 : /*-************************************************************************************************************
2576 : @interface com.sun.star.document.XActionLockable
2577 : @short implement locking of frame/task from outside
2578 : @descr Sometimes we have problems to decide if closing of task is allowed. Because; frame/task
2579 : could be used for pending loading jobs. So you can lock this object from outside and
2580 : prevent instance against closing during using! But - don't do it in a wrong or expensive manner.
2581 : Otherwise task couldn't die anymore!!!
2582 :
2583 : @seealso interface XActionLockable
2584 : @seeelso method BaseDispatcher::implts_loadIt()
2585 : @seeelso method Desktop::loadComponentFromURL()
2586 : @return true if frame/task is locked
2587 : false otherwise
2588 : @threadsafe yes
2589 : *//*-*************************************************************************************************************/
2590 6565 : sal_Bool SAL_CALL Frame::isActionLocked() throw( css::uno::RuntimeException, std::exception )
2591 : {
2592 6565 : SolarMutexGuard g;
2593 6565 : return( m_nExternalLockCount!=0);
2594 : }
2595 :
2596 3290 : void SAL_CALL Frame::addActionLock() throw( css::uno::RuntimeException, std::exception )
2597 : {
2598 3290 : SolarMutexGuard g;
2599 3290 : ++m_nExternalLockCount;
2600 3290 : }
2601 :
2602 3290 : void SAL_CALL Frame::removeActionLock() throw( css::uno::RuntimeException, std::exception )
2603 : {
2604 : // Register no transaction here! Otherwhise we wait for ever inside possible
2605 : // implts_checkSuicide()/dispose() request ...
2606 :
2607 : {
2608 3290 : SolarMutexGuard g;
2609 : SAL_WARN_IF( m_nExternalLockCount<=0, "fwk", "Frame::removeActionLock(): Frame is not locked! Possible multithreading problem detected." );
2610 3290 : --m_nExternalLockCount;
2611 : }
2612 :
2613 3290 : implts_checkSuicide();
2614 3290 : }
2615 :
2616 0 : void SAL_CALL Frame::setActionLocks( sal_Int16 nLock ) throw( css::uno::RuntimeException, std::exception )
2617 : {
2618 0 : SolarMutexGuard g;
2619 : // Attention: If somewhere called resetActionLocks() before and get e.g. 5 locks ...
2620 : // and tried to set these 5 ones here after his operations ...
2621 : // we can't ignore setted requests during these two calls!
2622 : // So we must add(!) these 5 locks here.
2623 0 : m_nExternalLockCount = m_nExternalLockCount + nLock;
2624 0 : }
2625 :
2626 0 : sal_Int16 SAL_CALL Frame::resetActionLocks() throw( css::uno::RuntimeException, std::exception )
2627 : {
2628 : // Register no transaction here! Otherwhise we wait for ever inside possible
2629 : // implts_checkSuicide()/dispose() request ...
2630 :
2631 0 : sal_Int16 nCurrentLocks = 0;
2632 : {
2633 0 : SolarMutexGuard g;
2634 0 : nCurrentLocks = m_nExternalLockCount;
2635 0 : m_nExternalLockCount = 0;
2636 : }
2637 :
2638 : // Attention:
2639 : // external lock count is 0 here every time ... but if
2640 : // member m_bSelfClose is set to true too .... we call our own close()/dispose().
2641 : // See close() for further information
2642 0 : implts_checkSuicide();
2643 :
2644 0 : return nCurrentLocks;
2645 : }
2646 :
2647 3283 : void Frame::impl_initializePropInfo()
2648 : {
2649 3283 : impl_setPropertyChangeBroadcaster(static_cast< css::frame::XFrame* >(this));
2650 :
2651 : impl_addPropertyInfo(
2652 : css::beans::Property(
2653 : FRAME_PROPNAME_DISPATCHRECORDERSUPPLIER,
2654 : FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER,
2655 3283 : cppu::UnoType<css::frame::XDispatchRecorderSupplier>::get(),
2656 3283 : css::beans::PropertyAttribute::TRANSIENT));
2657 :
2658 : impl_addPropertyInfo(
2659 : css::beans::Property(
2660 : FRAME_PROPNAME_INDICATORINTERCEPTION,
2661 : FRAME_PROPHANDLE_INDICATORINTERCEPTION,
2662 3283 : cppu::UnoType<css::task::XStatusIndicator>::get(),
2663 3283 : css::beans::PropertyAttribute::TRANSIENT));
2664 :
2665 : impl_addPropertyInfo(
2666 : css::beans::Property(
2667 : FRAME_PROPNAME_ISHIDDEN,
2668 : FRAME_PROPHANDLE_ISHIDDEN,
2669 3283 : cppu::UnoType<bool>::get(),
2670 6566 : css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY));
2671 :
2672 : impl_addPropertyInfo(
2673 : css::beans::Property(
2674 : FRAME_PROPNAME_LAYOUTMANAGER,
2675 : FRAME_PROPHANDLE_LAYOUTMANAGER,
2676 3283 : cppu::UnoType<com::sun::star::frame::XLayoutManager>::get(),
2677 3283 : css::beans::PropertyAttribute::TRANSIENT));
2678 :
2679 : impl_addPropertyInfo(
2680 : css::beans::Property(
2681 : FRAME_PROPNAME_TITLE,
2682 : FRAME_PROPHANDLE_TITLE,
2683 3283 : cppu::UnoType<OUString>::get(),
2684 3283 : css::beans::PropertyAttribute::TRANSIENT));
2685 3283 : }
2686 :
2687 2 : void SAL_CALL Frame::impl_setPropertyValue(const OUString& /*sProperty*/,
2688 : sal_Int32 nHandle ,
2689 : const css::uno::Any& aValue )
2690 :
2691 : {
2692 : /* There is no need to lock any mutex here. Because we share the
2693 : solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
2694 : see ctor of PropertySetHelper for further information.
2695 : */
2696 :
2697 : /* Attention: You can use nHandle only, if you are sure that all supported
2698 : properties has an unique handle. That must be guaranteed
2699 : inside method impl_initializePropInfo()!
2700 : */
2701 2 : switch (nHandle)
2702 : {
2703 : case FRAME_PROPHANDLE_TITLE :
2704 : {
2705 1 : OUString sExternalTitle;
2706 1 : aValue >>= sExternalTitle;
2707 1 : setTitle (sExternalTitle);
2708 : }
2709 1 : break;
2710 :
2711 : case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
2712 1 : aValue >>= m_xDispatchRecorderSupplier;
2713 1 : break;
2714 :
2715 : case FRAME_PROPHANDLE_LAYOUTMANAGER :
2716 : {
2717 0 : css::uno::Reference< css::frame::XLayoutManager2 > xOldLayoutManager = m_xLayoutManager;
2718 0 : css::uno::Reference< css::frame::XLayoutManager2 > xNewLayoutManager;
2719 0 : aValue >>= xNewLayoutManager;
2720 :
2721 0 : if (xOldLayoutManager != xNewLayoutManager)
2722 : {
2723 0 : m_xLayoutManager = xNewLayoutManager;
2724 0 : if (xOldLayoutManager.is())
2725 0 : lcl_disableLayoutManager(xOldLayoutManager, this);
2726 0 : if (xNewLayoutManager.is())
2727 0 : lcl_enableLayoutManager(xNewLayoutManager, this);
2728 0 : }
2729 : }
2730 0 : break;
2731 :
2732 : case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
2733 : {
2734 0 : css::uno::Reference< css::task::XStatusIndicator > xProgress;
2735 0 : aValue >>= xProgress;
2736 0 : m_xIndicatorInterception = xProgress;
2737 : }
2738 0 : break;
2739 :
2740 : default :
2741 : SAL_INFO("fwk", "Frame::setFastPropertyValue_NoBroadcast(): Invalid handle detected!" );
2742 0 : break;
2743 : }
2744 2 : }
2745 :
2746 75852 : css::uno::Any SAL_CALL Frame::impl_getPropertyValue(const OUString& /*sProperty*/,
2747 : sal_Int32 nHandle )
2748 : {
2749 : /* There is no need to lock any mutex here. Because we share the
2750 : solar mutex with our base class. And we said to our base class: "dont release it on calling us" .-)
2751 : see ctor of PropertySetHelper for further information.
2752 : */
2753 :
2754 : /* Attention: You can use nHandle only, if you are sure that all supported
2755 : properties has an unique handle. That must be guaranteed
2756 : inside method impl_initializePropInfo()!
2757 : */
2758 75852 : css::uno::Any aValue;
2759 75852 : switch (nHandle)
2760 : {
2761 : case FRAME_PROPHANDLE_TITLE :
2762 29 : aValue <<= getTitle ();
2763 29 : break;
2764 :
2765 : case FRAME_PROPHANDLE_DISPATCHRECORDERSUPPLIER :
2766 531 : aValue <<= m_xDispatchRecorderSupplier;
2767 531 : break;
2768 :
2769 : case FRAME_PROPHANDLE_ISHIDDEN :
2770 19055 : aValue <<= m_bIsHidden;
2771 19055 : break;
2772 :
2773 : case FRAME_PROPHANDLE_LAYOUTMANAGER :
2774 56237 : aValue <<= m_xLayoutManager;
2775 56237 : break;
2776 :
2777 : case FRAME_PROPHANDLE_INDICATORINTERCEPTION :
2778 : {
2779 0 : css::uno::Reference< css::task::XStatusIndicator > xProgress(m_xIndicatorInterception.get(), css::uno::UNO_QUERY);
2780 0 : aValue = css::uno::makeAny(xProgress);
2781 : }
2782 0 : break;
2783 :
2784 : default :
2785 : SAL_INFO("fwk", "Frame::getFastPropertyValue(): Invalid handle detected!" );
2786 0 : break;
2787 : }
2788 :
2789 75852 : return aValue;
2790 : }
2791 :
2792 : /*-****************************************************************************************************
2793 : @short dispose old container window and forget his reference
2794 : @descr Sometimes we must repair our "modal dialog parent mechanism" too!
2795 : @param "xWindow", reference to old container window to dispose it
2796 : @return An empty reference.
2797 : @threadsafe NO!
2798 : *//*-*****************************************************************************************************/
2799 3274 : void Frame::impl_disposeContainerWindow( css::uno::Reference< css::awt::XWindow >& xWindow )
2800 : {
2801 3274 : if( xWindow.is() )
2802 : {
2803 3273 : xWindow->setVisible( sal_False );
2804 : // All VclComponents are XComponents; so call dispose before discarding
2805 : // a css::uno::Reference< XVclComponent >, because this frame is the owner of the window
2806 3273 : xWindow->dispose();
2807 3273 : xWindow = css::uno::Reference< css::awt::XWindow >();
2808 : }
2809 3274 : }
2810 :
2811 : /*-****************************************************************************************************
2812 : @short send frame action event to our listener
2813 : @descr This method is threadsafe AND can be called by our dispose method too!
2814 : @param "aAction", describe the event for sending
2815 : *//*-*****************************************************************************************************/
2816 18602 : void Frame::implts_sendFrameActionEvent( const css::frame::FrameAction& aAction )
2817 : {
2818 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2819 : // Sometimes used by dispose() => soft exceptions!
2820 18602 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
2821 :
2822 : // Log information about order of events to file!
2823 : // (only activated in debug version!)
2824 : SAL_INFO( "fwk.frame",
2825 : "[Frame] " << m_sName << " send event " <<
2826 : (aAction == css::frame::FrameAction_COMPONENT_ATTACHED ? OUString("COMPONENT ATTACHED") :
2827 : (aAction == css::frame::FrameAction_COMPONENT_DETACHING ? OUString("COMPONENT DETACHING") :
2828 : (aAction == css::frame::FrameAction_COMPONENT_REATTACHED ? OUString("COMPONENT REATTACHED") :
2829 : (aAction == css::frame::FrameAction_FRAME_ACTIVATED ? OUString("FRAME ACTIVATED") :
2830 : (aAction == css::frame::FrameAction_FRAME_DEACTIVATING ? OUString("FRAME DEACTIVATING") :
2831 : (aAction == css::frame::FrameAction_CONTEXT_CHANGED ? OUString("CONTEXT CHANGED") :
2832 : (aAction == css::frame::FrameAction_FRAME_UI_ACTIVATED ? OUString("FRAME UI ACTIVATED") :
2833 : (aAction == css::frame::FrameAction_FRAME_UI_DEACTIVATING ? OUString("FRAME UI DEACTIVATING") :
2834 : (aAction == css::frame::FrameAction_MAKE_FIXED_SIZE ? OUString("MAKE_FIXED_SIZE") :
2835 : OUString("*invalid*")))))))))));
2836 :
2837 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2838 : // Send css::frame::FrameAction event to all listener.
2839 : // Get container for right listener.
2840 : // FOLLOW LINES ARE THREADSAFE!!!
2841 : // ( OInterfaceContainerHelper is synchronized with m_aListenerContainer! )
2842 18602 : ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<css::frame::XFrameActionListener>::get());
2843 :
2844 18602 : if( pContainer != NULL )
2845 : {
2846 : // Build action event.
2847 18602 : css::frame::FrameActionEvent aFrameActionEvent( static_cast< ::cppu::OWeakObject* >(this), this, aAction );
2848 :
2849 : // Get iterator for access to listener.
2850 37204 : ::cppu::OInterfaceIteratorHelper aIterator( *pContainer );
2851 : // Send message to all listener.
2852 227629 : while( aIterator.hasMoreElements() )
2853 : {
2854 : try
2855 : {
2856 190425 : static_cast<css::frame::XFrameActionListener*>(aIterator.next())->frameAction( aFrameActionEvent );
2857 : }
2858 4 : catch( const css::uno::RuntimeException& )
2859 : {
2860 4 : aIterator.remove();
2861 : }
2862 18602 : }
2863 18602 : }
2864 18602 : }
2865 :
2866 : /*-****************************************************************************************************
2867 : @short helper to resize our component window
2868 : @descr A frame contains 2 windows - a container ~ and a component window.
2869 : This method resize inner component window to full size of outer container window.
2870 : This method is threadsafe AND can be called by our dispose method too!
2871 : *//*-*****************************************************************************************************/
2872 14479 : void Frame::implts_resizeComponentWindow()
2873 : {
2874 : // usually the LayoutManager does the resizing
2875 : // in case there is no LayoutManager resizing has to be done here
2876 14479 : if ( !m_xLayoutManager.is() )
2877 : {
2878 0 : css::uno::Reference< css::awt::XWindow > xComponentWindow( getComponentWindow() );
2879 0 : if( xComponentWindow.is() )
2880 : {
2881 0 : css::uno::Reference< css::awt::XDevice > xDevice( getContainerWindow(), css::uno::UNO_QUERY );
2882 :
2883 : // Convert relativ size to output size.
2884 0 : css::awt::Rectangle aRectangle = getContainerWindow()->getPosSize();
2885 0 : css::awt::DeviceInfo aInfo = xDevice->getInfo();
2886 0 : css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
2887 0 : aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
2888 :
2889 : // Resize our component window.
2890 0 : xComponentWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE );
2891 0 : }
2892 : }
2893 14479 : }
2894 :
2895 : /*-****************************************************************************************************
2896 : @short helper to set icon on our container window (if it is a system window!)
2897 : @descr We use our internal set controller (if it exist) to specify which factory he represented.
2898 : These information can be used to find right icon. But our controller can say it us directly
2899 : too ... we should ask his optional property set first ...
2900 :
2901 : @seealso method Window::SetIcon()
2902 : @onerror We do nothing.
2903 : *//*-*****************************************************************************************************/
2904 6566 : void Frame::implts_setIconOnWindow()
2905 : {
2906 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2907 : // Look for rejected calls.
2908 6566 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2909 :
2910 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2911 : // Make snapshot of necessary members and release lock.
2912 13132 : SolarMutexClearableGuard aReadLock;
2913 13132 : css::uno::Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow, css::uno::UNO_QUERY );
2914 13132 : css::uno::Reference< css::frame::XController > xController ( m_xController , css::uno::UNO_QUERY );
2915 6566 : aReadLock.clear();
2916 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2917 :
2918 6566 : if( xContainerWindow.is() && xController.is() )
2919 : {
2920 :
2921 : // a) set default value to an invalid one. So we can start further searches for right icon id, if
2922 : // first steps failed!
2923 : // We must reset it to any fallback value - if no search step returns a valid result.
2924 3293 : sal_Int32 nIcon = -1;
2925 :
2926 : // b) try to find information on controller propertyset directly
2927 : // Don't forget to catch possible exceptions - because these property is an optional one!
2928 3293 : css::uno::Reference< css::beans::XPropertySet > xSet( xController, css::uno::UNO_QUERY );
2929 3293 : if( xSet.is() )
2930 : {
2931 : try
2932 : {
2933 3236 : css::uno::Reference< css::beans::XPropertySetInfo > const xPSI( xSet->getPropertySetInfo(), css::uno::UNO_SET_THROW );
2934 3236 : if ( xPSI->hasPropertyByName( "IconId" ) )
2935 0 : xSet->getPropertyValue( "IconId" ) >>= nIcon;
2936 : }
2937 0 : catch( css::uno::Exception& )
2938 : {
2939 : DBG_UNHANDLED_EXCEPTION();
2940 : }
2941 : }
2942 :
2943 : // c) if b) failed ... analyze argument list of currently loaded document insde the frame to find the filter.
2944 : // He can be used to detect right factory - and these can be used to match factory to icon ...
2945 3293 : if( nIcon == -1 )
2946 : {
2947 3293 : css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
2948 3293 : if( xModel.is() )
2949 : {
2950 3289 : SvtModuleOptions::EFactory eFactory = SvtModuleOptions::ClassifyFactoryByModel(xModel);
2951 3289 : if (eFactory != SvtModuleOptions::EFactory::UNKNOWN_FACTORY)
2952 3289 : nIcon = SvtModuleOptions().GetFactoryIcon( eFactory );
2953 3293 : }
2954 : }
2955 :
2956 : // d) if all steps failed - use fallback!
2957 3293 : if( nIcon == -1 )
2958 : {
2959 4 : nIcon = 0;
2960 : }
2961 :
2962 : // e) set icon on container window now
2963 : // Don't forget SolarMutex! We use vcl directly :-(
2964 : // Check window pointer for right WorkWindow class too!!!
2965 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2966 : {
2967 3293 : SolarMutexGuard aSolarGuard;
2968 3293 : vcl::Window* pWindow = (VCLUnoHelper::GetWindow( xContainerWindow ));
2969 3293 : if(
2970 6586 : ( pWindow != NULL ) &&
2971 3293 : ( pWindow->GetType() == WINDOW_WORKWINDOW )
2972 : )
2973 : {
2974 3289 : WorkWindow* pWorkWindow = static_cast<WorkWindow*>(pWindow);
2975 3289 : pWorkWindow->SetIcon( (sal_uInt16)nIcon );
2976 3293 : }
2977 3293 : }
2978 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2979 6566 : }
2980 6566 : }
2981 :
2982 : /*-************************************************************************************************************
2983 : @short helper to start/stop listeneing for window events on container window
2984 : @descr If we get a new container window, we must set it on internal member ...
2985 : and stop listening at old one ... and start listening on new one!
2986 : But sometimes (in dispose() call!) it's necessary to stop listeneing without starting
2987 : on new connections. So we split this functionality to make it easier at use.
2988 :
2989 : @seealso method initialize()
2990 : @seealso method dispose()
2991 : @onerror We do nothing!
2992 : @threadsafe yes
2993 : *//*-*************************************************************************************************************/
2994 9848 : void Frame::implts_startWindowListening()
2995 : {
2996 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
2997 9848 : TransactionGuard aTransaction( m_aTransactionManager, E_HARDEXCEPTIONS );
2998 :
2999 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3000 : // Make snapshot of necessary member!
3001 19696 : SolarMutexClearableGuard aReadLock;
3002 19696 : css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
3003 19696 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
3004 19696 : css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > xDragDropListener = m_xDropTargetListener;
3005 19696 : css::uno::Reference< css::awt::XWindowListener > xWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3006 19696 : css::uno::Reference< css::awt::XFocusListener > xFocusListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3007 19696 : css::uno::Reference< css::awt::XTopWindowListener > xTopWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3008 9848 : aReadLock.clear();
3009 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
3010 :
3011 9848 : if( xContainerWindow.is() )
3012 : {
3013 9848 : xContainerWindow->addWindowListener( xWindowListener);
3014 9848 : xContainerWindow->addFocusListener ( xFocusListener );
3015 :
3016 9848 : css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
3017 9848 : if( xTopWindow.is() )
3018 : {
3019 9848 : xTopWindow->addTopWindowListener( xTopWindowListener );
3020 :
3021 9848 : css::uno::Reference< css::awt::XToolkit2 > xToolkit = css::awt::Toolkit::create( xContext );
3022 19696 : css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xToolkit->getDropTarget( xContainerWindow );
3023 9848 : if( xDropTarget.is() )
3024 : {
3025 9848 : xDropTarget->addDropTargetListener( xDragDropListener );
3026 9848 : xDropTarget->setActive( sal_True );
3027 9848 : }
3028 9848 : }
3029 9848 : }
3030 9848 : }
3031 :
3032 9842 : void Frame::implts_stopWindowListening()
3033 : {
3034 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
3035 : // Sometimes used by dispose() => soft exceptions!
3036 9842 : TransactionGuard aTransaction( m_aTransactionManager, E_SOFTEXCEPTIONS );
3037 :
3038 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3039 : // Make snapshot of necessary member!
3040 19684 : SolarMutexClearableGuard aReadLock;
3041 19684 : css::uno::Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow;
3042 19684 : css::uno::Reference< css::uno::XComponentContext > xContext = m_xContext;
3043 19684 : css::uno::Reference< css::datatransfer::dnd::XDropTargetListener > xDragDropListener = m_xDropTargetListener;
3044 19684 : css::uno::Reference< css::awt::XWindowListener > xWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3045 19684 : css::uno::Reference< css::awt::XFocusListener > xFocusListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3046 19684 : css::uno::Reference< css::awt::XTopWindowListener > xTopWindowListener ( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY );
3047 9842 : aReadLock.clear();
3048 : /* UNSAFE AREA --------------------------------------------------------------------------------------------- */
3049 :
3050 9842 : if( xContainerWindow.is() )
3051 : {
3052 9841 : xContainerWindow->removeWindowListener( xWindowListener);
3053 9841 : xContainerWindow->removeFocusListener ( xFocusListener );
3054 :
3055 9841 : css::uno::Reference< css::awt::XTopWindow > xTopWindow( xContainerWindow, css::uno::UNO_QUERY );
3056 9841 : if( xTopWindow.is() )
3057 : {
3058 9841 : xTopWindow->removeTopWindowListener( xTopWindowListener );
3059 :
3060 9841 : css::uno::Reference< css::awt::XToolkit2 > xToolkit = css::awt::Toolkit::create( xContext );
3061 19678 : css::uno::Reference< css::datatransfer::dnd::XDropTarget > xDropTarget = xToolkit->getDropTarget( xContainerWindow );
3062 9839 : if( xDropTarget.is() )
3063 : {
3064 9839 : xDropTarget->removeDropTargetListener( xDragDropListener );
3065 9839 : xDropTarget->setActive( sal_False );
3066 9839 : }
3067 9841 : }
3068 9842 : }
3069 9840 : }
3070 :
3071 : /*-****************************************************************************************************
3072 : @short helper to force breaked close() request again
3073 : @descr If we self disagree with a close() request, and detect that all external locks are gone ...
3074 : then we must try to close this frame again.
3075 :
3076 : @seealso XCloseable::close()
3077 : @seealso Frame::close()
3078 : @seealso Frame::removeActionLock()
3079 : @seealso Frame::resetActionLock()
3080 : @seealso m_bSelfClose
3081 : @seealso m_nExternalLockCount
3082 :
3083 : @threadsafe yes
3084 : *//*-*****************************************************************************************************/
3085 3290 : void Frame::implts_checkSuicide()
3086 : {
3087 : /* SAFE */
3088 3290 : SolarMutexClearableGuard aReadLock;
3089 : // in case of lock==0 and safed state of previous close() request m_bSelfClose
3090 : // we must force close() again. Because we had disagreed with that before.
3091 3290 : bool bSuicide = (m_nExternalLockCount==0 && m_bSelfClose);
3092 3290 : m_bSelfClose = false;
3093 3290 : aReadLock.clear();
3094 : /* } SAFE */
3095 : // force close and deliver ownership to source of possible throwed veto exception
3096 : // Attention: Because this method is not designed to throw such exception we must suppress
3097 : // it for outside code!
3098 : try
3099 : {
3100 3290 : if (bSuicide)
3101 1 : close(sal_True);
3102 : }
3103 0 : catch(const css::util::CloseVetoException&)
3104 : {}
3105 0 : catch(const css::lang::DisposedException&)
3106 3290 : {}
3107 3290 : }
3108 :
3109 : /** little helper to enable/disable the menu closer at the menubar of the given frame.
3110 :
3111 : @param xFrame
3112 : we use its layout manager to set/reset a special callback.
3113 : Its existence regulate visibility of this closer item.
3114 :
3115 : @param bState
3116 : <TRUE/> enable; <FALSE/> disable this state
3117 : */
3118 :
3119 6335 : void Frame::impl_setCloser( /*IN*/ const css::uno::Reference< css::frame::XFrame2 >& xFrame ,
3120 : /*IN*/ bool bState )
3121 : {
3122 : // Note: If start module is not installed - no closer has to be shown!
3123 6335 : if (!SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::EModule::STARTMODULE))
3124 6335 : return;
3125 :
3126 : try
3127 : {
3128 6335 : css::uno::Reference< css::beans::XPropertySet > xFrameProps(xFrame, css::uno::UNO_QUERY_THROW);
3129 12670 : css::uno::Reference< css::frame::XLayoutManager > xLayoutManager;
3130 6335 : xFrameProps->getPropertyValue(FRAME_PROPNAME_LAYOUTMANAGER) >>= xLayoutManager;
3131 12670 : css::uno::Reference< css::beans::XPropertySet > xLayoutProps(xLayoutManager, css::uno::UNO_QUERY_THROW);
3132 12670 : xLayoutProps->setPropertyValue(LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, css::uno::makeAny(bState));
3133 : }
3134 0 : catch(const css::uno::RuntimeException&)
3135 0 : { throw; }
3136 0 : catch(const css::uno::Exception&)
3137 : {}
3138 : }
3139 :
3140 : /** it checks, which of the top level task frames must have the special menu closer for
3141 : switching to the backing window mode.
3142 :
3143 : It analyze the current list of visible top level frames. Only the last real document
3144 : frame can have this symbol. Not the help frame nor the backing task itself.
3145 : Here we do anything related to this closer. We remove it from the old frame and set it
3146 : for the new one.
3147 : */
3148 :
3149 19462 : void Frame::impl_checkMenuCloser()
3150 : {
3151 : /* SAFE { */
3152 19462 : SolarMutexClearableGuard aReadLock;
3153 :
3154 : // only top frames, which are part of our desktop hierarchy, can
3155 : // do so! By the way - we need the desktop instance to have access
3156 : // to all other top level frames too.
3157 35641 : css::uno::Reference< css::frame::XDesktop > xDesktop (m_xParent, css::uno::UNO_QUERY);
3158 35641 : css::uno::Reference< css::frame::XFramesSupplier > xTaskSupplier(xDesktop , css::uno::UNO_QUERY);
3159 19462 : if ( !xDesktop.is() || !xTaskSupplier.is() )
3160 22745 : return;
3161 :
3162 16179 : aReadLock.clear();
3163 : /* } SAFE */
3164 :
3165 : // analyze the list of current open tasks
3166 : // Suppress search for other views to the same model ...
3167 : // It's not needed here and can be very expensive.
3168 : FrameListAnalyzer aAnalyzer(
3169 : xTaskSupplier,
3170 : this,
3171 32358 : FrameListAnalyzer::E_HIDDEN | FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);
3172 :
3173 : // specify the new frame, which must have this special state ...
3174 32358 : css::uno::Reference< css::frame::XFrame2 > xNewCloserFrame;
3175 :
3176 : // a)
3177 : // If there exist ate least one other frame - there are two frames currently open.
3178 : // But we can enable this closer only, if one of these two tasks includes the help module.
3179 : // The "other frame" couldn't be the help. Because then it wouldn't be part of this "other list".
3180 : // In such case it will be separated to the reference aAnalyzer.m_xHelp!
3181 : // But we must check, if weself includes the help ...
3182 : // Check aAnalyzer.m_bReferenceIsHelp!
3183 16179 : if (
3184 16501 : (aAnalyzer.m_lOtherVisibleFrames.getLength()==1) &&
3185 : (
3186 539 : (aAnalyzer.m_bReferenceIsHelp ) ||
3187 : (aAnalyzer.m_bReferenceIsHidden)
3188 : )
3189 : )
3190 : {
3191 : // others[0] can't be the backing component!
3192 : // Because it's set at the special member aAnalyzer.m_xBackingComponent ... :-)
3193 322 : xNewCloserFrame.set( aAnalyzer.m_lOtherVisibleFrames[0], css::uno::UNO_QUERY_THROW );
3194 : }
3195 :
3196 : // b)
3197 : // There is no other frame ... means no other document frame. The help module
3198 : // will be handled separately and must(!) be ignored here ... excepting weself includes the help.
3199 15857 : else if (
3200 31491 : (aAnalyzer.m_lOtherVisibleFrames.getLength()==0) &&
3201 31268 : (!aAnalyzer.m_bReferenceIsHelp ) &&
3202 43130 : (!aAnalyzer.m_bReferenceIsHidden ) &&
3203 11639 : (!aAnalyzer.m_bReferenceIsBacking )
3204 : )
3205 : {
3206 11638 : xNewCloserFrame = this;
3207 : }
3208 :
3209 : // Look for necessary actions ...
3210 : // Only if the closer state must be moved from one frame to another one
3211 : // or must be enabled/disabled at all.
3212 32358 : SolarMutexGuard aGuard;
3213 :
3214 32358 : css::uno::Reference< css::frame::XFrame2 > xCloserFrame (m_xCloserFrame.get(), css::uno::UNO_QUERY);
3215 16179 : if (xCloserFrame!=xNewCloserFrame)
3216 : {
3217 6335 : if (xCloserFrame.is())
3218 3164 : impl_setCloser(xCloserFrame, false);
3219 6335 : if (xNewCloserFrame.is())
3220 3171 : impl_setCloser(xNewCloserFrame, true);
3221 6335 : m_xCloserFrame = xNewCloserFrame;
3222 16179 : }
3223 : }
3224 :
3225 : // debug methods
3226 :
3227 : // Its allowed to reset the active frame membervariable with a NULL-css::uno::Reference but not with a NULL-pointer!
3228 : // And we accept frames only! No tasks and desktops!
3229 0 : bool Frame::implcp_setActiveFrame( const css::uno::Reference< css::frame::XFrame >& xFrame )
3230 : {
3231 0 : return css::uno::Reference< css::frame::XDesktop >( xFrame, css::uno::UNO_QUERY ).is();
3232 : }
3233 :
3234 0 : bool Frame::implcp_addFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
3235 : {
3236 0 : return !xListener.is();
3237 : }
3238 :
3239 0 : bool Frame::implcp_removeFrameActionListener( const css::uno::Reference< css::frame::XFrameActionListener >& xListener )
3240 : {
3241 0 : return !xListener.is();
3242 : }
3243 :
3244 0 : bool Frame::implcp_addEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
3245 : {
3246 0 : return !xListener.is();
3247 : }
3248 :
3249 0 : bool Frame::implcp_removeEventListener( const css::uno::Reference< css::lang::XEventListener >& xListener )
3250 : {
3251 0 : return !xListener.is();
3252 : }
3253 :
3254 0 : bool Frame::implcp_windowResized( const css::awt::WindowEvent& aEvent )
3255 : {
3256 0 : return !aEvent.Source.is();
3257 : }
3258 :
3259 0 : bool Frame::implcp_focusGained( const css::awt::FocusEvent& aEvent )
3260 : {
3261 0 : return !aEvent.Source.is();
3262 : }
3263 :
3264 0 : bool Frame::implcp_windowActivated( const css::lang::EventObject& aEvent )
3265 : {
3266 0 : return !aEvent.Source.is();
3267 : }
3268 :
3269 0 : bool Frame::implcp_windowDeactivated( const css::lang::EventObject& aEvent )
3270 : {
3271 0 : return !aEvent.Source.is();
3272 : }
3273 :
3274 0 : bool Frame::implcp_disposing( const css::lang::EventObject& aEvent )
3275 : {
3276 0 : return !aEvent.Source.is();
3277 : }
3278 :
3279 : }
3280 :
3281 : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
3282 3283 : com_sun_star_comp_framework_Frame_get_implementation(
3283 : css::uno::XComponentContext *context,
3284 : css::uno::Sequence<css::uno::Any> const &)
3285 : {
3286 3283 : Frame *inst = new Frame(context);
3287 3283 : css::uno::XInterface *acquired_inst = cppu::acquire(inst);
3288 :
3289 3283 : inst->initListeners();
3290 :
3291 3283 : return acquired_inst;
3292 648 : }
3293 :
3294 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|