Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : :
21 : : #include "fltfnc.hxx"
22 : : #include <com/sun/star/uno/Exception.hpp>
23 : : #include <com/sun/star/beans/PropertyValue.hpp>
24 : : #include <com/sun/star/beans/NamedValue.hpp>
25 : : #include <com/sun/star/container/XNameAccess.hpp>
26 : : #include <com/sun/star/container/XEnumeration.hpp>
27 : : #include <com/sun/star/datatransfer/DataFlavor.hpp>
28 : : #include <com/sun/star/document/XTypeDetection.hpp>
29 : : #include <com/sun/star/container/XContainerQuery.hpp>
30 : :
31 : : #include <comphelper/sequenceashashmap.hxx>
32 : :
33 : : #include <sot/exchange.hxx>
34 : : #include <basic/sbmeth.hxx>
35 : : #include <basic/basmgr.hxx>
36 : : #include <basic/sbstar.hxx>
37 : : #include <basic/sbxobj.hxx>
38 : : #include <basic/sbxmeth.hxx>
39 : : #include <basic/sbxcore.hxx>
40 : : #include <vcl/msgbox.hxx>
41 : : #include <rtl/ustring.hxx>
42 : : #include <rtl/ustrbuf.hxx>
43 : : #include <svl/eitem.hxx>
44 : : #include <svl/intitem.hxx>
45 : : #include <svl/stritem.hxx>
46 : : #include <svl/lckbitem.hxx>
47 : : #include <svl/inettype.hxx>
48 : : #include <svl/rectitem.hxx>
49 : :
50 : : #include <sot/storage.hxx>
51 : : #include <com/sun/star/frame/XDispatchProviderInterceptor.hpp>
52 : : #include <com/sun/star/frame/XDispatch.hpp>
53 : : #include <com/sun/star/frame/XDispatchProvider.hpp>
54 : : #include <com/sun/star/frame/XStatusListener.hpp>
55 : : #include <com/sun/star/frame/FrameSearchFlag.hpp>
56 : : #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
57 : : #include <com/sun/star/frame/FeatureStateEvent.hpp>
58 : : #include <com/sun/star/frame/DispatchDescriptor.hpp>
59 : : #include <com/sun/star/frame/XController.hpp>
60 : : #include <com/sun/star/frame/XFrameActionListener.hpp>
61 : : #include <com/sun/star/frame/XComponentLoader.hpp>
62 : : #include <com/sun/star/frame/XFrame.hpp>
63 : : #include <com/sun/star/frame/FrameActionEvent.hpp>
64 : : #include <com/sun/star/frame/FrameAction.hpp>
65 : : #include <com/sun/star/frame/XFrameLoader.hpp>
66 : : #include <com/sun/star/frame/XLoadEventListener.hpp>
67 : : #include <com/sun/star/frame/XFilterDetect.hpp>
68 : : #include <com/sun/star/loader/XImplementationLoader.hpp>
69 : : #include <comphelper/processfactory.hxx>
70 : :
71 : : #include <sal/types.h>
72 : : #include <com/sun/star/uno/Reference.hxx>
73 : : #include <com/sun/star/ucb/XContent.hpp>
74 : : #include <unotools/pathoptions.hxx>
75 : : #include <unotools/moduleoptions.hxx>
76 : : #include <comphelper/mediadescriptor.hxx>
77 : : #include <tools/urlobj.hxx>
78 : :
79 : : #include <rtl/logfile.hxx>
80 : : #include <rtl/instance.hxx>
81 : :
82 : : using namespace ::com::sun::star::uno;
83 : : using namespace ::com::sun::star::ucb;
84 : : using namespace ::com::sun::star::document;
85 : : using namespace ::com::sun::star::beans;
86 : : #include <svl/ctypeitm.hxx>
87 : : #include <svtools/sfxecode.hxx>
88 : : #include <unotools/syslocale.hxx>
89 : :
90 : : #include "sfx2/sfxhelp.hxx"
91 : : #include <sfx2/docfilt.hxx>
92 : : #include <sfx2/docfac.hxx>
93 : : #include "sfxtypes.hxx"
94 : : #include <sfx2/sfxuno.hxx>
95 : : #include <sfx2/docfile.hxx>
96 : : #include <sfx2/progress.hxx>
97 : : #include "openflag.hxx"
98 : : #include "bastyp.hrc"
99 : : #include "sfx2/sfxresid.hxx"
100 : : #include <sfx2/doctempl.hxx>
101 : : #include <sfx2/frame.hxx>
102 : : #include <sfx2/dispatch.hxx>
103 : : #include <sfx2/viewfrm.hxx>
104 : : #include "helper.hxx"
105 : : #include "fltlst.hxx"
106 : : #include <sfx2/request.hxx>
107 : : #include "arrdecl.hxx"
108 : : #include <sfx2/appuno.hxx>
109 : :
110 : : #include <boost/ptr_container/ptr_vector.hpp>
111 : : #include <functional>
112 : :
113 : : namespace
114 : : {
115 : : class theSfxFilterListener : public rtl::Static<SfxFilterListener, theSfxFilterListener> {};
116 : : }
117 : :
118 : : static SfxFilterList_Impl* pFilterArr = 0;
119 : : static sal_Bool bFirstRead = sal_True;
120 : :
121 : 127 : static void CreateFilterArr()
122 : : {
123 [ + - ]: 127 : pFilterArr = new SfxFilterList_Impl;
124 : 127 : theSfxFilterListener::get();
125 : 127 : }
126 : :
127 : : //----------------------------------------------------------------
128 : 0 : inline String ToUpper_Impl( const String &rStr )
129 : : {
130 [ # # ][ # # ]: 0 : return SvtSysLocale().GetCharClass().uppercase( rStr );
[ # # ][ # # ]
[ # # ]
131 : : }
132 : :
133 : : //----------------------------------------------------------------
134 [ + - ]: 1201 : class SfxFilterContainer_Impl
135 : : {
136 : : public:
137 : : String aName;
138 : : String aServiceName;
139 : :
140 : 1201 : SfxFilterContainer_Impl( const String& rName )
141 [ + - ]: 1201 : : aName( rName )
142 : : {
143 [ + - ][ + - ]: 1201 : aServiceName = SfxObjectShell::GetServiceNameFromFactory( rName );
[ + - ]
144 : 1201 : }
145 : : };
146 : :
147 : : #define IMPL_FORWARD_LOOP( aMethod, ArgType, aArg ) \
148 : : const SfxFilter* SfxFilterContainer::aMethod( ArgType aArg, SfxFilterFlags nMust, SfxFilterFlags nDont ) const \
149 : : {\
150 : : SfxFilterMatcher aMatch( pImpl->aName ); \
151 : : return aMatch.aMethod( aArg, nMust, nDont ); \
152 : : }
153 : :
154 [ # # ][ # # ]: 0 : IMPL_FORWARD_LOOP( GetFilter4EA, const String&, rEA );
[ # # ]
155 [ # # ][ # # ]: 0 : IMPL_FORWARD_LOOP( GetFilter4Extension, const String&, rExt );
[ # # ]
156 [ + - ][ + - ]: 2907 : IMPL_FORWARD_LOOP( GetFilter4FilterName, const String&, rName );
[ + - ]
157 : :
158 : 0 : const SfxFilter* SfxFilterContainer::GetAnyFilter( SfxFilterFlags nMust, SfxFilterFlags nDont ) const
159 : : {
160 [ # # ]: 0 : SfxFilterMatcher aMatch( pImpl->aName );
161 [ # # ][ # # ]: 0 : return aMatch.GetAnyFilter( nMust, nDont );
162 : : }
163 : :
164 : : //----------------------------------------------------------------
165 : :
166 : 1201 : SfxFilterContainer::SfxFilterContainer( const String& rName )
167 : : {
168 [ + - ]: 1201 : pImpl = new SfxFilterContainer_Impl( rName );
169 : 1201 : }
170 : :
171 : : //----------------------------------------------------------------
172 : :
173 : 1201 : SfxFilterContainer::~SfxFilterContainer()
174 : : {
175 [ + - ]: 1201 : delete pImpl;
176 : 1201 : }
177 : :
178 : : //----------------------------------------------------------------
179 : :
180 : 398 : const String SfxFilterContainer::GetName() const
181 : : {
182 : 398 : return pImpl->aName;
183 : : }
184 : :
185 : 10 : const SfxFilter* SfxFilterContainer::GetDefaultFilter_Impl( const String& rName )
186 : : {
187 : : // Try to find out the type of factory.
188 : : // Interpret given name as Service- and ShortName!
189 [ + - ]: 10 : SvtModuleOptions aOpt;
190 [ + - ][ + - ]: 10 : SvtModuleOptions::EFactory eFactory = aOpt.ClassifyFactoryByServiceName(rName);
191 [ - + ]: 10 : if (eFactory == SvtModuleOptions::E_UNKNOWN_FACTORY)
192 [ # # ][ # # ]: 0 : eFactory = aOpt.ClassifyFactoryByShortName(rName);
193 : :
194 : : // could not classify factory by its service nor by its short name.
195 : : // Must be an unknown factory! => return NULL
196 [ - + ]: 10 : if (eFactory == SvtModuleOptions::E_UNKNOWN_FACTORY)
197 : 0 : return NULL;
198 : :
199 : : // For the following code we need some additional informations.
200 [ + - ][ + - ]: 10 : String sServiceName = aOpt.GetFactoryName(eFactory);
201 [ + - ][ + - ]: 10 : String sShortName = aOpt.GetFactoryShortName(eFactory);
202 [ + - ][ + - ]: 10 : String sDefaultFilter = aOpt.GetFactoryDefaultFilter(eFactory);
203 : :
204 : : // Try to get the default filter. Dont fiorget to verify it.
205 : : // May the set default filter does not exists any longer or
206 : : // does not fit the given factory.
207 [ + - ]: 10 : const SfxFilterMatcher aMatcher;
208 [ + - ]: 10 : const SfxFilter* pFilter = aMatcher.GetFilter4FilterName(sDefaultFilter);
209 : :
210 [ + - - + ]: 30 : if (
[ - + ]
211 : : pFilter &&
212 [ + - ][ + - ]: 20 : !pFilter->GetServiceName().equalsIgnoreAsciiCase(sServiceName)
[ # # ]
213 : : )
214 : : {
215 : 0 : pFilter = 0;
216 : : }
217 : :
218 : : // If at least no default filter could be located - use any filter of this
219 : : // factory.
220 [ - + ]: 10 : if (!pFilter)
221 : : {
222 [ # # ]: 0 : if ( bFirstRead )
223 [ # # ]: 0 : ReadFilters_Impl();
224 : :
225 [ # # ]: 0 : for ( size_t i = 0, n = pFilterArr->size(); i < n; ++i )
226 : : {
227 [ # # ]: 0 : const SfxFilter* pCheckFilter = pFilterArr->at( i );
228 [ # # ][ # # ]: 0 : if ( pCheckFilter->GetServiceName().equalsIgnoreAsciiCase(sServiceName) )
229 : : {
230 : 0 : pFilter = pCheckFilter;
231 : 0 : break;
232 : : }
233 : : }
234 : : }
235 : :
236 [ + - ][ + - ]: 10 : return pFilter;
[ + - ][ + - ]
[ + - ]
237 : : }
238 : :
239 : :
240 : : //----------------------------------------------------------------
241 : :
242 : : // Impl-Data is shared between all FilterMatchers of the same factory
243 : 3688 : class SfxFilterMatcher_Impl
244 : : {
245 : : public:
246 : : ::rtl::OUString aName;
247 : : SfxFilterList_Impl* pList; // is created on demand
248 : :
249 : : void InitForIterating() const;
250 : : void Update();
251 : 3688 : SfxFilterMatcher_Impl(const ::rtl::OUString &rName)
252 : : : aName(rName)
253 : 3688 : , pList(0)
254 : : {
255 : 3688 : }
256 : : };
257 : :
258 : : namespace
259 : : {
260 : : typedef boost::ptr_vector<SfxFilterMatcher_Impl> SfxFilterMatcherArr_Impl;
261 : 245 : static SfxFilterMatcherArr_Impl aImplArr;
262 : : static int nSfxFilterMatcherCount;
263 : :
264 : : class hasName :
265 : : public std::unary_function<SfxFilterMatcher_Impl, bool>
266 : : {
267 : : private:
268 : : const rtl::OUString& mrName;
269 : : public:
270 : 14003 : hasName(const rtl::OUString &rName) : mrName(rName) {}
271 : 181005 : bool operator() (const SfxFilterMatcher_Impl& rImpl) const
272 : : {
273 : 181005 : return rImpl.aName == mrName;
274 : : }
275 : : };
276 : :
277 : 14003 : SfxFilterMatcher_Impl & getSfxFilterMatcher_Impl(const rtl::OUString &rName)
278 : : {
279 : 14003 : rtl::OUString aName;
280 : :
281 [ + + ]: 14003 : if (!rName.isEmpty())
282 [ + - ][ + - ]: 3499 : aName = SfxObjectShell::GetServiceNameFromFactory(rName);
[ + - ][ + - ]
[ + - ]
283 : :
284 : : // find the impl-Data of any comparable FilterMatcher that was created
285 : : // previously
286 [ + - ]: 14003 : SfxFilterMatcherArr_Impl::iterator aEnd = aImplArr.end();
287 : : SfxFilterMatcherArr_Impl::iterator aIter =
288 [ + - ][ + - ]: 14003 : std::find_if(aImplArr.begin(), aEnd, hasName(rName));
289 [ + - ][ + + ]: 14003 : if (aIter != aEnd)
290 [ + - ]: 10315 : return *aIter;
291 : :
292 : : // first Matcher created for this factory
293 [ + - ]: 3688 : SfxFilterMatcher_Impl *pImpl = new SfxFilterMatcher_Impl(aName);
294 [ + - ]: 3688 : aImplArr.push_back(pImpl);
295 : 14003 : return *pImpl;
296 : : }
297 : : }
298 : :
299 : 3499 : SfxFilterMatcher::SfxFilterMatcher( const String& rName )
300 [ + - ][ + - ]: 3499 : : m_rImpl( getSfxFilterMatcher_Impl(rName) )
301 : : {
302 : 3499 : ++nSfxFilterMatcherCount;
303 : 3499 : }
304 : :
305 : 10504 : SfxFilterMatcher::SfxFilterMatcher()
306 [ + - ]: 10504 : : m_rImpl( getSfxFilterMatcher_Impl(::rtl::OUString()) )
307 : : {
308 : : // global FilterMatcher always uses global filter array (also created on
309 : : // demand)
310 : 10504 : ++nSfxFilterMatcherCount;
311 : 10504 : }
312 : :
313 : 13958 : SfxFilterMatcher::~SfxFilterMatcher()
314 : : {
315 : 13958 : --nSfxFilterMatcherCount;
316 [ + + ]: 13958 : if (nSfxFilterMatcherCount == 0)
317 [ + - ]: 1132 : aImplArr.clear();
318 : 13958 : }
319 : :
320 : 632 : void SfxFilterMatcher_Impl::Update()
321 : : {
322 [ + + ]: 632 : if ( pList )
323 : : {
324 : : // this List was already used
325 : 430 : pList->clear();
326 [ + + ]: 80724 : for ( size_t i = 0, n = pFilterArr->size(); i < n; ++i )
327 : : {
328 [ + - ]: 80294 : SfxFilter* pFilter = pFilterArr->at( i );
329 [ + + ]: 80294 : if ( pFilter->GetServiceName() == aName )
330 [ + - ]: 13554 : pList->push_back( pFilter );
331 : : }
332 : : }
333 : 632 : }
334 : :
335 : 430 : void SfxFilterMatcher_Impl::InitForIterating() const
336 : : {
337 [ - + ]: 430 : if ( pList )
338 : 430 : return;
339 : :
340 [ + + ]: 430 : if ( bFirstRead )
341 : : // global filter array has not been created yet
342 : 23 : SfxFilterContainer::ReadFilters_Impl();
343 : :
344 [ + - ]: 430 : if ( !aName.isEmpty() )
345 : : {
346 : : // matcher of factory: use only filters of that document type
347 [ + - ]: 430 : ((SfxFilterMatcher_Impl*)this)->pList = new SfxFilterList_Impl;
348 : 430 : ((SfxFilterMatcher_Impl*)this)->Update();
349 : : }
350 : : else
351 : : {
352 : : // global matcher: use global filter array
353 : 0 : ((SfxFilterMatcher_Impl*)this)->pList = pFilterArr;
354 : : }
355 : : }
356 : :
357 : 0 : const SfxFilter* SfxFilterMatcher::GetAnyFilter( SfxFilterFlags nMust, SfxFilterFlags nDont ) const
358 : : {
359 : 0 : m_rImpl.InitForIterating();
360 [ # # ]: 0 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
361 : : {
362 : 0 : const SfxFilter* pFilter = m_rImpl.pList->at( i );
363 : 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
364 [ # # ][ # # ]: 0 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) )
365 : 0 : return pFilter;
366 : : }
367 : :
368 : 0 : return NULL;
369 : : }
370 : :
371 : : //----------------------------------------------------------------
372 : :
373 : 0 : sal_uInt32 SfxFilterMatcher::GuessFilterIgnoringContent(
374 : : SfxMedium& rMedium,
375 : : const SfxFilter**ppFilter,
376 : : SfxFilterFlags nMust,
377 : : SfxFilterFlags nDont ) const
378 : : {
379 [ # # ][ # # ]: 0 : Reference< XTypeDetection > xDetection( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString("com.sun.star.document.TypeDetection")), UNO_QUERY );
[ # # ][ # # ]
380 : 0 : ::rtl::OUString sTypeName;
381 : : try
382 : : {
383 [ # # ][ # # ]: 0 : sTypeName = xDetection->queryTypeByURL( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
[ # # ][ # # ]
[ # # ]
384 : : }
385 [ # # ]: 0 : catch( Exception& )
386 : : {
387 : : }
388 : :
389 : 0 : *ppFilter = NULL;
390 [ # # ]: 0 : if ( !sTypeName.isEmpty() )
391 : : {
392 : : // make sure filter list is initialized
393 [ # # ]: 0 : m_rImpl.InitForIterating();
394 [ # # ][ # # ]: 0 : *ppFilter = GetFilter4EA( sTypeName, nMust, nDont );
[ # # ]
395 : : }
396 : :
397 [ # # ]: 0 : return *ppFilter ? ERRCODE_NONE : ERRCODE_ABORT;
398 : : }
399 : :
400 : : //----------------------------------------------------------------
401 : :
402 : 11 : sal_uInt32 SfxFilterMatcher::GuessFilter( SfxMedium& rMedium, const SfxFilter**ppFilter, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
403 : : {
404 : 11 : return GuessFilterControlDefaultUI( rMedium, ppFilter, nMust, nDont, sal_True );
405 : : }
406 : :
407 : : //----------------------------------------------------------------
408 : :
409 : 11 : sal_uInt32 SfxFilterMatcher::GuessFilterControlDefaultUI( SfxMedium& rMedium, const SfxFilter** ppFilter, SfxFilterFlags nMust, SfxFilterFlags nDont, sal_Bool /*bDefUI*/ ) const
410 : : {
411 : 11 : const SfxFilter* pOldFilter = *ppFilter;
412 : :
413 : : // no detection service -> nothing to do !
414 [ + - ][ + - ]: 11 : Reference< XTypeDetection > xDetection( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString("com.sun.star.document.TypeDetection")), UNO_QUERY );
[ + - ][ + - ]
415 [ + + ]: 11 : if (!xDetection.is())
416 : 6 : return ERRCODE_ABORT;
417 : :
418 : 5 : ::rtl::OUString sTypeName;
419 : : try
420 : : {
421 : : // open the stream one times only ...
422 : : // Otherwhise it will be tried more then once and show the same interaction more then once ...
423 : :
424 [ + - ][ + - ]: 5 : ::rtl::OUString sURL( rMedium.GetURLObject().GetMainURL( INetURLObject::NO_DECODE ) );
425 [ + - ]: 5 : ::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInStream = rMedium.GetInputStream();
426 : 5 : rtl::OUString aFilterName;
427 : :
428 : : // stream exists => deep detection (with preselection ... if possible)
429 [ + - ]: 5 : if (xInStream.is())
430 : : {
431 [ + - ]: 5 : ::comphelper::MediaDescriptor aDescriptor;
432 : :
433 [ + - ][ + - ]: 5 : aDescriptor[::comphelper::MediaDescriptor::PROP_URL() ] <<= sURL;
[ + - ]
434 [ + - ][ + - ]: 5 : aDescriptor[::comphelper::MediaDescriptor::PROP_INPUTSTREAM() ] <<= xInStream;
[ + - ]
435 [ + - ][ + - ]: 5 : aDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= rMedium.GetInteractionHandler();
[ + - ][ + - ]
436 : :
437 [ + - ]: 5 : if ( !m_rImpl.aName.isEmpty() )
438 [ + - ][ + - ]: 5 : aDescriptor[::comphelper::MediaDescriptor::PROP_DOCUMENTSERVICE()] <<= m_rImpl.aName;
[ + - ]
439 : :
440 [ - + ]: 5 : if ( pOldFilter )
441 : : {
442 [ # # ][ # # ]: 0 : aDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME() ] <<= ::rtl::OUString( pOldFilter->GetTypeName() );
[ # # ][ # # ]
443 [ # # ][ # # ]: 0 : aDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= ::rtl::OUString( pOldFilter->GetFilterName() );
[ # # ][ # # ]
444 : : }
445 : :
446 [ + - ]: 5 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > lDescriptor = aDescriptor.getAsConstPropertyValueList();
447 [ + - ][ + - ]: 5 : sTypeName = xDetection->queryTypeByDescriptor(lDescriptor, sal_True); // lDescriptor is used as In/Out param ... dont use aDescriptor.getAsConstPropertyValueList() directly!
448 : :
449 [ + + ]: 40 : for (sal_Int32 i = 0; i < lDescriptor.getLength(); ++i)
450 : : {
451 [ + - ][ + + ]: 35 : if (lDescriptor[i].Name == "FilterName")
452 : : // Type detection picked a preferred filter for this format.
453 [ + - ][ + - ]: 5 : aFilterName = lDescriptor[i].Value.get<rtl::OUString>();
454 [ + - ][ + - ]: 5 : }
455 : : }
456 : : // no stream exists => try flat detection without preselection as fallback
457 : : else
458 [ # # ][ # # ]: 0 : sTypeName = xDetection->queryTypeByURL(sURL);
459 : :
460 [ + - ]: 5 : if (!sTypeName.isEmpty())
461 : : {
462 : 5 : const SfxFilter* pFilter = NULL;
463 [ + - ]: 5 : if (!aFilterName.isEmpty())
464 : : // Type detection returned a suitable filter for this. Use it.
465 [ + - ][ + - ]: 5 : pFilter = SfxFilter::GetFilterByName(aFilterName);
[ + - ]
466 : :
467 [ - + ]: 5 : if (!pFilter)
468 : : {
469 : : // detect filter by given type
470 : : // In case of this matcher is bound to a particular document type:
471 : : // If there is no acceptable type for this document at all, the type detection has possibly returned something else.
472 : : // The DocumentService property is only a preselection, and all preselections are considered as optional!
473 : : // This "wrong" type will be sorted out now because we match only allowed filters to the detected type
474 [ # # ]: 0 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::NamedValue > lQuery(1);
475 [ # # ]: 0 : lQuery[0].Name = ::rtl::OUString("Name");
476 [ # # ][ # # ]: 0 : lQuery[0].Value <<= sTypeName;
477 : :
478 [ # # ][ # # ]: 0 : pFilter = GetFilterForProps(lQuery, nMust, nDont);
479 : : }
480 : :
481 [ + - ]: 5 : if (pFilter)
482 : : {
483 : 5 : *ppFilter = pFilter;
484 : 5 : return ERRCODE_NONE;
485 : : }
486 [ + - ][ + - ]: 5 : }
[ - + ][ # # ]
487 : : }
488 [ # # ]: 0 : catch(const Exception&)
489 : : {}
490 : :
491 : 11 : return ERRCODE_ABORT;
492 : : }
493 : :
494 : : //----------------------------------------------------------------
495 : 0 : sal_Bool SfxFilterMatcher::IsFilterInstalled_Impl( const SfxFilter* pFilter )
496 : : {
497 [ # # ]: 0 : if ( pFilter->GetFilterFlags() & SFX_FILTER_MUSTINSTALL )
498 : : {
499 : : // Here could a re-installation be offered
500 [ # # ][ # # ]: 0 : String aText( SfxResId(STR_FILTER_NOT_INSTALLED).toString() );
[ # # ]
501 [ # # ]: 0 : aText.SearchAndReplaceAscii( "$(FILTER)", pFilter->GetUIName() );
502 [ # # ]: 0 : QueryBox aQuery( NULL, WB_YES_NO | WB_DEF_YES, aText );
503 [ # # ]: 0 : short nRet = aQuery.Execute();
504 : : if ( nRet == RET_YES )
505 : : {
506 : : #ifdef DBG_UTIL
507 : : // Start Setup
508 : : InfoBox( NULL, DEFINE_CONST_UNICODE("Here should the Setup now be starting!") ).Execute();
509 : : #endif
510 : : // Installation must still give feedback if it worked or not,
511 : : // then the Filterflag be deleted
512 : : }
513 : :
514 [ # # ][ # # ]: 0 : return ( !(pFilter->GetFilterFlags() & SFX_FILTER_MUSTINSTALL) );
515 : : }
516 [ # # ]: 0 : else if ( pFilter->GetFilterFlags() & SFX_FILTER_CONSULTSERVICE )
517 : : {
518 [ # # ][ # # ]: 0 : String aText( SfxResId(STR_FILTER_CONSULT_SERVICE).toString() );
[ # # ]
519 [ # # ]: 0 : aText.SearchAndReplaceAscii( "$(FILTER)", pFilter->GetUIName() );
520 [ # # ][ # # ]: 0 : InfoBox ( NULL, aText ).Execute();
[ # # ]
521 [ # # ]: 0 : return sal_False;
522 : : }
523 : : else
524 : 0 : return sal_True;
525 : : }
526 : :
527 : :
528 : 0 : sal_uInt32 SfxFilterMatcher::DetectFilter( SfxMedium& rMedium, const SfxFilter**ppFilter, sal_Bool /*bPlugIn*/, sal_Bool bAPI ) const
529 : : /* [Description]
530 : :
531 : : Here the Filter selection box is pulled up. Otherwise GuessFilter
532 : : */
533 : :
534 : : {
535 [ # # ]: 0 : const SfxFilter* pOldFilter = rMedium.GetFilter();
536 [ # # ]: 0 : if ( pOldFilter )
537 : : {
538 [ # # ][ # # ]: 0 : if( !IsFilterInstalled_Impl( pOldFilter ) )
539 : 0 : pOldFilter = 0;
540 : : else
541 : : {
542 [ # # ][ # # ]: 0 : SFX_ITEMSET_ARG( rMedium.GetItemSet(), pSalvageItem, SfxStringItem, SID_DOC_SALVAGE, sal_False);
[ # # ]
543 [ # # ][ # # ]: 0 : if ( ( pOldFilter->GetFilterFlags() & SFX_FILTER_PACKED ) && pSalvageItem )
[ # # ]
544 : : // Salvage is always done without packing
545 : 0 : pOldFilter = 0;
546 : : }
547 : : }
548 : :
549 : 0 : const SfxFilter* pFilter = pOldFilter;
550 : :
551 [ # # ]: 0 : sal_Bool bPreview = rMedium.IsPreview_Impl();
552 [ # # ][ # # ]: 0 : SFX_ITEMSET_ARG(rMedium.GetItemSet(), pReferer, SfxStringItem, SID_REFERER, sal_False);
[ # # ]
553 [ # # ][ # # ]: 0 : if ( bPreview && rMedium.IsRemote() && ( !pReferer || pReferer->GetValue().CompareToAscii("private:searchfolder:",21 ) != COMPARE_EQUAL ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
554 : 0 : return ERRCODE_ABORT;
555 : :
556 [ # # ]: 0 : ErrCode nErr = GuessFilter( rMedium, &pFilter );
557 [ # # ]: 0 : if ( nErr == ERRCODE_ABORT )
558 : 0 : return nErr;
559 : :
560 [ # # ]: 0 : if ( nErr == ERRCODE_IO_PENDING )
561 : : {
562 : 0 : *ppFilter = pFilter;
563 : 0 : return nErr;
564 : : }
565 : :
566 [ # # ]: 0 : if ( !pFilter )
567 : : {
568 : 0 : const SfxFilter* pInstallFilter = NULL;
569 : :
570 : : // Now test the filter which are not installed (ErrCode is irrelevant)
571 [ # # ]: 0 : GuessFilter( rMedium, &pInstallFilter, SFX_FILTER_IMPORT, SFX_FILTER_CONSULTSERVICE );
572 [ # # ]: 0 : if ( pInstallFilter )
573 : : {
574 [ # # ][ # # ]: 0 : if ( IsFilterInstalled_Impl( pInstallFilter ) )
575 : : // Maybe the filter was installed was installed afterwards.
576 : 0 : pFilter = pInstallFilter;
577 : : }
578 : : else
579 : : {
580 : : // Now test the filter, which first must be obtained by Star
581 : : // (ErrCode is irrelevant)
582 [ # # ]: 0 : GuessFilter( rMedium, &pInstallFilter, SFX_FILTER_IMPORT, 0 );
583 [ # # ]: 0 : if ( pInstallFilter )
584 [ # # ]: 0 : IsFilterInstalled_Impl( pInstallFilter );
585 : : }
586 : : }
587 : :
588 : 0 : sal_Bool bHidden = bPreview;
589 [ # # ][ # # ]: 0 : SFX_ITEMSET_ARG( rMedium.GetItemSet(), pFlags, SfxStringItem, SID_OPTIONS, sal_False);
[ # # ]
590 [ # # ][ # # ]: 0 : if ( !bHidden && pFlags )
591 : : {
592 [ # # ]: 0 : String aFlags( pFlags->GetValue() );
593 [ # # ]: 0 : aFlags.ToUpperAscii();
594 [ # # ][ # # ]: 0 : if( STRING_NOTFOUND != aFlags.Search( 'H' ) )
595 [ # # ]: 0 : bHidden = sal_True;
596 : : }
597 : 0 : *ppFilter = pFilter;
598 : :
599 [ # # ][ # # ]: 0 : if ( bHidden || (bAPI && nErr == ERRCODE_SFX_CONSULTUSER) )
[ # # ]
600 [ # # ]: 0 : nErr = pFilter ? ERRCODE_NONE : ERRCODE_ABORT;
601 : 0 : return nErr;
602 : : }
603 : :
604 : 3991 : const SfxFilter* SfxFilterMatcher::GetFilterForProps( const com::sun::star::uno::Sequence < ::com::sun::star::beans::NamedValue >& aSeq, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
605 : : {
606 [ + - ]: 3991 : ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
607 : 3991 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerQuery > xTypeCFG;
608 [ + - ]: 3991 : if( xServiceManager.is() == sal_True )
609 [ + - ][ + - ]: 3991 : xTypeCFG = ::com::sun::star::uno::Reference < com::sun::star::container::XContainerQuery >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" ) ), ::com::sun::star::uno::UNO_QUERY );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
610 [ + - ]: 3991 : if ( xTypeCFG.is() )
611 : : {
612 : : // make query for all types matching the properties
613 [ + - ][ + - ]: 3991 : ::com::sun::star::uno::Reference < com::sun::star::container::XEnumeration > xEnum = xTypeCFG->createSubSetEnumerationByProperties( aSeq );
614 [ + - ][ + - ]: 4034 : while ( xEnum->hasMoreElements() )
[ + + ]
615 : : {
616 [ + - ][ + - ]: 3899 : ::comphelper::SequenceAsHashMap aProps( xEnum->nextElement() );
[ + - ]
617 : 3899 : ::rtl::OUString aValue;
618 : :
619 : : // try to get the preferred filter (works without loading all filters!)
620 [ + - ][ + - ]: 3899 : if ( (aProps[::rtl::OUString("PreferredFilter")] >>= aValue) && !aValue.isEmpty() )
[ + - ][ + - ]
[ + - # #
# # ][ + - ]
621 : : {
622 [ + - ][ + - ]: 3899 : const SfxFilter* pFilter = SfxFilter::GetFilterByName( aValue );
[ + - ]
623 [ + - ][ + - ]: 3899 : if ( !pFilter || (pFilter->GetFilterFlags() & nMust) != nMust || (pFilter->GetFilterFlags() & nDont ) )
[ + + ][ + + ]
624 : : // check for filter flags
625 : : // pFilter == 0: if preferred filter is a Writer filter, but Writer module is not installed
626 : 11 : continue;
627 : :
628 [ + + ]: 3888 : if ( !m_rImpl.aName.isEmpty() )
629 : : {
630 : : // if this is not the global FilterMatcher: check if filter matches the document type
631 [ + + ]: 160 : if ( pFilter->GetServiceName() != m_rImpl.aName )
632 : : {
633 : : // preferred filter belongs to another document type; now we must search the filter
634 [ + - ]: 32 : m_rImpl.InitForIterating();
635 [ + - ]: 32 : aProps[::rtl::OUString("Name")] >>= aValue;
636 [ + - ][ + - ]: 32 : pFilter = GetFilter4EA( aValue, nMust, nDont );
[ + - ]
637 [ - + ]: 32 : if ( pFilter )
638 : 0 : return pFilter;
639 : : }
640 : : else
641 : 128 : return pFilter;
642 : : }
643 : : else
644 : 3760 : return pFilter;
645 : : }
646 [ + + + ]: 4034 : }
[ + - ]
[ + + + ]
[ + + ]
647 : : }
648 : :
649 : 3991 : return 0;
650 : : }
651 : :
652 : 0 : const SfxFilter* SfxFilterMatcher::GetFilter4Mime( const ::rtl::OUString& rMediaType, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
653 : : {
654 [ # # ]: 0 : if ( m_rImpl.pList )
655 : : {
656 [ # # ]: 0 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
657 : : {
658 [ # # ]: 0 : const SfxFilter* pFilter = m_rImpl.pList->at( i );
659 : 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
660 [ # # ][ # # ]: 0 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetMimeType() == rMediaType )
[ # # ][ # # ]
661 : 0 : return pFilter;
662 : : }
663 : :
664 : 0 : return 0;
665 : : }
666 : :
667 [ # # ]: 0 : com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
668 [ # # ]: 0 : aSeq[0].Name = ::rtl::OUString("MediaType");
669 [ # # ][ # # ]: 0 : aSeq[0].Value <<= rMediaType;
670 [ # # ][ # # ]: 0 : return GetFilterForProps( aSeq, nMust, nDont );
671 : : }
672 : :
673 : 2237 : const SfxFilter* SfxFilterMatcher::GetFilter4EA( const String& rType,SfxFilterFlags nMust, SfxFilterFlags nDont ) const
674 : : {
675 [ + + ]: 2237 : if ( m_rImpl.pList )
676 : : {
677 : 32 : const SfxFilter* pFirst = 0;
678 [ + + ]: 846 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
679 : : {
680 [ + - ]: 814 : const SfxFilter* pFilter = m_rImpl.pList->at( i );
681 : 814 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
682 [ + + ][ + - ]: 814 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetTypeName() == rType )
[ - + ][ - + ]
[ + + ]
683 : : {
684 [ # # ]: 0 : if (nFlags & SFX_FILTER_PREFERED)
685 : 0 : return pFilter;
686 [ # # ]: 0 : if (!pFirst)
687 : 0 : pFirst = pFilter;
688 : : }
689 : : }
690 [ - + ]: 32 : if (pFirst)
691 : 0 : return pFirst;
692 : :
693 : 32 : return 0;
694 : : }
695 : :
696 [ + - ]: 2205 : com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
697 [ + - ]: 2205 : aSeq[0].Name = ::rtl::OUString("Name");
698 [ + - ][ + - ]: 2205 : aSeq[0].Value <<= ::rtl::OUString( rType );
[ + - ]
699 [ + - ][ + - ]: 2237 : return GetFilterForProps( aSeq, nMust, nDont );
700 : : }
701 : :
702 : 0 : const SfxFilter* SfxFilterMatcher::GetFilter4Extension( const String& rExt, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
703 : : {
704 [ # # ]: 0 : if ( m_rImpl.pList )
705 : : {
706 [ # # ]: 0 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
707 : : {
708 [ # # ]: 0 : const SfxFilter* pFilter = m_rImpl.pList->at( i );
709 : 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
710 [ # # ][ # # ]: 0 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) )
711 : : {
712 [ # # ][ # # ]: 0 : String sWildCard = ToUpper_Impl( pFilter->GetWildcard().getGlob() );
[ # # ][ # # ]
713 [ # # ]: 0 : String sExt = ToUpper_Impl( rExt );
714 : :
715 [ # # ]: 0 : if (!sExt.Len())
716 : 0 : continue;
717 : :
718 [ # # ]: 0 : if (sExt.GetChar(0) != (sal_Unicode)'.')
719 [ # # ]: 0 : sExt.Insert((sal_Unicode)'.', 0);
720 : :
721 [ # # ][ # # ]: 0 : WildCard aCheck(sWildCard, ';');
722 [ # # ][ # # ]: 0 : if (aCheck.Matches(sExt))
723 [ # # ][ # # ]: 0 : return pFilter;
[ # # ]
[ # # # ]
[ # # ]
[ # # # ]
724 : : }
725 : : }
726 : :
727 : 0 : return 0;
728 : : }
729 : :
730 : : // Use extension without dot!
731 [ # # ]: 0 : String sExt( rExt );
732 [ # # ][ # # ]: 0 : if ( sExt.Len() && ( sExt.GetChar(0) == (sal_Unicode)'.' ))
[ # # ]
733 [ # # ]: 0 : sExt.Erase(0,1);
734 : :
735 [ # # ]: 0 : com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
736 [ # # ]: 0 : aSeq[0].Name = ::rtl::OUString("Extensions");
737 [ # # ]: 0 : ::com::sun::star::uno::Sequence < ::rtl::OUString > aExts(1);
738 [ # # ][ # # ]: 0 : aExts[0] = sExt;
739 [ # # ][ # # ]: 0 : aSeq[0].Value <<= aExts;
740 [ # # ][ # # ]: 0 : return GetFilterForProps( aSeq, nMust, nDont );
[ # # ][ # # ]
741 : : }
742 : :
743 : 1786 : const SfxFilter* SfxFilterMatcher::GetFilter4ClipBoardId( sal_uInt32 nId, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
744 : : {
745 [ - + ]: 1786 : if (nId == 0)
746 : 0 : return 0;
747 : :
748 [ + - ]: 1786 : com::sun::star::uno::Sequence < com::sun::star::beans::NamedValue > aSeq(1);
749 [ + - ][ + - ]: 1786 : ::rtl::OUString aName = SotExchange::GetFormatName( nId );
[ + - ]
750 [ + - ]: 1786 : aSeq[0].Name = ::rtl::OUString("ClipboardFormat");
751 [ + - ][ + - ]: 1786 : aSeq[0].Value <<= aName;
752 [ + - ][ + - ]: 1786 : return GetFilterForProps( aSeq, nMust, nDont );
753 : : }
754 : :
755 : 0 : const SfxFilter* SfxFilterMatcher::GetFilter4UIName( const String& rName, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
756 : : {
757 : 0 : m_rImpl.InitForIterating();
758 : 0 : const SfxFilter* pFirstFilter=0;
759 [ # # ]: 0 : for ( size_t i = 0, n = m_rImpl.pList->size(); i < n; ++i )
760 : : {
761 : 0 : const SfxFilter* pFilter = m_rImpl.pList->at( i );
762 : 0 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
763 [ # # # # ]: 0 : if ( (nFlags & nMust) == nMust &&
[ # # ][ # # ]
764 : 0 : !(nFlags & nDont ) && pFilter->GetUIName() == rName )
765 : : {
766 [ # # ]: 0 : if ( pFilter->GetFilterFlags() & SFX_FILTER_PREFERED )
767 : 0 : return pFilter;
768 [ # # ]: 0 : else if ( !pFirstFilter )
769 : 0 : pFirstFilter = pFilter;
770 : : }
771 : : }
772 : 0 : return pFirstFilter;
773 : : }
774 : :
775 : 13362 : const SfxFilter* SfxFilterMatcher::GetFilter4FilterName( const String& rName, SfxFilterFlags nMust, SfxFilterFlags nDont ) const
776 : : {
777 [ + - ]: 13362 : String aName( rName );
778 [ + - ]: 13362 : sal_uInt16 nIndex = aName.SearchAscii(": ");
779 [ - + ]: 13362 : if ( nIndex != STRING_NOTFOUND )
780 : : {
781 : : OSL_FAIL("Old filter name used!");
782 [ # # ][ # # ]: 0 : aName = rName.Copy( nIndex + 2 );
[ # # ]
783 : : }
784 : :
785 [ + + ]: 13362 : if ( bFirstRead )
786 : : {
787 [ + - ]: 5427 : ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
788 : 5427 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > xFilterCFG ;
789 : 5427 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > xTypeCFG ;
790 [ + - ]: 5427 : if( xServiceManager.is() == sal_True )
791 : : {
792 [ + - ][ + - ]: 5427 : xFilterCFG = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), ::com::sun::star::uno::UNO_QUERY );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
793 [ + - ][ + - ]: 5427 : xTypeCFG = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" ) ), ::com::sun::star::uno::UNO_QUERY );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
794 : : }
795 : :
796 [ + - ][ + - ]: 5427 : if( xFilterCFG.is() && xTypeCFG.is() )
[ + - ]
797 : : {
798 [ + + ]: 5427 : if ( !pFilterArr )
799 [ + - ]: 127 : CreateFilterArr();
800 : : else
801 : : {
802 [ + + ]: 14426 : for ( size_t i = 0, n = pFilterArr->size(); i < n; ++i )
803 : : {
804 [ + - ]: 14345 : const SfxFilter* pFilter = pFilterArr->at( i );
805 : 14345 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
806 [ + + ][ + - ]: 14345 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetFilterName().CompareIgnoreCaseToAscii( aName ) == COMPARE_EQUAL )
[ + + ][ + + ]
[ + + ]
807 : 5219 : return pFilter;
808 : : }
809 : : }
810 : :
811 [ + - ][ + - ]: 208 : SfxFilterContainer::ReadSingleFilter_Impl( rName, xTypeCFG, xFilterCFG, sal_False );
812 [ + + ][ + + ]: 5427 : }
[ + + ]
813 : : }
814 : :
815 : 8143 : SfxFilterList_Impl* pList = m_rImpl.pList;
816 [ + - ]: 8143 : if ( !pList )
817 : 8143 : pList = pFilterArr;
818 : :
819 [ + + ]: 449892 : for ( size_t i = 0, n = pList->size(); i < n; ++i )
820 : : {
821 [ + - ]: 445562 : const SfxFilter* pFilter = pList->at( i );
822 : 445562 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
823 [ + + ][ + - ]: 445562 : if ( (nFlags & nMust) == nMust && !(nFlags & nDont ) && pFilter->GetFilterName().CompareIgnoreCaseToAscii( aName ) == COMPARE_EQUAL )
[ + + ][ + + ]
[ + + ]
824 : 3813 : return pFilter;
825 : : }
826 : :
827 [ + - ]: 13362 : return NULL;
828 : : }
829 : :
830 : 0 : IMPL_STATIC_LINK( SfxFilterMatcher, MaybeFileHdl_Impl, String*, pString )
831 : : {
832 : 0 : const SfxFilter* pFilter = pThis->GetFilter4Extension( *pString, SFX_FILTER_IMPORT );
833 [ # # ][ # # ]: 0 : if (pFilter && !pFilter->GetWildcard().Matches( String() ) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
[ # # ]
834 [ # # ][ # # ]: 0 : !pFilter->GetWildcard().Matches(DEFINE_CONST_UNICODE("*.*")) &&
[ # # ][ # # ]
[ # # ]
835 [ # # ][ # # ]: 0 : !pFilter->GetWildcard().Matches(rtl::OUString('*'))
[ # # ][ # # ]
[ # # ]
[ # # # # ]
836 : : )
837 : : {
838 : 0 : return sal_True;
839 : : }
840 : 0 : return sal_False;
841 : : }
842 : :
843 : : //----------------------------------------------------------------
844 : :
845 : 398 : SfxFilterMatcherIter::SfxFilterMatcherIter(
846 : : const SfxFilterMatcher& rMatcher,
847 : : SfxFilterFlags nOrMaskP, SfxFilterFlags nAndMaskP )
848 : : : nOrMask( nOrMaskP ), nAndMask( nAndMaskP ),
849 : 398 : nCurrent(0), m_rMatch(rMatcher.m_rImpl)
850 : : {
851 [ - + ]: 398 : if( nOrMask == 0xffff ) //Due to falty build on s
852 : 0 : nOrMask = 0;
853 [ + - ]: 398 : m_rMatch.InitForIterating();
854 : 398 : }
855 : :
856 : : //----------------------------------------------------------------
857 : :
858 : 7858 : const SfxFilter* SfxFilterMatcherIter::Find_Impl()
859 : : {
860 : 7858 : const SfxFilter* pFilter = 0;
861 [ + + ]: 7858 : while( nCurrent < m_rMatch.pList->size() )
862 : : {
863 : 7625 : pFilter = m_rMatch.pList->at( nCurrent++ );
864 : 7625 : SfxFilterFlags nFlags = pFilter->GetFilterFlags();
865 [ + - ][ + - ]: 7625 : if( ((nFlags & nOrMask) == nOrMask ) && !(nFlags & nAndMask ) )
866 : 7625 : break;
867 : 0 : pFilter = 0;
868 : : }
869 : :
870 : 7858 : return pFilter;
871 : : }
872 : :
873 : 398 : const SfxFilter* SfxFilterMatcherIter::First()
874 : : {
875 : 398 : nCurrent = 0;
876 : 398 : return Find_Impl();
877 : : }
878 : :
879 : : //----------------------------------------------------------------
880 : :
881 : 7460 : const SfxFilter* SfxFilterMatcherIter::Next()
882 : : {
883 : 7460 : return Find_Impl();
884 : : }
885 : :
886 : : /*---------------------------------------------------------------
887 : : helper to build own formated string from given stringlist by
888 : : using given seperator
889 : : ---------------------------------------------------------------*/
890 : 13476 : ::rtl::OUString implc_convertStringlistToString( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& lList ,
891 : : const sal_Unicode& cSeperator,
892 : : const ::rtl::OUString& sPrefix )
893 : : {
894 : 13476 : ::rtl::OUStringBuffer sString ( 1000 ) ;
895 : 13476 : sal_Int32 nCount = lList.getLength();
896 : 13476 : sal_Int32 nItem = 0 ;
897 [ + + ]: 24074 : for( nItem=0; nItem<nCount; ++nItem )
898 : : {
899 [ + + ]: 10598 : if( !sPrefix.isEmpty() )
900 : : {
901 [ + - ]: 6066 : sString.append( sPrefix );
902 : : }
903 [ + - ]: 10598 : sString.append( lList[nItem] );
904 [ + + ]: 10598 : if( nItem+1<nCount )
905 : : {
906 [ + - ]: 3926 : sString.append( cSeperator );
907 : : }
908 : : }
909 [ + - ]: 13476 : return sString.makeStringAndClear();
910 : : }
911 : :
912 : :
913 : 4558 : void SfxFilterContainer::ReadSingleFilter_Impl(
914 : : const ::rtl::OUString& rName,
915 : : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xTypeCFG,
916 : : const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xFilterCFG,
917 : : sal_Bool bUpdate
918 : : )
919 : : {
920 : 4558 : ::rtl::OUString sFilterName( rName );
921 : 4558 : SfxFilterList_Impl& rList = *pFilterArr;
922 [ + - ]: 4558 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > lFilterProperties ;
923 : 4558 : ::com::sun::star::uno::Any aResult;
924 : : try
925 : : {
926 [ + + ][ + - ]: 4558 : aResult = xFilterCFG->getByName( sFilterName );
927 : : }
928 [ + - ]: 40 : catch( ::com::sun::star::container::NoSuchElementException& )
929 : : {
930 : 20 : aResult = ::com::sun::star::uno::Any();
931 : : }
932 : :
933 [ + - ][ + + ]: 4558 : if( aResult >>= lFilterProperties )
934 : : {
935 : : // collect informations to add filter to container
936 : : // (attention: some informations aren't available on filter directly ... you must search for corresponding type too!)
937 : 4538 : sal_Int32 nFlags = 0 ;
938 : 4538 : sal_Int32 nClipboardId = 0 ;
939 : 4538 : sal_Int32 nDocumentIconId = 0 ;
940 : 4538 : sal_Int32 nFormatVersion = 0 ;
941 : 4538 : ::rtl::OUString sMimeType ;
942 : 4538 : ::rtl::OUString sType ;
943 : 4538 : ::rtl::OUString sUIName ;
944 : 4538 : ::rtl::OUString sHumanName ;
945 : 4538 : ::rtl::OUString sDefaultTemplate ;
946 : 4538 : ::rtl::OUString sUserData ;
947 : 4538 : ::rtl::OUString sExtension ;
948 : 4538 : ::rtl::OUString sPattern ;
949 : 4538 : ::rtl::OUString sServiceName ;
950 : :
951 : : // first get directly available properties
952 : 4538 : sal_Int32 nFilterPropertyCount = lFilterProperties.getLength();
953 : 4538 : sal_Int32 nFilterProperty = 0 ;
954 [ + + ]: 62749 : for( nFilterProperty=0; nFilterProperty<nFilterPropertyCount; ++nFilterProperty )
955 : : {
956 [ + - ][ + + ]: 58211 : if ( lFilterProperties[nFilterProperty].Name == "FileFormatVersion" )
957 : : {
958 [ + - ]: 4538 : lFilterProperties[nFilterProperty].Value >>= nFormatVersion;
959 : : }
960 [ + - ][ + + ]: 53673 : else if ( lFilterProperties[nFilterProperty].Name == "TemplateName" )
961 : : {
962 [ + - ]: 4538 : lFilterProperties[nFilterProperty].Value >>= sDefaultTemplate;
963 : : }
964 [ + - ][ + + ]: 49135 : else if ( lFilterProperties[nFilterProperty].Name == "Flags" )
965 : : {
966 [ + - ]: 4538 : lFilterProperties[nFilterProperty].Value >>= nFlags;
967 : : }
968 [ + - ][ + + ]: 44597 : else if ( lFilterProperties[nFilterProperty].Name == "UIName" )
969 : : {
970 [ + - ]: 3617 : lFilterProperties[nFilterProperty].Value >>= sUIName;
971 : : }
972 [ + - ][ + + ]: 40980 : else if ( lFilterProperties[nFilterProperty].Name == "UserData" )
973 : : {
974 [ + - ]: 4538 : ::com::sun::star::uno::Sequence< ::rtl::OUString > lUserData;
975 [ + - ][ + - ]: 4538 : lFilterProperties[nFilterProperty].Value >>= lUserData;
976 [ + - ][ + - ]: 4538 : sUserData = implc_convertStringlistToString( lUserData, ',', ::rtl::OUString() );
[ # # ]
977 : : }
978 [ + - ][ + + ]: 36442 : else if ( lFilterProperties[nFilterProperty].Name == "DocumentService" )
979 : : {
980 [ + - ]: 4538 : lFilterProperties[nFilterProperty].Value >>= sServiceName;
981 : : }
982 [ + - ][ + + ]: 31904 : else if (lFilterProperties[nFilterProperty].Name == "ExportExtension")
983 : : {
984 : : // Extension preferred by the filter. This takes precedence
985 : : // over those that are given in the file format type.
986 [ + - ]: 138 : lFilterProperties[nFilterProperty].Value >>= sExtension;
987 : 138 : sExtension = OUString("*.") + sExtension;
988 : : }
989 [ + - ][ + + ]: 31766 : else if ( lFilterProperties[nFilterProperty].Name == "Type" )
990 : : {
991 [ + - ]: 4538 : lFilterProperties[nFilterProperty].Value >>= sType;
992 : : // Try to get filter .. but look for any exceptions!
993 : : // May be filter was deleted by another thread ...
994 : : try
995 : : {
996 [ + - ][ + - ]: 4538 : aResult = xTypeCFG->getByName( sType );
997 : : }
998 [ # # ]: 0 : catch (const ::com::sun::star::container::NoSuchElementException&)
999 : : {
1000 : 0 : aResult = ::com::sun::star::uno::Any();
1001 : : }
1002 : :
1003 [ + - ]: 4538 : ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > lTypeProperties;
1004 [ + - ][ + - ]: 4538 : if( aResult >>= lTypeProperties )
1005 : : {
1006 : : // get indirect available properties then (types)
1007 : 4538 : sal_Int32 nTypePropertyCount = lTypeProperties.getLength();
1008 : 4538 : sal_Int32 nTypeProperty = 0 ;
1009 [ + + ]: 58994 : for( nTypeProperty=0; nTypeProperty<nTypePropertyCount; ++nTypeProperty )
1010 : : {
1011 [ + - ][ + + ]: 54456 : if ( lTypeProperties[nTypeProperty].Name == "ClipboardFormat" )
1012 : : {
1013 [ + - ]: 4538 : lTypeProperties[nTypeProperty].Value >>= sHumanName;
1014 : : }
1015 [ + - ][ - + ]: 49918 : else if ( lTypeProperties[nTypeProperty].Name == "DocumentIconID" )
1016 : : {
1017 [ # # ]: 0 : lTypeProperties[nTypeProperty].Value >>= nDocumentIconId;
1018 : : }
1019 [ + - ][ + + ]: 49918 : else if ( lTypeProperties[nTypeProperty].Name == "MediaType" )
1020 : : {
1021 [ + - ]: 4538 : lTypeProperties[nTypeProperty].Value >>= sMimeType;
1022 : : }
1023 [ + - ][ + + ]: 45380 : else if ( lTypeProperties[nTypeProperty].Name == "Extensions" )
1024 : : {
1025 [ + + ]: 4538 : if (sExtension.isEmpty())
1026 : : {
1027 [ + - ]: 4400 : ::com::sun::star::uno::Sequence< ::rtl::OUString > lExtensions;
1028 [ + - ][ + - ]: 4400 : lTypeProperties[nTypeProperty].Value >>= lExtensions;
1029 [ + - ][ + - ]: 4400 : sExtension = implc_convertStringlistToString( lExtensions, ';', DEFINE_CONST_UNICODE("*.") );
[ + - ][ + - ]
[ + - ]
1030 : : }
1031 : : }
1032 [ + - ][ + + ]: 40842 : else if ( lTypeProperties[nTypeProperty].Name == "URLPattern" )
1033 : : {
1034 [ + - ]: 4538 : ::com::sun::star::uno::Sequence< ::rtl::OUString > lPattern;
1035 [ + - ][ + - ]: 4538 : lTypeProperties[nTypeProperty].Value >>= lPattern;
1036 [ + - ][ + - ]: 4538 : sPattern = implc_convertStringlistToString( lPattern, ';', ::rtl::OUString() );
1037 : : }
1038 : : }
1039 [ + - ]: 4538 : }
1040 : : }
1041 : : }
1042 : :
1043 [ - + ]: 4538 : if ( sServiceName.isEmpty() )
1044 [ - + ]: 4578 : return;
1045 : :
1046 : : // old formats are found ... using HumanPresentableName!
1047 [ + + ]: 4538 : if( !sHumanName.isEmpty() )
1048 : : {
1049 [ + - ][ + - ]: 1564 : nClipboardId = SotExchange::RegisterFormatName( sHumanName );
[ + - ]
1050 : :
1051 : : // For external filters ignore clipboard IDs
1052 [ + + ]: 1564 : if((nFlags & SFX_FILTER_STARONEFILTER) == SFX_FILTER_STARONEFILTER)
1053 : : {
1054 : 410 : nClipboardId = 0;
1055 : : }
1056 : : }
1057 : : // register SfxFilter
1058 : : // first erase module name from old filter names!
1059 : : // e.g: "scalc: DIF" => "DIF"
1060 [ + - ][ + - ]: 4538 : sal_Int32 nStartRealName = sFilterName.indexOf( DEFINE_CONST_UNICODE(": "), 0 );
[ + - ]
1061 [ - + ]: 4538 : if( nStartRealName != -1 )
1062 : : {
1063 : : OSL_FAIL("Old format, not supported!");
1064 : 0 : sFilterName = sFilterName.copy( nStartRealName+2 );
1065 : : }
1066 : :
1067 [ + + ][ + - ]: 4538 : SfxFilter* pFilter = bUpdate ? (SfxFilter*) SfxFilter::GetFilterByName( sFilterName ) : 0;
[ + - ][ + + ]
[ + - ][ # # ]
1068 : 4538 : sal_Bool bNew = sal_False;
1069 [ + + ]: 4538 : if (!pFilter)
1070 : : {
1071 : 4487 : bNew = sal_True;
1072 : : pFilter = new SfxFilter( sFilterName ,
1073 : : sExtension ,
1074 : : nFlags ,
1075 : : nClipboardId ,
1076 : : sType ,
1077 : : (sal_uInt16)nDocumentIconId ,
1078 : : sMimeType ,
1079 : : sUserData ,
1080 [ + - ][ + - ]: 4487 : sServiceName );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
1081 : : }
1082 : : else
1083 : : {
1084 [ + - ]: 51 : pFilter->aFilterName = sFilterName;
1085 [ + - ][ + - ]: 51 : pFilter->aWildCard = WildCard(sExtension, ';');
[ + - ]
1086 : 51 : pFilter->nFormatType = nFlags;
1087 : 51 : pFilter->lFormat = nClipboardId;
1088 [ + - ]: 51 : pFilter->aTypeName = sType;
1089 : 51 : pFilter->nDocIcon = (sal_uInt16)nDocumentIconId;
1090 : 51 : pFilter->aMimeType = sMimeType;
1091 : 51 : pFilter->aUserData = sUserData;
1092 : 51 : pFilter->aServiceName = sServiceName;
1093 : : }
1094 : :
1095 : : // Don't forget to set right UIName!
1096 : : // Otherwise internal name is used as fallback ...
1097 [ + - ][ + - ]: 4538 : pFilter->SetUIName( sUIName );
[ + - ]
1098 [ + - ][ + - ]: 4538 : pFilter->SetDefaultTemplate( sDefaultTemplate );
[ + - ]
1099 [ + + ]: 4538 : if( nFormatVersion )
1100 : : {
1101 : 1062 : pFilter->SetVersion( nFormatVersion );
1102 : : }
1103 [ + - ][ + - ]: 4538 : pFilter->SetURLPattern(sPattern);
[ + - ]
1104 : :
1105 [ + + ]: 4538 : if (bNew)
1106 [ + - ][ - + ]: 4558 : rList.push_back( pFilter );
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ - + ]
[ - + ][ + - ]
1107 [ - + ][ + - ]: 4558 : }
[ - + ][ + - ]
1108 : : }
1109 : :
1110 : 23 : void SfxFilterContainer::ReadFilters_Impl( sal_Bool bUpdate )
1111 : : {
1112 : : RTL_LOGFILE_CONTEXT( aMeasure, "sfx2 (as96863) ::SfxFilterContainer::ReadFilters" );
1113 [ - + ]: 23 : if ( !pFilterArr )
1114 : 0 : CreateFilterArr();
1115 : :
1116 : 23 : bFirstRead = sal_False;
1117 : 23 : SfxFilterList_Impl& rList = *pFilterArr;
1118 : :
1119 : : try
1120 : : {
1121 : : // get the FilterFactory service to access the registered filters ... and types!
1122 [ + - ]: 23 : ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory();
1123 : 23 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > xFilterCFG ;
1124 : 23 : ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > xTypeCFG ;
1125 [ + - ]: 23 : if( xServiceManager.is() == sal_True )
1126 : : {
1127 [ + - ][ + - ]: 23 : xFilterCFG = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.FilterFactory" ) ), ::com::sun::star::uno::UNO_QUERY );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
1128 [ + - ][ + - ]: 23 : xTypeCFG = ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >( xServiceManager->createInstance( DEFINE_CONST_UNICODE( "com.sun.star.document.TypeDetection" ) ), ::com::sun::star::uno::UNO_QUERY );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
1129 : : }
1130 : :
1131 [ + - ]: 46 : if(
[ + - + - ]
1132 : 23 : ( xFilterCFG.is() == sal_True ) &&
1133 : 23 : ( xTypeCFG.is() == sal_True )
1134 : : )
1135 : : {
1136 : : // select right query to get right set of filters for search modul
1137 [ + - ][ + - ]: 23 : ::com::sun::star::uno::Sequence< ::rtl::OUString > lFilterNames = xFilterCFG->getElementNames();
1138 [ + - ]: 23 : if ( lFilterNames.getLength() )
1139 : : {
1140 : : // If list of filters already exist ...
1141 : : // ReadExternalFilters must work in update mode.
1142 : : // Best way seams to mark all filters NOT_INSTALLED
1143 : : // and change it back for all valid filters afterwards.
1144 [ + - ]: 23 : if( !rList.empty() )
1145 : : {
1146 : 23 : bUpdate = sal_True;
1147 : : SfxFilter* pFilter;
1148 [ + + ]: 76 : for ( size_t i = 0, n = rList.size(); i < n; ++i )
1149 : : {
1150 : 53 : pFilter = NULL;
1151 [ + - ]: 53 : pFilter = rList[ i ];
1152 : 53 : pFilter->nFormatType |= SFX_FILTER_NOTINSTALLED;
1153 : : }
1154 : : }
1155 : :
1156 : : // get all properties of filters ... put it into the filter container
1157 : 23 : sal_Int32 nFilterCount = lFilterNames.getLength();
1158 : 23 : sal_Int32 nFilter=0;
1159 [ + + ]: 4373 : for( nFilter=0; nFilter<nFilterCount; ++nFilter )
1160 : : {
1161 : : // Try to get filter .. but look for any exceptions!
1162 : : // May be filter was deleted by another thread ...
1163 [ + - ]: 4350 : ::rtl::OUString sFilterName = lFilterNames[nFilter];
1164 [ + - ]: 4350 : ReadSingleFilter_Impl( sFilterName, xTypeCFG, xFilterCFG, bUpdate );
1165 : 4350 : }
1166 [ + - ]: 23 : }
1167 [ # # ]: 23 : }
1168 : : }
1169 : 0 : catch(const ::com::sun::star::uno::Exception&)
1170 : : {
1171 : : DBG_ASSERT( sal_False, "SfxFilterContainer::ReadFilter()\nException detected. Possible not all filters could be cached.\n" );
1172 : : }
1173 : :
1174 [ + - ]: 23 : if ( bUpdate )
1175 : : {
1176 : : // global filter arry was modified, factory specific ones might need an
1177 : : // update too
1178 : : std::for_each(aImplArr.begin(), aImplArr.end(),
1179 : 23 : std::mem_fun_ref(&SfxFilterMatcher_Impl::Update));
1180 : : }
1181 [ + - ][ + - ]: 758 : }
1182 : :
1183 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|