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