1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: FilterContainer.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_fpicker.hxx"
36 #include <osl/diagnose.h>
37 #include "FilterContainer.hxx"
42 #pragma warning(push, 1)
49 //-------------------------------------------------------------------
50 // namespace directives
51 //-------------------------------------------------------------------
53 using ::rtl::OUString
;
55 //-------------------------------------------------------------------------------------
57 //-------------------------------------------------------------------------------------
59 CFilterContainer::CFilterContainer( sal_Int32 initSize
) :
60 m_vFilters( initSize
),
61 m_bIterInitialized( sal_False
)
65 //-----------------------------------------------------------------------------------------
66 // add a name/filter pair
67 //-----------------------------------------------------------------------------------------
69 sal_Bool SAL_CALL
CFilterContainer::addFilter(
70 const OUString
& aName
, const OUString
& aFilter
, sal_Bool bAllowDuplicates
)
72 // check if the filter is already in the container
75 if ( !bAllowDuplicates
)
77 pos
= getFilterTagPos( aName
);
78 if ( pos
< 0 ) // if not there, append
80 m_vFilters
.push_back( std::make_pair( aName
, aFilter
) );
81 m_bIterInitialized
= sal_False
;
86 m_vFilters
.push_back( std::make_pair( aName
, aFilter
) );
87 m_bIterInitialized
= sal_False
;
90 return ( pos
< 0 ) ? sal_True
: sal_False
;
93 //-----------------------------------------------------------------------------------------
95 // Precondition: the container is not empty
96 // there is a filter identified by the given name
97 //-----------------------------------------------------------------------------------------
99 sal_Bool SAL_CALL
CFilterContainer::delFilter( const OUString
& aName
)
101 OSL_ASSERT( m_vFilters
.size() > 0 );
103 sal_Int32 pos
= getFilterTagPos( aName
);
106 m_vFilters
.erase( ( m_vFilters
.begin() + pos
) );
107 m_bIterInitialized
= sal_False
;
110 return ( pos
> -1 ) ? sal_True
: sal_False
;
113 //-----------------------------------------------------------------------------------------
114 // return the number of filters currently in the container
115 //-----------------------------------------------------------------------------------------
117 sal_Int32 SAL_CALL
CFilterContainer::numFilter( )
119 return m_vFilters
.size( );
122 //-----------------------------------------------------------------------------------------
124 //-----------------------------------------------------------------------------------------
126 void SAL_CALL
CFilterContainer::empty()
131 //-----------------------------------------------------------------------------------------
132 // get a filter by name
133 // Precondition: the container is not empty
134 // there is a filter identified by the name
135 //-----------------------------------------------------------------------------------------
137 sal_Bool SAL_CALL
CFilterContainer::getFilter( const OUString
& aName
, OUString
& theFilter
) const
139 OSL_PRECOND( m_vFilters
.size() > 0, "Empty filter container" );
141 sal_Int32 pos
= getFilterTagPos( aName
);
146 theFilter
= m_vFilters
.at( pos
).second
;
148 catch( std::out_of_range
& )
150 OSL_ENSURE( sal_False
, "Filter not in filter container" );
154 return (pos
> -1 ) ? sal_True
: sal_False
;
157 //-----------------------------------------------------------------------------------------
159 //-----------------------------------------------------------------------------------------
161 sal_Bool SAL_CALL
CFilterContainer::getFilter( sal_Int32 aIndex
, OUString
& theFilter
) const
163 sal_Bool bRet
= sal_True
;
167 theFilter
= m_vFilters
.at( aIndex
).first
;
169 catch( std::out_of_range
& )
171 OSL_ENSURE( sal_False
, "Filter index out of range" );
178 //-----------------------------------------------------------------------------------------
180 //-----------------------------------------------------------------------------------------
182 sal_Int32 SAL_CALL
CFilterContainer::getFilterPos( const OUString
& aName
) const
184 return getFilterTagPos( aName
);
187 //-----------------------------------------------------------------------------------------
188 // returns the index of the filter identified by name
189 //-----------------------------------------------------------------------------------------
191 sal_Int32 SAL_CALL
CFilterContainer::getFilterTagPos( const OUString
& aName
) const
193 if ( m_vFilters
.size( ) > 0 )
196 FILTER_VECTOR_T::const_iterator iter
;
197 FILTER_VECTOR_T::const_iterator iter_end
= m_vFilters
.end( );
199 for ( iter
= m_vFilters
.begin( ); iter
!= iter_end
; ++iter
, ++i
)
200 if ( ( *iter
).first
.equalsIgnoreAsciiCase( aName
) )
207 //-----------------------------------------------------------------------------------------
208 // starts enumerating the filter in the container
209 //-----------------------------------------------------------------------------------------
211 void SAL_CALL
CFilterContainer::beginEnumFilter( )
213 m_iter
= m_vFilters
.begin( );
214 m_bIterInitialized
= sal_True
;
217 //-----------------------------------------------------------------------------------------
218 // returns true if another filter has been retrieved
219 //-----------------------------------------------------------------------------------------
221 sal_Bool SAL_CALL
CFilterContainer::getNextFilter( FILTER_ENTRY_T
& nextFilterEntry
)
223 OSL_ASSERT( m_bIterInitialized
);
225 sal_Bool bRet
= ( m_iter
!= m_vFilters
.end( ) );
228 nextFilterEntry
= *m_iter
++;
230 m_bIterInitialized
= sal_False
;
235 //-----------------------------------------------------------------------------------------
236 void SAL_CALL
CFilterContainer::setCurrentFilter( const ::rtl::OUString
& aName
)
238 m_sCurrentFilter
= aName
;
241 //-----------------------------------------------------------------------------------------
242 ::rtl::OUString SAL_CALL
CFilterContainer::getCurrentFilter() const
244 return m_sCurrentFilter
;
247 //###################################################################
250 //-------------------------------------------------------------------
251 // calculates the length of a '\0' separated filter, that means
252 // length of the name + '\0' + length of the filter string +
254 //-------------------------------------------------------------------
256 static sal_uInt32
_getLengthFilter( CFilterContainer::FILTER_ENTRY_T aFilterEntry
)
259 aFilterEntry
.first
.getLength( ) + 1 +
260 aFilterEntry
.second
.getLength( ) + 1 );
263 //-------------------------------------------------------------------
264 // calculates the length of all filters currently in the container
265 //-------------------------------------------------------------------
267 static sal_uInt32
_getTotalFilterLength( CFilterContainer
& aFilterContainer
)
269 CFilterContainer::FILTER_ENTRY_T nextFilter
;
271 aFilterContainer
.beginEnumFilter( );
273 sal_uInt32 totalLength
= 0;
274 while( aFilterContainer
.getNextFilter( nextFilter
) )
275 totalLength
+= _getLengthFilter( nextFilter
);
277 return ( totalLength
> 0 ) ? totalLength
+ 1 : totalLength
;
280 //-------------------------------------------------------------------
282 //-------------------------------------------------------------------
285 void _wcsmemcpy( sal_Unicode
* pDest
, const sal_Unicode
* pSrc
, sal_uInt32 nLength
)
287 memcpy( pDest
, pSrc
, nLength
* sizeof( sal_Unicode
) );
290 //-------------------------------------------------------------------
291 // a helper trivial helper function to create a filter buffer in the
292 // format the Win32 API requires,
293 // e.g. "Text\0*.txt\0Doc\0*.doc;*xls\0\0"
294 //-------------------------------------------------------------------
296 rtl::OUString SAL_CALL
makeWinFilterBuffer( CFilterContainer
& aFilterContainer
)
298 // calculate the required buffer size
299 sal_uInt32 reqBuffSize
= _getTotalFilterLength( aFilterContainer
);
301 // return if there are no filters
305 sal_Unicode
* pBuff
= new sal_Unicode
[reqBuffSize
];
307 // initialize the buffer with 0
308 ZeroMemory( pBuff
, sizeof( sal_Unicode
) * reqBuffSize
);
310 OUString winFilterBuff
;
311 CFilterContainer::FILTER_ENTRY_T nextFilter
;
312 sal_uInt32 memPos
= 0;
314 aFilterContainer
.beginEnumFilter( );
316 while( aFilterContainer
.getNextFilter( nextFilter
) )
320 nextFilter
.first
.getStr( ),
321 nextFilter
.first
.getLength( ) );
323 memPos
+= nextFilter
.first
.getLength( ) + 1;
327 nextFilter
.second
.getStr( ),
328 nextFilter
.second
.getLength( ) );
330 memPos
+= nextFilter
.second
.getLength( ) + 1 ;
333 winFilterBuff
= OUString( pBuff
, reqBuffSize
);
335 // remove the allocated buffer
338 return winFilterBuff
;