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