calc: on editing invalidation of view with different zoom is wrong
[LibreOffice.git] / fpicker / source / win32 / FilterContainer.cxx
blob67ccd6353ba38e2e0b85834521699e9a42459d99
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 <algorithm>
23 #include <memory>
24 #include <stdexcept>
25 #include <osl/diagnose.h>
26 #include "FilterContainer.hxx"
28 #include <utility>
30 #if !defined WIN32_LEAN_AND_MEAN
31 # define WIN32_LEAN_AND_MEAN
32 #endif
33 #include <windows.h>
35 CFilterContainer::CFilterContainer( sal_Int32 initSize ) :
36 m_vFilters( initSize ),
37 m_bIterInitialized( false )
41 // add a name/filter pair
43 bool CFilterContainer::addFilter(
44 const OUString& aName, const OUString& aFilter, bool bAllowDuplicates )
46 // check if the filter is already in the container
47 sal_Int32 pos = -1;
49 if ( !bAllowDuplicates )
51 pos = getFilterTagPos( aName );
52 if ( pos < 0 ) // if not there, append
54 m_vFilters.push_back( std::make_pair( aName, aFilter ) );
55 m_bIterInitialized = false;
58 else
60 m_vFilters.push_back( std::make_pair( aName, aFilter ) );
61 m_bIterInitialized = false;
64 return pos < 0;
67 // delete a filter
68 // Precondition: the container is not empty
69 // there is a filter identified by the given name
71 bool CFilterContainer::delFilter( const OUString& aName )
73 OSL_ASSERT( !m_vFilters.empty() );
75 sal_Int32 pos = getFilterTagPos( aName );
76 if ( pos > -1 )
78 m_vFilters.erase( m_vFilters.begin() + pos );
79 m_bIterInitialized = false;
82 return pos > -1;
85 // return the number of filters currently in the container
87 sal_Int32 CFilterContainer::numFilter( )
89 return m_vFilters.size( );
92 // clear all entries
94 void CFilterContainer::empty()
96 m_vFilters.clear( );
99 // get a filter by name
100 // Precondition: the container is not empty
101 // there is a filter identified by the name
103 bool CFilterContainer::getFilterByName(const OUString& aName, OUString& theFilter) const
105 OSL_PRECOND( !m_vFilters.empty() , "Empty filter container" );
106 return getFilterByIndex(getFilterTagPos(aName), theFilter);
109 bool CFilterContainer::getFilterByIndex(sal_Int32 aIndex, OUString& theFilter) const
111 bool bRet = true;
115 theFilter = m_vFilters.at(aIndex).second;
117 catch (std::out_of_range&)
119 OSL_FAIL("Filter index out of range");
120 bRet = false;
123 return bRet;
126 bool CFilterContainer::getFilterNameByIndex(sal_Int32 aIndex, OUString& theName) const
128 bool bRet = true;
132 theName = m_vFilters.at(aIndex).first;
134 catch( std::out_of_range& )
136 OSL_FAIL( "Filter index out of range" );
137 bRet = false;
140 return bRet;
143 sal_Int32 CFilterContainer::getFilterPos( const OUString& aName ) const
145 return getFilterTagPos( aName );
148 // returns the index of the filter identified by name
150 sal_Int32 CFilterContainer::getFilterTagPos( const OUString& aName ) const
152 if ( !m_vFilters.empty() )
154 FILTER_VECTOR_T::const_iterator iter = std::find_if(m_vFilters.begin(), m_vFilters.end(),
155 [&aName](const FILTER_ENTRY_T& rFilter) { return rFilter.first.equalsIgnoreAsciiCase(aName); });
156 if (iter != m_vFilters.end())
157 return std::distance(m_vFilters.begin(), iter);
160 return -1;
163 // starts enumerating the filter in the container
165 void CFilterContainer::beginEnumFilter( )
167 m_iter = m_vFilters.begin( );
168 m_bIterInitialized = true;
171 // returns true if another filter has been retrieved
173 bool CFilterContainer::getNextFilter( FILTER_ENTRY_T& nextFilterEntry )
175 OSL_ASSERT( m_bIterInitialized );
177 bool bRet = ( m_iter != m_vFilters.end( ) );
179 if ( bRet )
180 nextFilterEntry = *m_iter++;
181 else
182 m_bIterInitialized = false;
184 return bRet;
187 void CFilterContainer::setCurrentFilter( const OUString& aName )
189 m_sCurrentFilter = aName;
192 OUString CFilterContainer::getCurrentFilter() const
194 return m_sCurrentFilter;
197 // calculates the length of a '\0' separated filter, that means
198 // length of the name + '\0' + length of the filter string +
199 // a trailing '\0'
201 static sal_uInt32 getLengthFilter( CFilterContainer::FILTER_ENTRY_T aFilterEntry )
203 return (
204 aFilterEntry.first.getLength( ) + 1 +
205 aFilterEntry.second.getLength( ) + 1 );
208 // calculates the length of all filters currently in the container
210 static sal_uInt32 getTotalFilterLength( CFilterContainer& aFilterContainer )
212 CFilterContainer::FILTER_ENTRY_T nextFilter;
214 aFilterContainer.beginEnumFilter( );
216 sal_uInt32 totalLength = 0;
217 while( aFilterContainer.getNextFilter( nextFilter ) )
218 totalLength += getLengthFilter( nextFilter );
220 return ( totalLength > 0 ) ? totalLength + 1 : totalLength;
223 static
224 void wcsmemcpy( sal_Unicode* pDest, const sal_Unicode* pSrc, sal_uInt32 nLength )
226 memcpy( pDest, pSrc, nLength * sizeof( sal_Unicode ) );
229 // a helper trivial helper function to create a filter buffer in the
230 // format the Win32 API requires,
231 // e.g. "Text\0*.txt\0Doc\0*.doc;*xls\0\0"
233 OUString makeWinFilterBuffer( CFilterContainer& aFilterContainer )
235 // calculate the required buffer size
236 sal_uInt32 reqBuffSize = getTotalFilterLength( aFilterContainer );
238 // return if there are no filters
239 if ( !reqBuffSize )
240 return OUString( );
242 auto pBuff = std::make_unique<sal_Unicode[]>(reqBuffSize);
244 // initialize the buffer with 0
245 ZeroMemory( pBuff.get(), sizeof( sal_Unicode ) * reqBuffSize );
247 OUString winFilterBuff;
248 CFilterContainer::FILTER_ENTRY_T nextFilter;
249 sal_uInt32 memPos = 0;
251 aFilterContainer.beginEnumFilter( );
253 while( aFilterContainer.getNextFilter( nextFilter ) )
255 wcsmemcpy(
256 pBuff.get() + memPos,
257 nextFilter.first.getStr( ),
258 nextFilter.first.getLength( ) );
260 memPos += nextFilter.first.getLength( ) + 1;
262 wcsmemcpy(
263 pBuff.get() + memPos,
264 nextFilter.second.getStr( ),
265 nextFilter.second.getLength( ) );
267 memPos += nextFilter.second.getLength( ) + 1 ;
270 winFilterBuff = OUString( pBuff.get(), reqBuffSize );
272 return winFilterBuff;
275 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */