Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "framework/framelistanalyzer.hxx"
30 : :
31 : : #include <threadhelp/writeguard.hxx>
32 : : #include <threadhelp/readguard.hxx>
33 : : #include <targets.h>
34 : : #include <properties.h>
35 : : #include <services.h>
36 : :
37 : : #include <com/sun/star/beans/XPropertySet.hpp>
38 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 : : #include <com/sun/star/frame/XModuleManager.hpp>
40 : :
41 : : #include <comphelper/processfactory.hxx>
42 : : #include <vcl/svapp.hxx>
43 : : #include <tools/diagnose_ex.h>
44 : :
45 : : namespace framework{
46 : :
47 : : /**
48 : : */
49 : :
50 : 9083 : FrameListAnalyzer::FrameListAnalyzer( const css::uno::Reference< css::frame::XFramesSupplier >& xSupplier ,
51 : : const css::uno::Reference< css::frame::XFrame >& xReferenceFrame ,
52 : : sal_uInt32 eDetectMode )
53 : : : m_xSupplier (xSupplier )
54 : : , m_xReferenceFrame(xReferenceFrame)
55 [ + - ][ + - ]: 9083 : , m_eDetectMode (eDetectMode )
56 : : {
57 [ + - ]: 9083 : impl_analyze();
58 : 9083 : }
59 : :
60 : : /**
61 : : */
62 : :
63 [ + - ][ + - ]: 9083 : FrameListAnalyzer::~FrameListAnalyzer()
64 : : {
65 [ - + ]: 9083 : }
66 : :
67 : : /** returns an analyzed list of all currently opened (top!) frames inside the desktop tree.
68 : :
69 : : We try to get a snapshot of all opened frames, which are part of the desktop frame container.
70 : : Of course we can't access frames, which stands outside of this tree.
71 : : But it's neccessary to collect top frames here only. Otherwhise we interpret closing of last
72 : : frame wrong. Further we analyze this list and split into different parts.
73 : : E.g. for "CloseDoc" we must know, which frames of the given list referr to the same model.
74 : : These frames must be closed then. But all other frames must be untouched.
75 : : In case the request was "CloseWin" these splitted lists can be used too, to decide if the last window
76 : : or document was closed. Then we have to initialize the backing window ...
77 : : Last but not least we must know something about our special help frame. It must be handled
78 : : seperatly. And last but not least - the backing component frame must be detected too.
79 : : */
80 : :
81 : 9083 : void FrameListAnalyzer::impl_analyze()
82 : : {
83 : : // reset all members to get a consistent state
84 : 9083 : m_bReferenceIsHidden = sal_False;
85 : 9083 : m_bReferenceIsHelp = sal_False;
86 : 9083 : m_bReferenceIsBacking = sal_False;
87 [ + - ]: 9083 : m_xHelp = css::uno::Reference< css::frame::XFrame >();
88 [ + - ]: 9083 : m_xBackingComponent = css::uno::Reference< css::frame::XFrame >();
89 : :
90 : : // try to get the task container by using the given supplier
91 [ + - ][ + - ]: 9083 : css::uno::Reference< css::container::XIndexAccess > xFrameContainer(m_xSupplier->getFrames(), css::uno::UNO_QUERY);
[ + - ]
92 : :
93 : : // All return list get an initial size to include all possible frames.
94 : : // They will be packed at the end of this method ... using the actual step positions then.
95 : 9083 : sal_Int32 nVisibleStep = 0;
96 : 9083 : sal_Int32 nHiddenStep = 0;
97 : 9083 : sal_Int32 nModelStep = 0;
98 [ + - ][ + - ]: 9083 : sal_Int32 nCount = xFrameContainer->getCount();
99 : :
100 [ + - ]: 9083 : m_lOtherVisibleFrames.realloc(nCount);
101 [ + - ]: 9083 : m_lOtherHiddenFrames.realloc(nCount);
102 [ + - ]: 9083 : m_lModelFrames.realloc(nCount);
103 : :
104 : : // ask for the model of the given reference frame.
105 : : // It must be compared with the model of every frame of the container
106 : : // to sort it into the list of frames with the same model.
107 : : // Supress this step, if right detect mode isn't set.
108 : 9083 : css::uno::Reference< css::frame::XModel > xReferenceModel;
109 [ + + ]: 9083 : if ((m_eDetectMode & E_MODEL) == E_MODEL )
110 : : {
111 : 2 : css::uno::Reference< css::frame::XController > xReferenceController;
112 [ + - ]: 2 : if (m_xReferenceFrame.is())
113 [ + - ][ + - ]: 2 : xReferenceController = m_xReferenceFrame->getController();
[ + - ]
114 [ + - ]: 2 : if (xReferenceController.is())
115 [ + - ][ + - ]: 2 : xReferenceModel = xReferenceController->getModel();
[ + - ]
116 : : }
117 : :
118 : : // check, if the reference frame is in hidden mode.
119 : : // But look, if this analyze step is realy needed.
120 [ + - ]: 9083 : css::uno::Reference< css::beans::XPropertySet > xSet(m_xReferenceFrame, css::uno::UNO_QUERY);
121 [ + + + - ]: 17596 : if (
[ + + ]
122 : : ((m_eDetectMode & E_HIDDEN) == E_HIDDEN) &&
123 : 8513 : (xSet.is() )
124 : : )
125 : : {
126 [ + - ][ + - ]: 8513 : xSet->getPropertyValue(FRAME_PROPNAME_ISHIDDEN) >>= m_bReferenceIsHidden;
[ + - ]
127 : : }
128 : :
129 : : // check, if the reference frame includes the backing component.
130 : : // But look, if this analyze step is realy needed.
131 [ + - ][ + + ]: 9083 : if (((m_eDetectMode & E_BACKINGCOMPONENT) == E_BACKINGCOMPONENT) && m_xReferenceFrame.is() )
[ + + ]
132 : : {
133 : : try
134 : : {
135 [ + - ]: 8515 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
136 [ + - ][ + - ]: 8515 : css::uno::Reference< css::frame::XModuleManager > xModuleMgr(xSMGR->createInstance(SERVICENAME_MODULEMANAGER), css::uno::UNO_QUERY_THROW);
[ + - ][ + - ]
137 [ + + ][ + - ]: 8515 : ::rtl::OUString sModule = xModuleMgr->identify(m_xReferenceFrame);
138 [ + - ]: 8515 : m_bReferenceIsBacking = (sModule.equals(SERVICENAME_STARTMODULE));
[ - + - ]
139 : : }
140 [ + - ]: 4114 : catch(const css::frame::UnknownModuleException&)
141 : : {
142 : : }
143 [ # # ]: 0 : catch(const css::uno::Exception&)
144 : : {
145 : : DBG_UNHANDLED_EXCEPTION();
146 : : }
147 : : }
148 : :
149 : : // check, if the reference frame includes the help module.
150 : : // But look, if this analyze step is realy needed.
151 [ + + + - : 35196 : if (
- + ][ - + ]
152 : : ((m_eDetectMode & E_HELP) == E_HELP ) &&
153 : 8515 : (m_xReferenceFrame.is() ) &&
154 [ + - ][ + - ]: 17598 : (m_xReferenceFrame->getName() == SPECIALTARGET_HELPTASK)
[ + - ][ + + ]
[ + + ]
[ # # # # ]
155 : : )
156 : : {
157 : 0 : m_bReferenceIsHelp = sal_True;
158 : : }
159 : :
160 : : try
161 : : {
162 : : // Step over all frames of the desktop frame container and analyze it.
163 [ + + ]: 29361 : for (sal_Int32 i=0; i<nCount; ++i)
164 : : {
165 : : // Ignore invalid items ... and of course the reference frame.
166 : : // It will be a member of the given frame list too - but it was already
167 : : // analyzed before!
168 : 20278 : css::uno::Reference< css::frame::XFrame > xFrame;
169 [ + - + - ]: 81112 : if (
[ + + ][ + + ]
170 [ + - ][ + - ]: 40556 : !(xFrameContainer->getByIndex(i) >>= xFrame) ||
[ + - ][ # # ]
[ + - ]
171 : 20278 : !(xFrame.is() ) ||
172 [ + - ]: 20278 : (xFrame==m_xReferenceFrame )
173 : : )
174 : 8515 : continue;
175 : :
176 : : #ifdef ENABLE_WARNINGS
177 : : if (
178 : : ((m_eDetectMode & E_ZOMBIE) == E_ZOMBIE) &&
179 : : (
180 : : (!xFrame->getContainerWindow().is()) ||
181 : : (!xFrame->getComponentWindow().is())
182 : : )
183 : : )
184 : : {
185 : : LOG_WARNING("FrameListAnalyzer::impl_analyze()", "ZOMBIE!")
186 : : }
187 : : #endif
188 : :
189 : : // -------------------------------------------------
190 : : // a) Is it the special help task?
191 : : // Return it seperated from any return list.
192 [ + + - + ]: 33230 : if (
[ - + ]
193 : : ((m_eDetectMode & E_HELP) == E_HELP ) &&
194 [ + - ][ + - ]: 21467 : (xFrame->getName()==SPECIALTARGET_HELPTASK)
[ + - ][ + + ]
[ + + ]
[ # # # # ]
195 : : )
196 : : {
197 [ # # ]: 0 : m_xHelp = xFrame;
198 : 0 : continue;
199 : : }
200 : :
201 : : // -------------------------------------------------
202 : : // b) Or is includes this task the special backing component?
203 : : // Return it seperated from any return list.
204 : : // But check if the reference task itself is the backing frame.
205 : : // Our user mst know it to decide right.
206 [ + - ]: 11763 : if ((m_eDetectMode & E_BACKINGCOMPONENT) == E_BACKINGCOMPONENT)
207 : : {
208 : : try
209 : : {
210 [ + - ]: 11763 : css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::comphelper::getProcessServiceFactory();
211 [ + - ][ + - ]: 11763 : css::uno::Reference< css::frame::XModuleManager > xModuleMgr(xSMGR->createInstance(SERVICENAME_MODULEMANAGER), css::uno::UNO_QUERY);
[ + - ][ + - ]
212 [ + + ][ + - ]: 11763 : ::rtl::OUString sModule = xModuleMgr->identify(xFrame);
213 [ + - ][ - + ]: 11619 : if (sModule.equals(SERVICENAME_STARTMODULE))
214 : : {
215 [ # # ]: 0 : m_xBackingComponent = xFrame;
216 : 11619 : continue;
217 [ - + ][ - + ]: 11763 : }
[ + - ][ - + ]
218 : : }
219 [ + - ]: 144 : catch (const css::uno::Exception&)
220 : : {
221 : : }
222 : : }
223 : :
224 : : // -------------------------------------------------
225 : : // c) Or is it the a task, which uses the specified model?
226 : : // Add it to the list of "model frames".
227 [ - + ]: 11763 : if ((m_eDetectMode & E_MODEL) == E_MODEL)
228 : : {
229 [ # # ][ # # ]: 0 : css::uno::Reference< css::frame::XController > xController = xFrame->getController();
230 : 0 : css::uno::Reference< css::frame::XModel > xModel ;
231 [ # # ]: 0 : if (xController.is())
232 [ # # ][ # # ]: 0 : xModel = xController->getModel();
[ # # ]
233 [ # # ][ # # ]: 0 : if (xModel==xReferenceModel)
234 : : {
235 [ # # ][ # # ]: 0 : m_lModelFrames[nModelStep] = xFrame;
236 : 0 : ++nModelStep;
237 : 0 : continue;
238 [ # # ][ # # ]: 0 : }
239 : : }
240 : :
241 : : // -------------------------------------------------
242 : : // d) Or is it the a task, which use another or no model at all?
243 : : // Add it to the list of "other frames". But look for it's
244 : : // visible state ... if it's allowed to do so.
245 : : // -------------------------------------------------
246 : 11763 : sal_Bool bHidden = sal_False;
247 [ + + ]: 11763 : if ((m_eDetectMode & E_HIDDEN) == E_HIDDEN )
248 : : {
249 [ + - ][ + - ]: 9704 : xSet = css::uno::Reference< css::beans::XPropertySet >(xFrame, css::uno::UNO_QUERY);
250 [ + - ]: 9704 : if (xSet.is())
251 : : {
252 [ + - ][ + - ]: 9704 : xSet->getPropertyValue(FRAME_PROPNAME_ISHIDDEN) >>= bHidden;
[ + - ]
253 : : }
254 : : }
255 : :
256 [ + + ]: 11763 : if (bHidden)
257 : : {
258 [ + - ][ + - ]: 920 : m_lOtherHiddenFrames[nHiddenStep] = xFrame;
259 : 920 : ++nHiddenStep;
260 : : }
261 : : else
262 : : {
263 [ + - ][ + - ]: 10843 : m_lOtherVisibleFrames[nVisibleStep] = xFrame;
264 : 11763 : ++nVisibleStep;
265 : : }
266 [ + + ][ # # ]: 20278 : }
267 : : }
268 [ # # ]: 0 : catch (const css::lang::IndexOutOfBoundsException&)
269 : : {
270 : : // stop copying if index seams to be wrong.
271 : : // This interface can't realy guarantee its count for multithreaded
272 : : // environments. So it can occure!
273 : : }
274 : :
275 : : // Pack both lists by using the actual step positions.
276 : : // All empty or ignorable items should exist at the end of these lists
277 : : // behind the position pointers. So they will be removed by a reallocation.
278 [ + - ]: 9083 : m_lOtherVisibleFrames.realloc(nVisibleStep);
279 [ + - ]: 9083 : m_lOtherHiddenFrames.realloc(nHiddenStep);
280 [ + - ]: 9083 : m_lModelFrames.realloc(nModelStep);
281 : 9083 : }
282 : :
283 : : } // namespace framework
284 : :
285 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|