1b557fc96SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3b557fc96SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4b557fc96SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5b557fc96SAndrew Rist  * distributed with this work for additional information
6b557fc96SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7b557fc96SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8b557fc96SAndrew Rist  * "License"); you may not use this file except in compliance
9b557fc96SAndrew Rist  * with the License.  You may obtain a copy of the License at
10b557fc96SAndrew Rist  *
11b557fc96SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12b557fc96SAndrew Rist  *
13b557fc96SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14b557fc96SAndrew Rist  * software distributed under the License is distributed on an
15b557fc96SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b557fc96SAndrew Rist  * KIND, either express or implied.  See the License for the
17b557fc96SAndrew Rist  * specific language governing permissions and limitations
18b557fc96SAndrew Rist  * under the License.
19b557fc96SAndrew Rist  *
20b557fc96SAndrew Rist  *************************************************************/
21b557fc96SAndrew Rist 
22b557fc96SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include <functional>
25cdf0e10cSrcweir #include <algorithm>
26cdf0e10cSrcweir #include <vos/mutex.hxx>
27cdf0e10cSrcweir #include <vcl/svapp.hxx>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir // #ifndef _OSL_DIAGNOSE_H_
30cdf0e10cSrcweir // #include <osl/diagnose.h>
31cdf0e10cSrcweir // #endif
32cdf0e10cSrcweir #include "CFStringUtilities.hxx"
33cdf0e10cSrcweir #include "NSString_OOoAdditions.hxx"
34cdf0e10cSrcweir #include "NSURL_OOoAdditions.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir #include "FilterHelper.hxx"
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #pragma mark DEFINES
39cdf0e10cSrcweir #define CLASS_NAME "FilterEntry"
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #pragma mark FilterEntry
42cdf0e10cSrcweir //---------------------------------------------------------------------
FilterEntry(const rtl::OUString & _rTitle,const UnoFilterList & _rSubFilters)43cdf0e10cSrcweir FilterEntry::FilterEntry( const rtl::OUString& _rTitle, const UnoFilterList& _rSubFilters )
44cdf0e10cSrcweir :m_sTitle( _rTitle )
45cdf0e10cSrcweir ,m_aSubFilters( _rSubFilters )
46cdf0e10cSrcweir {
47cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", _rTitle);
48cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
49cdf0e10cSrcweir }
50cdf0e10cSrcweir 
51cdf0e10cSrcweir //---------------------------------------------------------------------
hasSubFilters() const52cdf0e10cSrcweir sal_Bool FilterEntry::hasSubFilters() const
53cdf0e10cSrcweir {
54cdf0e10cSrcweir //    OSL_TRACE(">>> FilterEntry::%s", __func__);
55cdf0e10cSrcweir     sal_Bool bReturn = ( 0 < m_aSubFilters.getLength() );
56cdf0e10cSrcweir //    OSL_TRACE("<<< FilterEntry::%s retVal: %d", __func__, bReturn);
57cdf0e10cSrcweir     return bReturn;
58cdf0e10cSrcweir }
59cdf0e10cSrcweir 
60cdf0e10cSrcweir //---------------------------------------------------------------------
getSubFilters(UnoFilterList & _rSubFilterList)61cdf0e10cSrcweir sal_Int32 FilterEntry::getSubFilters( UnoFilterList& _rSubFilterList )
62cdf0e10cSrcweir {
63cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     _rSubFilterList = m_aSubFilters;
66cdf0e10cSrcweir     sal_Int32 nReturn = m_aSubFilters.getLength();
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__, nReturn);
69cdf0e10cSrcweir 
70cdf0e10cSrcweir     return nReturn;
71cdf0e10cSrcweir }
72cdf0e10cSrcweir 
73cdf0e10cSrcweir #pragma mark statics
74cdf0e10cSrcweir static bool
isFilterString(const rtl::OUString & rFilterString,const char * pMatch)75cdf0e10cSrcweir isFilterString( const rtl::OUString& rFilterString, const char *pMatch )
76cdf0e10cSrcweir {
77cdf0e10cSrcweir     sal_Int32 nIndex = 0;
78cdf0e10cSrcweir     rtl::OUString aToken;
79cdf0e10cSrcweir     bool bIsFilter = true;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir     rtl::OUString aMatch(rtl::OUString::createFromAscii(pMatch));
82cdf0e10cSrcweir 
83cdf0e10cSrcweir     do
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir         aToken = rFilterString.getToken( 0, ';', nIndex );
86cdf0e10cSrcweir         if( !aToken.match( aMatch ) )
87cdf0e10cSrcweir         {
88cdf0e10cSrcweir             bIsFilter = false;
89cdf0e10cSrcweir             break;
90cdf0e10cSrcweir         }
91cdf0e10cSrcweir     }
92cdf0e10cSrcweir     while( nIndex >= 0 );
93cdf0e10cSrcweir 
94cdf0e10cSrcweir     return bIsFilter;
95cdf0e10cSrcweir }
96cdf0e10cSrcweir 
97cdf0e10cSrcweir //=====================================================================
98cdf0e10cSrcweir 
99cdf0e10cSrcweir static rtl::OUString
shrinkFilterName(const rtl::OUString aFilterName,bool bAllowNoStar=false)100cdf0e10cSrcweir shrinkFilterName( const rtl::OUString aFilterName, bool bAllowNoStar = false )
101cdf0e10cSrcweir {
102cdf0e10cSrcweir     // DBG_PRINT_ENTRY(CLASS_NAME, "shrinkFilterName", "filterName", aFilterName);
103cdf0e10cSrcweir 
104cdf0e10cSrcweir     int i;
105cdf0e10cSrcweir     int nBracketLen = -1;
106cdf0e10cSrcweir     int nBracketEnd = -1;
107cdf0e10cSrcweir     rtl::OUString rFilterName = aFilterName;
108*24c56ab9SHerbert Dürr     const sal_Unicode* pStr = rFilterName.getStr();
109cdf0e10cSrcweir     rtl::OUString aRealName = rFilterName;
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     for( i = aRealName.getLength() - 1; i > 0; i-- )
112cdf0e10cSrcweir     {
113cdf0e10cSrcweir         if( pStr[i] == ')' )
114cdf0e10cSrcweir             nBracketEnd = i;
115cdf0e10cSrcweir         else if( pStr[i] == '(' )
116cdf0e10cSrcweir         {
117cdf0e10cSrcweir             nBracketLen = nBracketEnd - i;
118cdf0e10cSrcweir             if( nBracketEnd <= 0 )
119cdf0e10cSrcweir                 continue;
120cdf0e10cSrcweir             if( isFilterString( rFilterName.copy( i + 1, nBracketLen - 1 ), "*." ) )
121cdf0e10cSrcweir                 aRealName = aRealName.replaceAt( i, nBracketLen + 1, rtl::OUString() );
122cdf0e10cSrcweir             else if (bAllowNoStar)
123cdf0e10cSrcweir             {
124cdf0e10cSrcweir                 if( isFilterString( rFilterName.copy( i + 1, nBracketLen - 1 ), ".") )
125cdf0e10cSrcweir                     aRealName = aRealName.replaceAt( i, nBracketLen + 1, rtl::OUString() );
126cdf0e10cSrcweir             }
127cdf0e10cSrcweir         }
128cdf0e10cSrcweir     }
129cdf0e10cSrcweir 
130cdf0e10cSrcweir     return aRealName;
131cdf0e10cSrcweir }
132cdf0e10cSrcweir 
133cdf0e10cSrcweir //------------------------------------------------------------------------------------
134cdf0e10cSrcweir namespace {
135cdf0e10cSrcweir     //................................................................................
136cdf0e10cSrcweir     struct FilterTitleMatch : public ::std::unary_function< FilterEntry, bool >
137cdf0e10cSrcweir     {
138cdf0e10cSrcweir protected:
139cdf0e10cSrcweir         const rtl::OUString rTitle;
140cdf0e10cSrcweir 
141cdf0e10cSrcweir public:
FilterTitleMatch__anona57501bf0111::FilterTitleMatch142cdf0e10cSrcweir         FilterTitleMatch( const rtl::OUString _rTitle ) : rTitle( _rTitle ) { }
143cdf0e10cSrcweir 
144cdf0e10cSrcweir         //............................................................................
operator ()__anona57501bf0111::FilterTitleMatch145cdf0e10cSrcweir         bool operator () ( const FilterEntry& _rEntry )
146cdf0e10cSrcweir         {
147cdf0e10cSrcweir             sal_Bool bMatch;
148cdf0e10cSrcweir             if( !_rEntry.hasSubFilters() ) {
149cdf0e10cSrcweir                 //first try the complete filter name
150cdf0e10cSrcweir                 rtl::OUString title = _rEntry.getTitle();
151cdf0e10cSrcweir                 bMatch = ( title.equals(rTitle) );
152cdf0e10cSrcweir                 if (!bMatch) {
153cdf0e10cSrcweir                     //we didn't find a match using the full name, let's give it another
154cdf0e10cSrcweir                     //try using the shrunk version
155cdf0e10cSrcweir                     rtl::OUString aShrunkName = shrinkFilterName( _rEntry.getTitle() ).trim();
156cdf0e10cSrcweir                     bMatch = ( aShrunkName.equals(rTitle) );
157cdf0e10cSrcweir                 }
158cdf0e10cSrcweir             }
159cdf0e10cSrcweir             else
160cdf0e10cSrcweir                 // a filter group -> search the sub filters
161cdf0e10cSrcweir                 bMatch =
162cdf0e10cSrcweir                     _rEntry.endSubFilters() != ::std::find_if(
163cdf0e10cSrcweir                                                               _rEntry.beginSubFilters(),
164cdf0e10cSrcweir                                                               _rEntry.endSubFilters(),
165cdf0e10cSrcweir                                                               *this
166cdf0e10cSrcweir                                                               );
167cdf0e10cSrcweir 
168cdf0e10cSrcweir             return bMatch ? true : false;
169cdf0e10cSrcweir         }
170cdf0e10cSrcweir 
operator ()__anona57501bf0111::FilterTitleMatch171cdf0e10cSrcweir         bool operator () ( const UnoFilterEntry& _rEntry )
172cdf0e10cSrcweir         {
173cdf0e10cSrcweir             rtl::OUString aShrunkName = shrinkFilterName( _rEntry.First );
174cdf0e10cSrcweir             bool retVal = aShrunkName.equals(rTitle);
175cdf0e10cSrcweir             return retVal;
176cdf0e10cSrcweir         }
177cdf0e10cSrcweir     };
178cdf0e10cSrcweir }
179cdf0e10cSrcweir 
180cdf0e10cSrcweir #undef CLASS_NAME
181cdf0e10cSrcweir #define CLASS_NAME "FilterHelper"
182cdf0e10cSrcweir 
FilterHelper()183cdf0e10cSrcweir FilterHelper::FilterHelper()
184cdf0e10cSrcweir : m_pFilterList(NULL)
185cdf0e10cSrcweir , m_pFilterNames(NULL)
186cdf0e10cSrcweir {
187cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
188cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
189cdf0e10cSrcweir }
190cdf0e10cSrcweir 
~FilterHelper()191cdf0e10cSrcweir FilterHelper::~FilterHelper()
192cdf0e10cSrcweir {
193cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
194cdf0e10cSrcweir 
195cdf0e10cSrcweir     NSAutoreleasePool *pool = [NSAutoreleasePool new];
196cdf0e10cSrcweir 
197cdf0e10cSrcweir     if (NULL != m_pFilterList) {
198cdf0e10cSrcweir         delete m_pFilterList;
199cdf0e10cSrcweir     }
200cdf0e10cSrcweir 
201cdf0e10cSrcweir     if (NULL != m_pFilterNames) {
202cdf0e10cSrcweir         //we called retain when we added the strings to the list, so we should release them now
203cdf0e10cSrcweir         for (NSStringList::iterator iter = m_pFilterNames->begin(); iter != m_pFilterNames->end(); iter++) {
204cdf0e10cSrcweir             [*iter release];
205cdf0e10cSrcweir         }
206cdf0e10cSrcweir         delete m_pFilterNames;
207cdf0e10cSrcweir     }
208cdf0e10cSrcweir 
209cdf0e10cSrcweir     [pool release];
210cdf0e10cSrcweir 
211cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
212cdf0e10cSrcweir }
213cdf0e10cSrcweir 
214cdf0e10cSrcweir //------------------------------------------------------------------------------------
FilterNameExists(const rtl::OUString rTitle)215cdf0e10cSrcweir sal_Bool FilterHelper::FilterNameExists( const rtl::OUString rTitle )
216cdf0e10cSrcweir {
217cdf0e10cSrcweir     sal_Bool bRet = sal_False;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir     if( m_pFilterList )
220cdf0e10cSrcweir         bRet =
221cdf0e10cSrcweir             m_pFilterList->end() != ::std::find_if(
222cdf0e10cSrcweir                                                    m_pFilterList->begin(),
223cdf0e10cSrcweir                                                    m_pFilterList->end(),
224cdf0e10cSrcweir                                                    FilterTitleMatch( rTitle )
225cdf0e10cSrcweir                                                    );
226cdf0e10cSrcweir 
227cdf0e10cSrcweir     return bRet;
228cdf0e10cSrcweir }
229cdf0e10cSrcweir 
230cdf0e10cSrcweir //------------------------------------------------------------------------------------
FilterNameExists(const UnoFilterList & _rGroupedFilters)231cdf0e10cSrcweir sal_Bool FilterHelper::FilterNameExists( const UnoFilterList& _rGroupedFilters )
232cdf0e10cSrcweir {
233cdf0e10cSrcweir     sal_Bool bRet = sal_False;
234cdf0e10cSrcweir 
235cdf0e10cSrcweir     if( m_pFilterList )
236cdf0e10cSrcweir     {
237cdf0e10cSrcweir         const UnoFilterEntry* pStart = _rGroupedFilters.getConstArray();
238cdf0e10cSrcweir         const UnoFilterEntry* pEnd = pStart + _rGroupedFilters.getLength();
239cdf0e10cSrcweir         for( ; pStart != pEnd; ++pStart )
240cdf0e10cSrcweir             if( m_pFilterList->end() != ::std::find_if(
241cdf0e10cSrcweir                                                         m_pFilterList->begin(),
242cdf0e10cSrcweir                                                         m_pFilterList->end(),
243cdf0e10cSrcweir                                                         FilterTitleMatch( pStart->First ) ) )
244cdf0e10cSrcweir                 break;
245cdf0e10cSrcweir 
246cdf0e10cSrcweir         bRet = (pStart != pEnd);
247cdf0e10cSrcweir     }
248cdf0e10cSrcweir 
249cdf0e10cSrcweir     return bRet;
250cdf0e10cSrcweir }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir //------------------------------------------------------------------------------------
ensureFilterList(const::rtl::OUString & _rInitialCurrentFilter)253cdf0e10cSrcweir void FilterHelper::ensureFilterList( const ::rtl::OUString& _rInitialCurrentFilter )
254cdf0e10cSrcweir {
255cdf0e10cSrcweir     //OSL_TRACE(">>> FilterHelper::%s", __func__);
256cdf0e10cSrcweir     if( NULL == m_pFilterList )
257cdf0e10cSrcweir     {
258cdf0e10cSrcweir         m_pFilterList = new FilterList;
259cdf0e10cSrcweir 
260cdf0e10cSrcweir         // set the first filter to the current filter
261cdf0e10cSrcweir         m_aCurrentFilter = _rInitialCurrentFilter;
262cdf0e10cSrcweir         OSL_TRACE("ensureFilterList filter:%s", OUStringToOString(m_aCurrentFilter, RTL_TEXTENCODING_UTF8).getStr());
263cdf0e10cSrcweir     }
264cdf0e10cSrcweir     //OSL_TRACE("<<< FilterHelper::%s", __func__);
265cdf0e10cSrcweir }
266cdf0e10cSrcweir 
SetCurFilter(const rtl::OUString & rFilter)267cdf0e10cSrcweir void FilterHelper::SetCurFilter( const rtl::OUString& rFilter )
268cdf0e10cSrcweir {
269cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "filter", rFilter);
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
272cdf0e10cSrcweir 
273cdf0e10cSrcweir     if(m_aCurrentFilter.equals(rFilter) == false)
274cdf0e10cSrcweir     {
275cdf0e10cSrcweir         m_aCurrentFilter = rFilter;
276cdf0e10cSrcweir     }
277cdf0e10cSrcweir 
278cdf0e10cSrcweir     //only for output purposes
279cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
280cdf0e10cSrcweir     FilterList::iterator aFilter = ::std::find_if(m_pFilterList->begin(), m_pFilterList->end(), FilterTitleMatch(m_aCurrentFilter));
281cdf0e10cSrcweir     if (aFilter != m_pFilterList->end()) {
282cdf0e10cSrcweir         OUStringList suffixes = aFilter->getFilterSuffixList();
283cdf0e10cSrcweir         if (!suffixes.empty()) {
284cdf0e10cSrcweir             OSL_TRACE("Current active suffixes: ");
285cdf0e10cSrcweir             OUStringList::iterator suffIter = suffixes.begin();
286cdf0e10cSrcweir             while(suffIter != suffixes.end()) {
287cdf0e10cSrcweir                 OSL_TRACE("%s", OUStringToOString((*suffIter), RTL_TEXTENCODING_UTF8).getStr());
288cdf0e10cSrcweir                 suffIter++;
289cdf0e10cSrcweir             }
290cdf0e10cSrcweir         }
291cdf0e10cSrcweir     } else {
292cdf0e10cSrcweir         OSL_TRACE("No filter entry was found for that name!");
293cdf0e10cSrcweir     }
294cdf0e10cSrcweir #endif
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
297cdf0e10cSrcweir }
298cdf0e10cSrcweir 
SetFilters()299cdf0e10cSrcweir void FilterHelper::SetFilters()
300cdf0e10cSrcweir {
301cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
302cdf0e10cSrcweir 
303cdf0e10cSrcweir     // set the default filter
304cdf0e10cSrcweir     if( m_aCurrentFilter.getLength() > 0 )
305cdf0e10cSrcweir     {
306cdf0e10cSrcweir         OSL_TRACE( "Setting current filter to %s", OUStringToOString(m_aCurrentFilter, RTL_TEXTENCODING_UTF8).getStr());
307cdf0e10cSrcweir 
308cdf0e10cSrcweir         SetCurFilter( m_aCurrentFilter );
309cdf0e10cSrcweir     }
310cdf0e10cSrcweir 
311cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
312cdf0e10cSrcweir }
313cdf0e10cSrcweir 
appendFilter(const::rtl::OUString & aTitle,const::rtl::OUString & aFilterString)314cdf0e10cSrcweir void FilterHelper::appendFilter(const ::rtl::OUString& aTitle, const ::rtl::OUString& aFilterString)
315cdf0e10cSrcweir throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ) {
316cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", aTitle, "filter", aFilterString);
317cdf0e10cSrcweir 
318cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
319cdf0e10cSrcweir 
320cdf0e10cSrcweir     if( FilterNameExists( aTitle ) ) {
321cdf0e10cSrcweir         throw com::sun::star::lang::IllegalArgumentException();
322cdf0e10cSrcweir     }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir     // ensure that we have a filter list
325cdf0e10cSrcweir     ensureFilterList( aTitle );
326cdf0e10cSrcweir 
327cdf0e10cSrcweir     // append the filter
328cdf0e10cSrcweir     OUStringList suffixList;
329cdf0e10cSrcweir     fillSuffixList(suffixList, aFilterString);
330cdf0e10cSrcweir     m_pFilterList->push_back(FilterEntry( aTitle, suffixList ) );
331cdf0e10cSrcweir 
332cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
333cdf0e10cSrcweir }
334cdf0e10cSrcweir 
setCurrentFilter(const::rtl::OUString & aTitle)335cdf0e10cSrcweir void FilterHelper::setCurrentFilter( const ::rtl::OUString& aTitle )
336cdf0e10cSrcweir throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException ) {
337cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "aTitle", OUStringToOString(aTitle, RTL_TEXTENCODING_UTF8).getStr());
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     SetCurFilter(aTitle);
340cdf0e10cSrcweir 
341cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
342cdf0e10cSrcweir }
343cdf0e10cSrcweir 
getCurrentFilter()344cdf0e10cSrcweir ::rtl::OUString SAL_CALL FilterHelper::getCurrentFilter(  )
345cdf0e10cSrcweir throw( ::com::sun::star::uno::RuntimeException ) {
346cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
347cdf0e10cSrcweir 
348cdf0e10cSrcweir     ::rtl::OUString sReturn = (m_aCurrentFilter);
349cdf0e10cSrcweir 
350cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__, OUStringToOString(sReturn, RTL_TEXTENCODING_UTF8).getStr());
351cdf0e10cSrcweir 
352cdf0e10cSrcweir     return sReturn;
353cdf0e10cSrcweir }
354cdf0e10cSrcweir 
appendFilterGroup(const::rtl::OUString & sGroupTitle,const::com::sun::star::uno::Sequence<::com::sun::star::beans::StringPair> & aFilters)355cdf0e10cSrcweir void SAL_CALL FilterHelper::appendFilterGroup( const ::rtl::OUString& sGroupTitle, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::StringPair >& aFilters )
356cdf0e10cSrcweir throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) {
357cdf0e10cSrcweir 
358cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "title", OUStringToOString(sGroupTitle, RTL_TEXTENCODING_UTF8).getStr());
359cdf0e10cSrcweir 
360cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
361cdf0e10cSrcweir 
362cdf0e10cSrcweir     //add a separator if this is not the first group to be added
363cdf0e10cSrcweir     sal_Bool bPrependSeparator = m_pFilterList != NULL;
364cdf0e10cSrcweir 
365cdf0e10cSrcweir     // ensure that we have a filter list
366cdf0e10cSrcweir     ::rtl::OUString sInitialCurrentFilter;
367cdf0e10cSrcweir     if( aFilters.getLength() > 0)
368cdf0e10cSrcweir         sInitialCurrentFilter = aFilters[0].First;
369cdf0e10cSrcweir     ensureFilterList( sInitialCurrentFilter );
370cdf0e10cSrcweir 
371cdf0e10cSrcweir     // append the filter
372cdf0e10cSrcweir     if (bPrependSeparator) {
373cdf0e10cSrcweir         rtl::OUString dash = rtl::OUString::createFromAscii("-");
374cdf0e10cSrcweir         OUStringList emptyList;
375cdf0e10cSrcweir         m_pFilterList->push_back(FilterEntry(dash, emptyList));
376cdf0e10cSrcweir     }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     const com::sun::star::beans::StringPair* pSubFilters   = aFilters.getConstArray();
379cdf0e10cSrcweir     const com::sun::star::beans::StringPair* pSubFiltersEnd = pSubFilters + aFilters.getLength();
380cdf0e10cSrcweir     for( ; pSubFilters != pSubFiltersEnd; ++pSubFilters ) {
381cdf0e10cSrcweir         appendFilter(pSubFilters->First, pSubFilters->Second);
382cdf0e10cSrcweir     }
383cdf0e10cSrcweir 
384cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
385cdf0e10cSrcweir }
386cdf0e10cSrcweir 
filenameMatchesFilter(NSString * sFilename)387cdf0e10cSrcweir sal_Bool FilterHelper::filenameMatchesFilter(NSString* sFilename)
388cdf0e10cSrcweir {
389cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
390cdf0e10cSrcweir 
391cdf0e10cSrcweir     if (m_aCurrentFilter == NULL) {
392cdf0e10cSrcweir         OSL_TRACE("filter name is null");
393cdf0e10cSrcweir         return sal_True;
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir     NSFileManager *manager = [NSFileManager defaultManager];
397cdf0e10cSrcweir     NSDictionary* pAttribs = [manager fileAttributesAtPath: sFilename traverseLink: NO];
398cdf0e10cSrcweir     if( pAttribs )
399cdf0e10cSrcweir     {
400cdf0e10cSrcweir         NSObject* pType = [pAttribs objectForKey: NSFileType];
401cdf0e10cSrcweir         if( pType && [pType isKindOfClass: [NSString class]] )
402cdf0e10cSrcweir         {
403cdf0e10cSrcweir             NSString* pT = (NSString*)pType;
404cdf0e10cSrcweir             if( [pT isEqualToString: NSFileTypeDirectory]    ||
405cdf0e10cSrcweir                 [pT isEqualToString: NSFileTypeSymbolicLink] )
406cdf0e10cSrcweir                 return sal_True;
407cdf0e10cSrcweir         }
408cdf0e10cSrcweir     }
409cdf0e10cSrcweir 
410cdf0e10cSrcweir     FilterList::iterator filter = ::std::find_if(m_pFilterList->begin(), m_pFilterList->end(), FilterTitleMatch(m_aCurrentFilter));
411cdf0e10cSrcweir     if (filter == m_pFilterList->end()) {
412cdf0e10cSrcweir         OSL_TRACE("filter not found in list");
413cdf0e10cSrcweir         return sal_True;
414cdf0e10cSrcweir     }
415cdf0e10cSrcweir 
416cdf0e10cSrcweir     OUStringList suffixList = filter->getFilterSuffixList();
417cdf0e10cSrcweir 
418cdf0e10cSrcweir     {
419cdf0e10cSrcweir         rtl::OUString aName = [sFilename OUString];
420cdf0e10cSrcweir         rtl::OUString allMatcher = rtl::OUString::createFromAscii(".*");
421cdf0e10cSrcweir         for(OUStringList::iterator iter = suffixList.begin(); iter != suffixList.end(); iter++) {
422cdf0e10cSrcweir             if (aName.matchIgnoreAsciiCase(*iter, aName.getLength() - (*iter).getLength()) || ((*iter).equals(allMatcher))) {
423cdf0e10cSrcweir                 return sal_True;
424cdf0e10cSrcweir             }
425cdf0e10cSrcweir         }
426cdf0e10cSrcweir     }
427cdf0e10cSrcweir 
428cdf0e10cSrcweir     // might be an alias
429cdf0e10cSrcweir     NSString* pResolved = resolveAlias( sFilename );
430cdf0e10cSrcweir     if( pResolved )
431cdf0e10cSrcweir     {
432cdf0e10cSrcweir         sal_Bool bResult = filenameMatchesFilter( pResolved );
433cdf0e10cSrcweir         [pResolved autorelease];
434cdf0e10cSrcweir         if( bResult )
435cdf0e10cSrcweir             return sal_True;
436cdf0e10cSrcweir     }
437cdf0e10cSrcweir 
438cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
439cdf0e10cSrcweir 
440cdf0e10cSrcweir     return sal_False;
441cdf0e10cSrcweir }
442cdf0e10cSrcweir 
getFilterList()443cdf0e10cSrcweir FilterList* FilterHelper::getFilterList() {
444cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
445cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     return m_pFilterList;
448cdf0e10cSrcweir }
449cdf0e10cSrcweir 
getFilterNames()450cdf0e10cSrcweir NSStringList* FilterHelper::getFilterNames() {
451cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
452cdf0e10cSrcweir 
453cdf0e10cSrcweir     if (NULL == m_pFilterList)
454cdf0e10cSrcweir         return NULL;
455cdf0e10cSrcweir     if (NULL == m_pFilterNames) {
456cdf0e10cSrcweir         //build filter names list
457cdf0e10cSrcweir         m_pFilterNames = new NSStringList;
458cdf0e10cSrcweir         for (FilterList::iterator iter = m_pFilterList->begin(); iter != m_pFilterList->end(); iter++) {
459cdf0e10cSrcweir             m_pFilterNames->push_back([[NSString stringWithOUString:iter->getTitle()] retain]);
460cdf0e10cSrcweir         }
461cdf0e10cSrcweir     }
462cdf0e10cSrcweir 
463cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
464cdf0e10cSrcweir 
465cdf0e10cSrcweir     return m_pFilterNames;
466cdf0e10cSrcweir }
467cdf0e10cSrcweir 
SetFilterAtIndex(unsigned index)468cdf0e10cSrcweir void FilterHelper::SetFilterAtIndex(unsigned index) {
469cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "index", index);
470cdf0e10cSrcweir 
471cdf0e10cSrcweir     if (m_pFilterList->size() <= index) {
472cdf0e10cSrcweir         index = 0;
473cdf0e10cSrcweir     }
474cdf0e10cSrcweir     FilterEntry entry = m_pFilterList->at(index);
475cdf0e10cSrcweir     SetCurFilter(entry.getTitle());
476cdf0e10cSrcweir 
477cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
478cdf0e10cSrcweir }
479cdf0e10cSrcweir 
fillSuffixList(OUStringList & aSuffixList,const::rtl::OUString & suffixString)480cdf0e10cSrcweir void FilterHelper::fillSuffixList(OUStringList& aSuffixList, const ::rtl::OUString& suffixString) {
481cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__, "aSuffixList", suffixString);
482cdf0e10cSrcweir 
483cdf0e10cSrcweir     sal_Int32 nIndex = 0;
484cdf0e10cSrcweir     do {
485cdf0e10cSrcweir         rtl::OUString aToken = suffixString.getToken( 0, ';', nIndex );
486cdf0e10cSrcweir         aSuffixList.push_back(aToken.copy(1));
487cdf0e10cSrcweir     } while ( nIndex >= 0 );
488cdf0e10cSrcweir 
489cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
490cdf0e10cSrcweir }
491cdf0e10cSrcweir 
getCurrentFilterIndex()492cdf0e10cSrcweir int FilterHelper::getCurrentFilterIndex() {
493cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
494cdf0e10cSrcweir 
495cdf0e10cSrcweir     int result = 0;//default to first filter
496cdf0e10cSrcweir     if (m_aCurrentFilter.getLength() > 0) {
497cdf0e10cSrcweir         int i = 0;
498cdf0e10cSrcweir         for (FilterList::iterator iter = m_pFilterList->begin(); iter != m_pFilterList->end(); iter++, i++) {
499cdf0e10cSrcweir             rtl::OUString aTitle = iter->getTitle();
500cdf0e10cSrcweir             if (m_aCurrentFilter.equals(aTitle)) {
501cdf0e10cSrcweir                 result = i;
502cdf0e10cSrcweir                 break;
503cdf0e10cSrcweir             } else {
504cdf0e10cSrcweir                 aTitle = shrinkFilterName(aTitle).trim();
505cdf0e10cSrcweir                 if (m_aCurrentFilter.equals(aTitle)) {
506cdf0e10cSrcweir                     result = i;
507cdf0e10cSrcweir                     break;
508cdf0e10cSrcweir                 }
509cdf0e10cSrcweir             }
510cdf0e10cSrcweir         }
511cdf0e10cSrcweir     }
512cdf0e10cSrcweir 
513cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__, result);
514cdf0e10cSrcweir 
515cdf0e10cSrcweir     return result;
516cdf0e10cSrcweir }
517cdf0e10cSrcweir 
getCurrentFilterSuffixList()518cdf0e10cSrcweir OUStringList FilterHelper::getCurrentFilterSuffixList() {
519cdf0e10cSrcweir     DBG_PRINT_ENTRY(CLASS_NAME, __func__);
520cdf0e10cSrcweir 
521cdf0e10cSrcweir     OUStringList retVal;
522cdf0e10cSrcweir     if (m_aCurrentFilter.getLength() > 0) {
523cdf0e10cSrcweir         for (FilterList::iterator iter = m_pFilterList->begin(); iter != m_pFilterList->end(); iter++) {
524cdf0e10cSrcweir             rtl::OUString aTitle = iter->getTitle();
525cdf0e10cSrcweir             if (m_aCurrentFilter.equals(aTitle)) {
526cdf0e10cSrcweir                 retVal = iter->getFilterSuffixList();
527cdf0e10cSrcweir                 break;
528cdf0e10cSrcweir             } else {
529cdf0e10cSrcweir                 aTitle = shrinkFilterName(aTitle).trim();
530cdf0e10cSrcweir                 if (m_aCurrentFilter.equals(aTitle)) {
531cdf0e10cSrcweir                     retVal = iter->getFilterSuffixList();
532cdf0e10cSrcweir                     break;
533cdf0e10cSrcweir                 }
534cdf0e10cSrcweir             }
535cdf0e10cSrcweir         }
536cdf0e10cSrcweir     }
537cdf0e10cSrcweir 
538cdf0e10cSrcweir     DBG_PRINT_EXIT(CLASS_NAME, __func__);
539cdf0e10cSrcweir 
540cdf0e10cSrcweir     return retVal;
541cdf0e10cSrcweir }
542