update dev300-m58
[ooovba.git] / fpicker / source / win32 / filepicker / FilterContainer.cxx
blobdbdb632906794ba04b37a8125440133fee939715
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: FilterContainer.cxx,v $
10 * $Revision: 1.7 $
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"
35 #include <stdexcept>
36 #include <osl/diagnose.h>
37 #include "FilterContainer.hxx"
39 #include <utility>
41 #if defined _MSC_VER
42 #pragma warning(push, 1)
43 #endif
44 #include <windows.h>
45 #if defined _MSC_VER
46 #pragma warning(pop)
47 #endif
49 //-------------------------------------------------------------------
50 // namespace directives
51 //-------------------------------------------------------------------
53 using ::rtl::OUString;
55 //-------------------------------------------------------------------------------------
56 // ctor
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
73 sal_Int32 pos = -1;
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;
84 else
86 m_vFilters.push_back( std::make_pair( aName, aFilter ) );
87 m_bIterInitialized = sal_False;
90 return ( pos < 0 ) ? sal_True : sal_False;
93 //-----------------------------------------------------------------------------------------
94 // delete a filter
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 );
104 if ( pos > -1 )
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 //-----------------------------------------------------------------------------------------
123 // clear all entries
124 //-----------------------------------------------------------------------------------------
126 void SAL_CALL CFilterContainer::empty()
128 m_vFilters.clear( );
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 );
145 if ( pos > -1 )
146 theFilter = m_vFilters.at( pos ).second;
148 catch( std::out_of_range& )
150 OSL_ENSURE( sal_False, "Filter not in filter container" );
151 pos = -1;
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" );
172 bRet = sal_False;
175 return bRet;
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 )
195 sal_Int32 i = 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 ) )
201 return i;
204 return -1;
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( ) );
227 if ( bRet )
228 nextFilterEntry = *m_iter++;
229 else
230 m_bIterInitialized = sal_False;
232 return bRet;
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 +
253 // a trailing '\0'
254 //-------------------------------------------------------------------
256 static sal_uInt32 _getLengthFilter( CFilterContainer::FILTER_ENTRY_T aFilterEntry )
258 return (
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 //-------------------------------------------------------------------
284 inline
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
302 if ( !reqBuffSize )
303 return OUString( );
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 ) )
318 _wcsmemcpy(
319 pBuff + memPos,
320 nextFilter.first.getStr( ),
321 nextFilter.first.getLength( ) );
323 memPos += nextFilter.first.getLength( ) + 1;
325 _wcsmemcpy(
326 pBuff + memPos,
327 nextFilter.second.getStr( ),
328 nextFilter.second.getLength( ) );
330 memPos += nextFilter.second.getLength( ) + 1 ;
333 winFilterBuff = OUString( pBuff, reqBuffSize );
335 // remove the allocated buffer
336 delete [] pBuff;
338 return winFilterBuff;