merged tag ooo/DEV300_m102
[LibreOffice.git] / fpicker / source / win32 / filepicker / FilterContainer.cxx
bloba54f796e23ac551a6ca0bba7ab3e5bc86d23c311
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_fpicker.hxx"
32 #include <stdexcept>
33 #include <osl/diagnose.h>
34 #include "FilterContainer.hxx"
36 #include <utility>
38 #if defined _MSC_VER
39 #pragma warning(push, 1)
40 #endif
41 #include <windows.h>
42 #if defined _MSC_VER
43 #pragma warning(pop)
44 #endif
46 //-------------------------------------------------------------------
47 // namespace directives
48 //-------------------------------------------------------------------
50 using ::rtl::OUString;
52 //-------------------------------------------------------------------------------------
53 // ctor
54 //-------------------------------------------------------------------------------------
56 CFilterContainer::CFilterContainer( sal_Int32 initSize ) :
57 m_vFilters( initSize ),
58 m_bIterInitialized( sal_False )
62 //-----------------------------------------------------------------------------------------
63 // add a name/filter pair
64 //-----------------------------------------------------------------------------------------
66 sal_Bool SAL_CALL CFilterContainer::addFilter(
67 const OUString& aName, const OUString& aFilter, sal_Bool bAllowDuplicates )
69 // check if the filter is already in the container
70 sal_Int32 pos = -1;
72 if ( !bAllowDuplicates )
74 pos = getFilterTagPos( aName );
75 if ( pos < 0 ) // if not there, append
77 m_vFilters.push_back( std::make_pair( aName, aFilter ) );
78 m_bIterInitialized = sal_False;
81 else
83 m_vFilters.push_back( std::make_pair( aName, aFilter ) );
84 m_bIterInitialized = sal_False;
87 return ( pos < 0 ) ? sal_True : sal_False;
90 //-----------------------------------------------------------------------------------------
91 // delete a filter
92 // Precondition: the container is not empty
93 // there is a filter identified by the given name
94 //-----------------------------------------------------------------------------------------
96 sal_Bool SAL_CALL CFilterContainer::delFilter( const OUString& aName )
98 OSL_ASSERT( m_vFilters.size() > 0 );
100 sal_Int32 pos = getFilterTagPos( aName );
101 if ( pos > -1 )
103 m_vFilters.erase( ( m_vFilters.begin() + pos ) );
104 m_bIterInitialized = sal_False;
107 return ( pos > -1 ) ? sal_True : sal_False;
110 //-----------------------------------------------------------------------------------------
111 // return the number of filters currently in the container
112 //-----------------------------------------------------------------------------------------
114 sal_Int32 SAL_CALL CFilterContainer::numFilter( )
116 return m_vFilters.size( );
119 //-----------------------------------------------------------------------------------------
120 // clear all entries
121 //-----------------------------------------------------------------------------------------
123 void SAL_CALL CFilterContainer::empty()
125 m_vFilters.clear( );
128 //-----------------------------------------------------------------------------------------
129 // get a filter by name
130 // Precondition: the container is not empty
131 // there is a filter identified by the name
132 //-----------------------------------------------------------------------------------------
134 sal_Bool SAL_CALL CFilterContainer::getFilter( const OUString& aName, OUString& theFilter ) const
136 OSL_PRECOND( m_vFilters.size() > 0, "Empty filter container" );
138 sal_Int32 pos = getFilterTagPos( aName );
142 if ( pos > -1 )
143 theFilter = m_vFilters.at( pos ).second;
145 catch( std::out_of_range& )
147 OSL_ENSURE( sal_False, "Filter not in filter container" );
148 pos = -1;
151 return (pos > -1 ) ? sal_True : sal_False;
154 //-----------------------------------------------------------------------------------------
156 //-----------------------------------------------------------------------------------------
158 sal_Bool SAL_CALL CFilterContainer::getFilter( sal_Int32 aIndex, OUString& theFilter ) const
160 sal_Bool bRet = sal_True;
164 theFilter = m_vFilters.at( aIndex ).first;
166 catch( std::out_of_range& )
168 OSL_ENSURE( sal_False, "Filter index out of range" );
169 bRet = sal_False;
172 return bRet;
175 //-----------------------------------------------------------------------------------------
177 //-----------------------------------------------------------------------------------------
179 sal_Int32 SAL_CALL CFilterContainer::getFilterPos( const OUString& aName ) const
181 return getFilterTagPos( aName );
184 //-----------------------------------------------------------------------------------------
185 // returns the index of the filter identified by name
186 //-----------------------------------------------------------------------------------------
188 sal_Int32 SAL_CALL CFilterContainer::getFilterTagPos( const OUString& aName ) const
190 if ( m_vFilters.size( ) > 0 )
192 sal_Int32 i = 0;
193 FILTER_VECTOR_T::const_iterator iter;
194 FILTER_VECTOR_T::const_iterator iter_end = m_vFilters.end( );
196 for ( iter = m_vFilters.begin( ); iter != iter_end; ++iter, ++i )
197 if ( ( *iter ).first.equalsIgnoreAsciiCase( aName ) )
198 return i;
201 return -1;
204 //-----------------------------------------------------------------------------------------
205 // starts enumerating the filter in the container
206 //-----------------------------------------------------------------------------------------
208 void SAL_CALL CFilterContainer::beginEnumFilter( )
210 m_iter = m_vFilters.begin( );
211 m_bIterInitialized = sal_True;
214 //-----------------------------------------------------------------------------------------
215 // returns true if another filter has been retrieved
216 //-----------------------------------------------------------------------------------------
218 sal_Bool SAL_CALL CFilterContainer::getNextFilter( FILTER_ENTRY_T& nextFilterEntry )
220 OSL_ASSERT( m_bIterInitialized );
222 sal_Bool bRet = ( m_iter != m_vFilters.end( ) );
224 if ( bRet )
225 nextFilterEntry = *m_iter++;
226 else
227 m_bIterInitialized = sal_False;
229 return bRet;
232 //-----------------------------------------------------------------------------------------
233 void SAL_CALL CFilterContainer::setCurrentFilter( const ::rtl::OUString& aName )
235 m_sCurrentFilter = aName;
238 //-----------------------------------------------------------------------------------------
239 ::rtl::OUString SAL_CALL CFilterContainer::getCurrentFilter() const
241 return m_sCurrentFilter;
244 //###################################################################
247 //-------------------------------------------------------------------
248 // calculates the length of a '\0' separated filter, that means
249 // length of the name + '\0' + length of the filter string +
250 // a trailing '\0'
251 //-------------------------------------------------------------------
253 static sal_uInt32 _getLengthFilter( CFilterContainer::FILTER_ENTRY_T aFilterEntry )
255 return (
256 aFilterEntry.first.getLength( ) + 1 +
257 aFilterEntry.second.getLength( ) + 1 );
260 //-------------------------------------------------------------------
261 // calculates the length of all filters currently in the container
262 //-------------------------------------------------------------------
264 static sal_uInt32 _getTotalFilterLength( CFilterContainer& aFilterContainer )
266 CFilterContainer::FILTER_ENTRY_T nextFilter;
268 aFilterContainer.beginEnumFilter( );
270 sal_uInt32 totalLength = 0;
271 while( aFilterContainer.getNextFilter( nextFilter ) )
272 totalLength += _getLengthFilter( nextFilter );
274 return ( totalLength > 0 ) ? totalLength + 1 : totalLength;
277 //-------------------------------------------------------------------
279 //-------------------------------------------------------------------
281 inline
282 void _wcsmemcpy( sal_Unicode* pDest, const sal_Unicode* pSrc, sal_uInt32 nLength )
284 memcpy( pDest, pSrc, nLength * sizeof( sal_Unicode ) );
287 //-------------------------------------------------------------------
288 // a helper trivial helper function to create a filter buffer in the
289 // format the Win32 API requires,
290 // e.g. "Text\0*.txt\0Doc\0*.doc;*xls\0\0"
291 //-------------------------------------------------------------------
293 rtl::OUString SAL_CALL makeWinFilterBuffer( CFilterContainer& aFilterContainer )
295 // calculate the required buffer size
296 sal_uInt32 reqBuffSize = _getTotalFilterLength( aFilterContainer );
298 // return if there are no filters
299 if ( !reqBuffSize )
300 return OUString( );
302 sal_Unicode* pBuff = new sal_Unicode[reqBuffSize];
304 // initialize the buffer with 0
305 ZeroMemory( pBuff, sizeof( sal_Unicode ) * reqBuffSize );
307 OUString winFilterBuff;
308 CFilterContainer::FILTER_ENTRY_T nextFilter;
309 sal_uInt32 memPos = 0;
311 aFilterContainer.beginEnumFilter( );
313 while( aFilterContainer.getNextFilter( nextFilter ) )
315 _wcsmemcpy(
316 pBuff + memPos,
317 nextFilter.first.getStr( ),
318 nextFilter.first.getLength( ) );
320 memPos += nextFilter.first.getLength( ) + 1;
322 _wcsmemcpy(
323 pBuff + memPos,
324 nextFilter.second.getStr( ),
325 nextFilter.second.getLength( ) );
327 memPos += nextFilter.second.getLength( ) + 1 ;
330 winFilterBuff = OUString( pBuff, reqBuffSize );
332 // remove the allocated buffer
333 delete [] pBuff;
335 return winFilterBuff;