1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26
27 #include "filterfactory.hxx"
28 #include "macros.hxx"
29 #include "constant.hxx"
30 #include "versions.hxx"
31
32 //_______________________________________________
33 // includes
34 #include <com/sun/star/lang/XInitialization.hpp>
35 #include <comphelper/enumhelper.hxx>
36 #include <comphelper/configurationhelper.hxx>
37 #include <rtl/ustrbuf.hxx>
38
39 //_______________________________________________
40 // namespace
41
42 namespace filter{
43 namespace config{
44
45 namespace css = ::com::sun::star;
46
47 //_______________________________________________
48 // definitions
49
50 /** @short can be used to query for filters related to its application module.
51 */
52 #define BASE_QUERY_ALL "_query_all"
53 #define BASE_QUERY_WRITER "_query_Writer"
54 #define BASE_QUERY_WEB "_query_web"
55 #define BASE_QUERY_GLOBAL "_query_global"
56 #define BASE_QUERY_CHART "_query_chart"
57 #define BASE_QUERY_CALC "_query_calc"
58 #define BASE_QUERY_IMPRESS "_query_impress"
59 #define BASE_QUERY_DRAW "_query_draw"
60 #define BASE_QUERY_MATH "_query_math"
61
62 //_______________________________________________
63
64 /** @short define all possible parts of a filter query.
65
66 @descr syntax: "<query>[:<param>[=<value>]]"
67 e.g.: "_query_writer:default_first:use_order:sort_prop=uiname"
68
69 argument description default
70 -----------------------------------------------------------------------------------------------
71 iflags=<mask> include filters by given mask 0
72 eflags=<mask> exclude filters by given mask 0
73 sort_prop=<[name,uiname]> sort by internal name or uiname name
74 descending sort descending false
75 use_order use order flag of filters for sorting false
76 default_first set default filter on top of return list false
77 case_sensitive compare "sort_prop" case sensitive false
78 */
79 #define SEPERATOR_QUERYPARAM ((sal_Unicode)':')
80 #define SEPERATOR_QUERYPARAMVALUE ((sal_Unicode)'=')
81
82 #define QUERYPARAM_IFLAGS ::rtl::OUString::createFromAscii("iflags")
83 #define QUERYPARAM_EFLAGS ::rtl::OUString::createFromAscii("eflags")
84 #define QUERYPARAM_SORT_PROP ::rtl::OUString::createFromAscii("sort_prop")
85
86 #define QUERYPARAM_DESCENDING ::rtl::OUString::createFromAscii("descending")
87 #define QUERYPARAM_USE_ORDER ::rtl::OUString::createFromAscii("use_order")
88 #define QUERYPARAM_DEFAULT_FIRST ::rtl::OUString::createFromAscii("default_first")
89 #define QUERYPARAM_CASE_SENSITIVE ::rtl::OUString::createFromAscii("case_sensitive")
90
91 #define QUERYPARAMVALUE_SORT_PROP_NAME ::rtl::OUString::createFromAscii("name")
92 #define QUERYPARAMVALUE_SORT_PROP_UINAME ::rtl::OUString::createFromAscii("uiname")
93
94 /*-----------------------------------------------
95 09.07.2003 07:43
96 -----------------------------------------------*/
FilterFactory(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)97 FilterFactory::FilterFactory(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
98 {
99 BaseContainer::init(xSMGR ,
100 FilterFactory::impl_getImplementationName() ,
101 FilterFactory::impl_getSupportedServiceNames(),
102 FilterCache::E_FILTER );
103 }
104
105 /*-----------------------------------------------
106 09.07.2003 07:43
107 -----------------------------------------------*/
~FilterFactory()108 FilterFactory::~FilterFactory()
109 {
110 }
111
112 /*-----------------------------------------------
113 16.07.2003 13:43
114 -----------------------------------------------*/
createInstance(const::rtl::OUString & sFilter)115 css::uno::Reference< css::uno::XInterface > SAL_CALL FilterFactory::createInstance(const ::rtl::OUString& sFilter)
116 throw(css::uno::Exception ,
117 css::uno::RuntimeException)
118 {
119 return createInstanceWithArguments(sFilter, css::uno::Sequence< css::uno::Any >());
120 }
121
122 /*-----------------------------------------------
123 17.07.2003 08:56
124 -----------------------------------------------*/
createInstanceWithArguments(const::rtl::OUString & sFilter,const css::uno::Sequence<css::uno::Any> & lArguments)125 css::uno::Reference< css::uno::XInterface > SAL_CALL FilterFactory::createInstanceWithArguments(const ::rtl::OUString& sFilter ,
126 const css::uno::Sequence< css::uno::Any >& lArguments)
127 throw(css::uno::Exception ,
128 css::uno::RuntimeException)
129 {
130 // SAFE ->
131 ::osl::ResettableMutexGuard aLock(m_aLock);
132
133 ::rtl::OUString sRealFilter = sFilter;
134
135 #ifdef _FILTER_CONFIG_MIGRATION_Q_
136
137 /* -> TODO - HACK
138 check if the given filter name really exists ...
139 Because our old implementation worked with an internal
140 type name instead of a filter name. For a small migration time
141 we must simulate this old feature :-( */
142
143 if (!m_rCache->hasItem(FilterCache::E_FILTER, sFilter) && m_rCache->hasItem(FilterCache::E_TYPE, sFilter))
144 {
145 OSL_ENSURE(sal_False, "Who use this deprecated functionality?");
146 _FILTER_CONFIG_LOG_("FilterFactory::createInstanceWithArguments() ... simulate old type search functionality!\n");
147
148 css::uno::Sequence< css::beans::NamedValue > lQuery(1);
149 lQuery[0].Name = PROPNAME_TYPE;
150 lQuery[0].Value <<= sFilter;
151
152 css::uno::Reference< css::container::XEnumeration > xSet = createSubSetEnumerationByProperties(lQuery);
153 while(xSet->hasMoreElements())
154 {
155 ::comphelper::SequenceAsHashMap lHandlerProps(xSet->nextElement());
156 if (!(lHandlerProps[PROPNAME_NAME] >>= sRealFilter))
157 continue;
158 }
159
160 // prevent outside code against NoSuchElementException!
161 // But don't implement such defensive strategy for our new create handling :-)
162 if (!m_rCache->hasItem(FilterCache::E_FILTER, sRealFilter))
163 return css::uno::Reference< css::uno::XInterface>();
164 }
165
166 /* <- HACK */
167
168 #endif // _FILTER_CONFIG_MIGRATION_Q_
169
170 // search filter on cache
171 CacheItem aFilter = m_rCache->getItem(FilterCache::E_FILTER, sRealFilter);
172 ::rtl::OUString sFilterService;
173 aFilter[PROPNAME_FILTERSERVICE] >>= sFilterService;
174
175 // create service instance
176 css::uno::Reference< css::uno::XInterface > xFilter;
177 if (sFilterService.getLength())
178 xFilter = m_xSMGR->createInstance(sFilterService);
179
180 // initialize filter
181 css::uno::Reference< css::lang::XInitialization > xInit(xFilter, css::uno::UNO_QUERY);
182 if (xInit.is())
183 {
184 // format: lInitData[0] = seq<PropertyValue>, which contains all configuration properties of this filter
185 // lInitData[1] = lArguments[0]
186 // ...
187 // lInitData[n] = lArguments[n-1]
188 css::uno::Sequence< css::beans::PropertyValue > lConfig;
189 aFilter >> lConfig;
190
191 ::comphelper::SequenceAsVector< css::uno::Any > stlArguments(lArguments);
192 stlArguments.insert(stlArguments.begin(), css::uno::makeAny(lConfig));
193
194 css::uno::Sequence< css::uno::Any > lInitData;
195 stlArguments >> lInitData;
196
197 xInit->initialize(lInitData);
198 }
199
200 return xFilter;
201 // <- SAFE
202 }
203
204 /*-----------------------------------------------
205 18.02.2004 14:21
206 -----------------------------------------------*/
getAvailableServiceNames()207 css::uno::Sequence< ::rtl::OUString > SAL_CALL FilterFactory::getAvailableServiceNames()
208 throw(css::uno::RuntimeException)
209 {
210 /* Attention: Instead of getElementNames() this method have to return only filter names,
211 which can be created as UNO Services really. That's why we search for filters,
212 which dont have a valid value for the property "FilterService".
213 Of course we can't check for corrupted service names here. We can check
214 for empty strings only ...
215 */
216 CacheItem lIProps;
217 CacheItem lEProps;
218 lEProps[PROPNAME_FILTERSERVICE] <<= ::rtl::OUString();
219
220 OUStringList lUNOFilters;
221 try
222 {
223 lUNOFilters = m_rCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps, lEProps);
224 }
225 catch(const css::uno::RuntimeException&)
226 { throw; }
227 catch(const css::uno::Exception&)
228 { lUNOFilters.clear(); }
229
230 return lUNOFilters.getAsConstList();
231 }
232
233 /*-----------------------------------------------
234 11.03.2004 08:37
235 -----------------------------------------------*/
createSubSetEnumerationByQuery(const::rtl::OUString & sQuery)236 css::uno::Reference< css::container::XEnumeration > SAL_CALL FilterFactory::createSubSetEnumerationByQuery(const ::rtl::OUString& sQuery)
237 throw (css::uno::RuntimeException)
238 {
239 // reject old deprecated queries ...
240 if (sQuery.matchAsciiL("_filterquery_",13,0))
241 throw css::uno::RuntimeException(
242 _FILTER_CONFIG_FROM_ASCII_("Use of deprecated and now unsupported query!"),
243 static_cast< css::container::XContainerQuery* >(this));
244
245 // convert "_query_xxx:..." to "getByDocService=xxx:..."
246 ::rtl::OUString sNewQuery(sQuery);
247 sal_Int32 pos = sNewQuery.indexOf(::rtl::OUString::createFromAscii("_query_"),0);
248 if (pos != -1)
249 {
250 OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use new query format: 'matchByDocumentService=...'");
251 ::rtl::OUStringBuffer sPatchedQuery(256);
252 sPatchedQuery.appendAscii("matchByDocumentService=");
253 sPatchedQuery.append (sNewQuery.copy(7) );
254 sNewQuery = sPatchedQuery.makeStringAndClear();
255 }
256
257 // analyze query and split it into its tokens
258 QueryTokenizer lTokens(sNewQuery);
259 QueryTokenizer::const_iterator pIt;
260 OUStringList lEnumSet;
261
262 // start query
263 // (see attention comment below!)
264 if (lTokens.valid())
265 {
266 // SAFE -> ----------------------
267 ::osl::ResettableMutexGuard aLock(m_aLock);
268 // May be not all filters was loaded ...
269 // But we need it now!
270 impl_loadOnDemand();
271 aLock.clear();
272 // <- SAFE ----------------------
273
274 if (lTokens.find(QUERY_IDENTIFIER_GETPREFERREDFILTERFORTYPE) != lTokens.end())
275 OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use prop search at the TypeDetection container!");
276 // lEnumSet = impl_queryGetPreferredFilterForType(lTokens);
277 else
278 if (lTokens.find(QUERY_IDENTIFIER_MATCHBYDOCUMENTSERVICE) != lTokens.end())
279 lEnumSet = impl_queryMatchByDocumentService(lTokens);
280 else
281 if (lTokens.find(QUERY_IDENTIFIER_GET_SORTED_FILTERLIST) != lTokens.end())
282 lEnumSet = impl_getSortedFilterList(lTokens);
283 }
284
285 // pack list of item names as an enum list
286 // Attention: Do not return empty reference for empty list!
287 // The outside check "hasMoreElements()" should be enough, to detect this state :-)
288 // size_t c = lEnumSet.size();
289 css::uno::Sequence< ::rtl::OUString > lSet = lEnumSet.getAsConstList();
290 ::comphelper::OEnumerationByName* pEnum = new ::comphelper::OEnumerationByName(this, lSet);
291 return css::uno::Reference< css::container::XEnumeration >(static_cast< css::container::XEnumeration* >(pEnum), css::uno::UNO_QUERY);
292 }
293 /*
294 if (lEnumSet.empty())
295 {
296 //-------------------------------------------
297 // 1) getDefaultFilterForType=<internal_typename>
298
299 pIt = lTokens.find(::rtl::OUString::createFromAscii("getDefaultFilterForType"));
300 if (pIt != lTokens.end())
301 {
302 // SAFE ->
303 ::osl::ResettableMutexGuard aLock(m_aLock);
304
305 // might not all types was loaded till now!
306 impl_loadOnDemand();
307
308 ::rtl::OUString sType = pIt->second;
309 FilterCache* pCache = impl_getWorkingCache();
310 if (pCache->hasItem(FilterCache::E_TYPE, sType))
311 {
312 CacheItem aType = pCache->getItem(FilterCache::E_TYPE, sType);
313 ::rtl::OUString sPreferredFilter;
314 aType[PROPNAME_PREFERREDFILTER] >>= sPreferredFilter;
315
316 if (
317 (sPreferredFilter.getLength() ) &&
318 (pCache->hasItem(FilterCache::E_FILTER, sPreferredFilter))
319 )
320 {
321 lEnumSet.push_back(sPreferredFilter);
322 }
323 }
324
325 aLock.clear();
326 // <- SAFE
327 }
328 }
329 */
330
331 /*-----------------------------------------------
332 11.03.2004 08:33
333 -----------------------------------------------*/
impl_queryMatchByDocumentService(const QueryTokenizer & lTokens) const334 OUStringList FilterFactory::impl_queryMatchByDocumentService(const QueryTokenizer& lTokens) const
335 {
336 // analyze query
337 QueryTokenizer::const_iterator pIt;
338
339 ::rtl::OUString sDocumentService;
340 sal_Int32 nIFlags = 0;
341 sal_Int32 nEFlags = 0;
342
343 pIt = lTokens.find(QUERY_IDENTIFIER_MATCHBYDOCUMENTSERVICE);
344 if (pIt != lTokens.end())
345 sDocumentService = pIt->second;
346
347 #define COMP_HACK
348 #ifdef COMP_HACK
349 if (sDocumentService.equalsAscii("writer"))
350 {
351 OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
352 sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.text.TextDocument");
353 }
354 else
355 if (sDocumentService.equalsAscii("web"))
356 {
357 OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
358 sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.text.WebDocument");
359 }
360 else
361 if (sDocumentService.equalsAscii("global"))
362 {
363 OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
364 sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.text.GlobalDocument");
365 }
366 else
367 if (sDocumentService.equalsAscii("calc"))
368 {
369 OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
370 sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.sheet.SpreadsheetDocument");
371 }
372 else
373 if (sDocumentService.equalsAscii("draw"))
374 {
375 OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
376 sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.drawing.DrawingDocument");
377 }
378 else
379 if (sDocumentService.equalsAscii("impress"))
380 {
381 OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
382 sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.presentation.PresentationDocument");
383 }
384 else
385 if (sDocumentService.equalsAscii("math"))
386 {
387 OSL_ENSURE(sal_False, "DEPRECATED!\nPlease use right document service for filter query!");
388 sDocumentService = ::rtl::OUString::createFromAscii("com.sun.star.formula.FormulaProperties");
389 }
390 #endif
391
392 pIt = lTokens.find(QUERY_PARAM_IFLAGS);
393 if (pIt != lTokens.end())
394 nIFlags = ::rtl::OUString(pIt->second).toInt32();
395
396 pIt = lTokens.find(QUERY_PARAM_EFLAGS);
397 if (pIt != lTokens.end())
398 nEFlags = ::rtl::OUString(pIt->second).toInt32();
399
400 // SAFE -> ----------------------
401 ::osl::ResettableMutexGuard aLock(m_aLock);
402
403 // search suitable filters
404 FilterCache* pCache = impl_getWorkingCache();
405 OUStringList lFilterNames = pCache->getItemNames(FilterCache::E_FILTER);
406 OUStringList lResult ;
407
408 for (OUStringList::const_iterator pName = lFilterNames.begin();
409 pName != lFilterNames.end() ;
410 ++pName )
411 {
412 try
413 {
414 const ::rtl::OUString& sName = *pName;
415 const CacheItem aFilter = pCache->getItem(FilterCache::E_FILTER, sName);
416 CacheItem::const_iterator pProp ;
417
418 // "matchByDocumentService=" => any filter will be addressed here
419 // "matchByDocumentService=all" => any filter will be addressed here
420 // "matchByDocumentService=com.sun.star..." => only filter matching this document service will be addressed
421 ::rtl::OUString sCheckValue = aFilter.getUnpackedValueOrDefault(PROPNAME_DOCUMENTSERVICE, ::rtl::OUString());
422 if (
423 ( sDocumentService.getLength() ) &&
424 (!sDocumentService.equals(QUERY_CONSTVALUE_ALL)) &&
425 (!sCheckValue.equals(sDocumentService) )
426 )
427 {
428 continue; // ignore filter -> try next one!
429 }
430
431 // "iflags=" => not allowed
432 // "iflags=-1" => not allowed
433 // "iflags=0" => not useful
434 // "iflags=283648" => only filter, which has set these flag field will be addressed
435 sal_Int32 nCheckValue = aFilter.getUnpackedValueOrDefault(PROPNAME_FLAGS, (sal_Int32)0);
436 if (
437 (nIFlags > 0 ) &&
438 ((nCheckValue & nIFlags) != nIFlags)
439 )
440 {
441 continue; // ignore filter -> try next one!
442 }
443
444 // "eflags=" => not allowed
445 // "eflags=-1" => not allowed
446 // "eflags=0" => not useful
447 // "eflags=283648" => only filter, which has not set these flag field will be addressed
448 if (
449 (nEFlags > 0 ) &&
450 ((nCheckValue & nEFlags) == nEFlags)
451 )
452 {
453 continue; // ignore filter -> try next one!
454 }
455
456 // OK - this filter passed all checks.
457 // It match the query ...
458 lResult.push_back(sName);
459 }
460 catch(const css::uno::RuntimeException& exRun)
461 { throw exRun; }
462 catch(const css::uno::Exception&)
463 { continue; }
464 }
465
466 aLock.clear();
467 // <- SAFE ----------------------
468
469 return lResult;
470 }
471
472 /*-----------------------------------------------
473 21.01.2005 13:39
474 -----------------------------------------------*/
475 class stlcomp_removeIfMatchFlags
476 {
477 private:
478 FilterCache* m_pCache ;
479 sal_Int32 m_nFlags ;
480 sal_Bool m_bIFlags;
481
482 public:
stlcomp_removeIfMatchFlags(FilterCache * pCache,sal_Int32 nFlags,sal_Bool bIFlags)483 stlcomp_removeIfMatchFlags(FilterCache* pCache ,
484 sal_Int32 nFlags ,
485 sal_Bool bIFlags)
486 : m_pCache (pCache )
487 , m_nFlags (nFlags )
488 , m_bIFlags(bIFlags)
489 {}
490
operator ()(const::rtl::OUString & sFilter) const491 bool operator() (const ::rtl::OUString& sFilter) const
492 {
493 try
494 {
495 const CacheItem aFilter = m_pCache->getItem(FilterCache::E_FILTER, sFilter);
496 sal_Int32 nFlags = aFilter.getUnpackedValueOrDefault(PROPNAME_FLAGS, ((sal_Int32)0));
497
498 bool bMatch = false;
499 if (m_bIFlags)
500 // IFlags are interpeted as ALL_FLAGS_MUST_MATCH !
501 bMatch = ((nFlags & m_nFlags) == m_nFlags);
502 else
503 // EFlags are interpreted as ATE_LEAST_ONE_FLAG_MUST_MATCH !
504 bMatch = !(nFlags & m_nFlags);
505 // We are asked for bRemove ! And bMatch = !bRemove => so bRemove = !bMatch .-)
506 return !bMatch;
507 }
508 catch(css::container::NoSuchElementException)
509 {
510 return true;
511 }
512 }
513 };
514
515 /*-----------------------------------------------
516 21.01.2005 13:39
517 -----------------------------------------------*/
impl_getSortedFilterList(const QueryTokenizer & lTokens) const518 OUStringList FilterFactory::impl_getSortedFilterList(const QueryTokenizer& lTokens) const
519 {
520 // analyze the given query parameter
521 QueryTokenizer::const_iterator pIt1;
522
523 ::rtl::OUString sModule;
524 sal_Int32 nIFlags = -1;
525 sal_Int32 nEFlags = -1;
526
527 pIt1 = lTokens.find(QUERY_PARAM_MODULE);
528 if (pIt1 != lTokens.end())
529 sModule = pIt1->second;
530 pIt1 = lTokens.find(QUERY_PARAM_IFLAGS);
531 if (pIt1 != lTokens.end())
532 nIFlags = ::rtl::OUString(pIt1->second).toInt32();
533 pIt1 = lTokens.find(QUERY_PARAM_EFLAGS);
534 if (pIt1 != lTokens.end())
535 nEFlags = ::rtl::OUString(pIt1->second).toInt32();
536
537 // simple search for filters of one specific module.
538 OUStringList lFilterList;
539 if (sModule.getLength())
540 lFilterList = impl_getSortedFilterListForModule(sModule, nIFlags, nEFlags);
541 else
542 {
543 // more complex search for all filters
544 // We check first, which office modules are installed ...
545 OUStringList lModules = impl_getListOfInstalledModules();
546 OUStringList::const_iterator pIt2;
547 for ( pIt2 = lModules.begin();
548 pIt2 != lModules.end() ;
549 ++pIt2 )
550 {
551 sModule = *pIt2;
552 OUStringList lFilters4Module = impl_getSortedFilterListForModule(sModule, nIFlags, nEFlags);
553 OUStringList::const_iterator pIt3;
554 for ( pIt3 = lFilters4Module.begin();
555 pIt3 != lFilters4Module.end() ;
556 ++pIt3 )
557 {
558 const ::rtl::OUString& sFilter = *pIt3;
559 lFilterList.push_back(sFilter);
560 }
561 }
562 }
563
564 return lFilterList;
565 }
566
567 /*-----------------------------------------------
568 21.01.2005 10:19
569 -----------------------------------------------*/
impl_getListOfInstalledModules() const570 OUStringList FilterFactory::impl_getListOfInstalledModules() const
571 {
572 // SAFE -> ----------------------
573 ::osl::ResettableMutexGuard aLock(m_aLock);
574 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
575 aLock.clear();
576 // <- SAFE ----------------------
577
578 try
579 {
580 css::uno::Reference< css::container::XNameAccess > xModuleConfig(
581 ::comphelper::ConfigurationHelper::openConfig(xSMGR,
582 CFGPACKAGE_OOO_MODULES,
583 ::comphelper::ConfigurationHelper::E_READONLY),
584 css::uno::UNO_QUERY_THROW);
585 OUStringList lModules(xModuleConfig->getElementNames());
586 return lModules;
587 }
588 catch(const css::uno::RuntimeException& exRun)
589 { throw exRun; }
590 catch(const css::uno::Exception&)
591 {}
592
593 return OUStringList();
594 }
595
596 /*-----------------------------------------------
597 21.01.2005 10:19
598 -----------------------------------------------*/
impl_getSortedFilterListForModule(const::rtl::OUString & sModule,sal_Int32 nIFlags,sal_Int32 nEFlags) const599 OUStringList FilterFactory::impl_getSortedFilterListForModule(const ::rtl::OUString& sModule,
600 sal_Int32 nIFlags,
601 sal_Int32 nEFlags) const
602 {
603 OUStringList lSortedFilters = impl_readSortedFilterListFromConfig(sModule);
604
605 // get all filters for the requested module
606 CacheItem lIProps;
607 lIProps[PROPNAME_DOCUMENTSERVICE] <<= sModule;
608
609 // SAFE -> ----------------------
610 ::osl::ResettableMutexGuard aLock(m_aLock);
611 FilterCache* pCache = impl_getWorkingCache();
612 OUStringList lOtherFilters = pCache->getMatchingItemsByProps(FilterCache::E_FILTER, lIProps);
613 aLock.clear();
614 // <- SAFE ----------------------
615
616 // bring "other" filters in an alphabeticly order
617 // It's needed below.
618 ::std::sort(lOtherFilters.begin(), lOtherFilters.end());
619
620 // merge both lists together
621 OUStringList lMergedFilters = lSortedFilters;
622 OUStringList::iterator pIt2;
623 OUStringList::iterator pIt3;
624 for ( pIt2 = lOtherFilters.begin();
625 pIt2 != lOtherFilters.end() ;
626 ++pIt2 )
627 {
628 const ::rtl::OUString& rFilter = *pIt2;
629 pIt3 = ::std::find(lSortedFilters.begin(), lSortedFilters.end(), rFilter);
630 if (pIt3 == lSortedFilters.end())
631 lMergedFilters.push_back(rFilter);
632 }
633
634 // remove all filters from this merged list, which does not fit the flag specification
635 if (nIFlags != -1)
636 {
637 pIt2 = ::std::remove_if(lMergedFilters.begin(), lMergedFilters.end(), stlcomp_removeIfMatchFlags(pCache, nIFlags, sal_True));
638 lMergedFilters.erase(pIt2, lMergedFilters.end());
639 }
640 if (nEFlags != -1)
641 {
642 pIt2 = ::std::remove_if(lMergedFilters.begin(), lMergedFilters.end(), stlcomp_removeIfMatchFlags(pCache, nEFlags, sal_False));
643 lMergedFilters.erase(pIt2, lMergedFilters.end());
644 }
645
646 // sort the default filter to the front of this list
647 // TODO
648
649 return lMergedFilters;
650 }
651
652 /*-----------------------------------------------
653 21.01.2005 10:19
654 -----------------------------------------------*/
impl_readSortedFilterListFromConfig(const::rtl::OUString & sModule) const655 OUStringList FilterFactory::impl_readSortedFilterListFromConfig(const ::rtl::OUString& sModule) const
656 {
657 // SAFE -> ----------------------
658 ::osl::ResettableMutexGuard aLock(m_aLock);
659 css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
660 aLock.clear();
661 // <- SAFE ----------------------
662
663 try
664 {
665 css::uno::Reference< css::container::XNameAccess > xUISortConfig(
666 ::comphelper::ConfigurationHelper::openConfig(xSMGR,
667 CFGPACKAGE_TD_UISORT,
668 ::comphelper::ConfigurationHelper::E_READONLY),
669 css::uno::UNO_QUERY_THROW);
670
671 // dont ccheck the module name here. If it does not exists, an exception is thrown and catched below.
672 // We return an empty list as result then.
673 css::uno::Reference< css::container::XNameAccess > xModule;
674 xUISortConfig->getByName(sModule) >>= xModule;
675 if (xModule.is()) // only to be on the safe side of life if the exception was not thrown .-)
676 {
677 // Note: conversion of the returned Any to OUStringList throws
678 // an IllegalArgumentException if the type does not match ...
679 // but it resets the OUStringList to a length of 0 if the Any is empty!
680 OUStringList lSortedFilters(xModule->getByName(PROPNAME_SORTEDFILTERLIST));
681 return lSortedFilters;
682 }
683 }
684 catch(const css::uno::RuntimeException& exRun)
685 { throw exRun; }
686 catch(const css::uno::Exception&)
687 {}
688
689 return OUStringList();
690 }
691
692 /*-----------------------------------------------
693 09.07.2003 07:43
694 -----------------------------------------------*/
impl_getImplementationName()695 ::rtl::OUString FilterFactory::impl_getImplementationName()
696 {
697 return ::rtl::OUString::createFromAscii("com.sun.star.comp.filter.config.FilterFactory");
698 }
699
700 /*-----------------------------------------------
701 09.07.2003 07:43
702 -----------------------------------------------*/
impl_getSupportedServiceNames()703 css::uno::Sequence< ::rtl::OUString > FilterFactory::impl_getSupportedServiceNames()
704 {
705 css::uno::Sequence< ::rtl::OUString > lServiceNames(1);
706 lServiceNames[0] = ::rtl::OUString::createFromAscii("com.sun.star.document.FilterFactory");
707 return lServiceNames;
708 }
709
710 /*-----------------------------------------------
711 09.07.2003 07:43
712 -----------------------------------------------*/
impl_createInstance(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)713 css::uno::Reference< css::uno::XInterface > SAL_CALL FilterFactory::impl_createInstance(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
714 {
715 FilterFactory* pNew = new FilterFactory(xSMGR);
716 return css::uno::Reference< css::uno::XInterface >(static_cast< css::lang::XMultiServiceFactory* >(pNew), css::uno::UNO_QUERY);
717 }
718
719 } // namespace config
720 } // namespace filter
721