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