bump product version to 6.1.0.2
[LibreOffice.git] / fpicker / source / win32 / filepicker / FilterContainer.cxx
blob088c4744db05c2620fce7b1b1b978471ab3feb7f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <memory>
23 #include <stdexcept>
24 #include <osl/diagnose.h>
25 #include "FilterContainer.hxx"
27 #include <utility>
29 #if !defined WIN32_LEAN_AND_MEAN
30 # define WIN32_LEAN_AND_MEAN
31 #endif
32 #include <windows.h>
34 CFilterContainer::CFilterContainer( sal_Int32 initSize ) :
35 m_vFilters( initSize ),
36 m_bIterInitialized( false )
40 // add a name/filter pair
42 bool CFilterContainer::addFilter(
43 const OUString& aName, const OUString& aFilter, bool bAllowDuplicates )
45 // check if the filter is already in the container
46 sal_Int32 pos = -1;
48 if ( !bAllowDuplicates )
50 pos = getFilterTagPos( aName );
51 if ( pos < 0 ) // if not there, append
53 m_vFilters.push_back( std::make_pair( aName, aFilter ) );
54 m_bIterInitialized = false;
57 else
59 m_vFilters.push_back( std::make_pair( aName, aFilter ) );
60 m_bIterInitialized = false;
63 return pos < 0;
66 // delete a filter
67 // Precondition: the container is not empty
68 // there is a filter identified by the given name
70 bool CFilterContainer::delFilter( const OUString& aName )
72 OSL_ASSERT( !m_vFilters.empty() );
74 sal_Int32 pos = getFilterTagPos( aName );
75 if ( pos > -1 )
77 m_vFilters.erase( m_vFilters.begin() + pos );
78 m_bIterInitialized = false;
81 return pos > -1;
84 // return the number of filters currently in the container
86 sal_Int32 CFilterContainer::numFilter( )
88 return m_vFilters.size( );
91 // clear all entries
93 void CFilterContainer::empty()
95 m_vFilters.clear( );
98 // get a filter by name
99 // Precondition: the container is not empty
100 // there is a filter identified by the name
102 bool CFilterContainer::getFilter( const OUString& aName, OUString& theFilter ) const
104 OSL_PRECOND( !m_vFilters.empty() , "Empty filter container" );
106 sal_Int32 pos = getFilterTagPos( aName );
110 if ( pos > -1 )
111 theFilter = m_vFilters.at( pos ).second;
113 catch( std::out_of_range& )
115 OSL_FAIL( "Filter not in filter container" );
116 pos = -1;
119 return pos > -1;
122 bool CFilterContainer::getFilter( sal_Int32 aIndex, OUString& theFilter ) const
124 bool bRet = true;
128 theFilter = m_vFilters.at( aIndex ).first;
130 catch( std::out_of_range& )
132 OSL_FAIL( "Filter index out of range" );
133 bRet = false;
136 return bRet;
139 sal_Int32 CFilterContainer::getFilterPos( const OUString& aName ) const
141 return getFilterTagPos( aName );
144 // returns the index of the filter identified by name
146 sal_Int32 CFilterContainer::getFilterTagPos( const OUString& aName ) const
148 if ( !m_vFilters.empty() )
150 sal_Int32 i = 0;
151 FILTER_VECTOR_T::const_iterator iter;
152 FILTER_VECTOR_T::const_iterator iter_end = m_vFilters.end( );
154 for ( iter = m_vFilters.begin( ); iter != iter_end; ++iter, ++i )
155 if ( ( *iter ).first.equalsIgnoreAsciiCase( aName ) )
156 return i;
159 return -1;
162 // starts enumerating the filter in the container
164 void CFilterContainer::beginEnumFilter( )
166 m_iter = m_vFilters.begin( );
167 m_bIterInitialized = true;
170 // returns true if another filter has been retrieved
172 bool CFilterContainer::getNextFilter( FILTER_ENTRY_T& nextFilterEntry )
174 OSL_ASSERT( m_bIterInitialized );
176 bool bRet = ( m_iter != m_vFilters.end( ) );
178 if ( bRet )
179 nextFilterEntry = *m_iter++;
180 else
181 m_bIterInitialized = false;
183 return bRet;
186 void CFilterContainer::setCurrentFilter( const OUString& aName )
188 m_sCurrentFilter = aName;
191 OUString CFilterContainer::getCurrentFilter() const
193 return m_sCurrentFilter;
196 // calculates the length of a '\0' separated filter, that means
197 // length of the name + '\0' + length of the filter string +
198 // a trailing '\0'
200 static sal_uInt32 getLengthFilter( CFilterContainer::FILTER_ENTRY_T aFilterEntry )
202 return (
203 aFilterEntry.first.getLength( ) + 1 +
204 aFilterEntry.second.getLength( ) + 1 );
207 // calculates the length of all filters currently in the container
209 static sal_uInt32 getTotalFilterLength( CFilterContainer& aFilterContainer )
211 CFilterContainer::FILTER_ENTRY_T nextFilter;
213 aFilterContainer.beginEnumFilter( );
215 sal_uInt32 totalLength = 0;
216 while( aFilterContainer.getNextFilter( nextFilter ) )
217 totalLength += getLengthFilter( nextFilter );
219 return ( totalLength > 0 ) ? totalLength + 1 : totalLength;
222 inline
223 void wcsmemcpy( sal_Unicode* pDest, const sal_Unicode* pSrc, sal_uInt32 nLength )
225 memcpy( pDest, pSrc, nLength * sizeof( sal_Unicode ) );
228 // a helper trivial helper function to create a filter buffer in the
229 // format the Win32 API requires,
230 // e.g. "Text\0*.txt\0Doc\0*.doc;*xls\0\0"
232 OUString makeWinFilterBuffer( CFilterContainer& aFilterContainer )
234 // calculate the required buffer size
235 sal_uInt32 reqBuffSize = getTotalFilterLength( aFilterContainer );
237 // return if there are no filters
238 if ( !reqBuffSize )
239 return OUString( );
241 auto pBuff = std::unique_ptr<sal_Unicode[]>(new sal_Unicode[reqBuffSize]);
243 // initialize the buffer with 0
244 ZeroMemory( pBuff.get(), sizeof( sal_Unicode ) * reqBuffSize );
246 OUString winFilterBuff;
247 CFilterContainer::FILTER_ENTRY_T nextFilter;
248 sal_uInt32 memPos = 0;
250 aFilterContainer.beginEnumFilter( );
252 while( aFilterContainer.getNextFilter( nextFilter ) )
254 wcsmemcpy(
255 pBuff.get() + memPos,
256 nextFilter.first.getStr( ),
257 nextFilter.first.getLength( ) );
259 memPos += nextFilter.first.getLength( ) + 1;
261 wcsmemcpy(
262 pBuff.get() + memPos,
263 nextFilter.second.getStr( ),
264 nextFilter.second.getLength( ) );
266 memPos += nextFilter.second.getLength( ) + 1 ;
269 winFilterBuff = OUString( pBuff.get(), reqBuffSize );
271 return winFilterBuff;
274 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */