merge the formfield patch from ooo-build
[ooovba.git] / fpicker / source / win32 / misc / WinImplHelper.cxx
blob8d41da1fb159ce513db48dceb6455974d9360084
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: WinImplHelper.cxx,v $
10 * $Revision: 1.12 $
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"
34 //------------------------------------------------------------------------
35 // includes
36 //------------------------------------------------------------------------
37 #include <osl/diagnose.h>
38 #include <rtl/ustrbuf.hxx>
39 #include "AutoBuffer.hxx"
40 #include "WinImplHelper.hxx"
41 #include <com/sun/star/uno/Sequence.hxx>
43 //------------------------------------------------------------
44 // namespace directives
45 //------------------------------------------------------------
47 using rtl::OUString;
48 using rtl::OUStringBuffer;
49 using ::com::sun::star::lang::IllegalArgumentException;
50 using ::com::sun::star::uno::Reference;
51 using ::com::sun::star::uno::XInterface;
52 using ::com::sun::star::uno::Any;
53 using ::com::sun::star::uno::Sequence;
55 //------------------------------------------------------------
57 //------------------------------------------------------------
59 const rtl::OUString TILDE = OUString::createFromAscii( "~" );
60 const sal_Unicode TILDE_SIGN = L'~';
61 const rtl::OUString AMPERSAND = OUString::createFromAscii( "&" );
62 const sal_Unicode AMPERSAND_SIGN = L'&';
64 //------------------------------------------------------------
65 // OS NAME Platform Major Minor
66 //
67 // Windows NT 3.51 VER_PLATFORM_WIN32_NT 3 51
68 // Windows NT 4.0 VER_PLATFORM_WIN32_NT 4 0
69 // Windows 2000 VER_PLATFORM_WIN32_NT 5 0
70 // Windows XP VER_PLATFORM_WIN32_NT 5 1
71 // Windows Vista VER_PLATFORM_WIN32_NT 6 0
72 // Windows 7 VER_PLATFORM_WIN32_NT 6 1
73 // Windows 95 VER_PLATFORM_WIN32_WINDOWS 4 0
74 // Windows 98 VER_PLATFORM_WIN32_WINDOWS 4 10
75 // Windows ME VER_PLATFORM_WIN32_WINDOWS 4 90
76 //------------------------------------------------------------
78 bool SAL_CALL IsWindowsVersion(unsigned int PlatformId, unsigned int MajorVersion, int MinorVersion = -1)
80 OSVERSIONINFO osvi;
81 osvi.dwOSVersionInfoSize = sizeof(osvi);
83 if(!GetVersionEx(&osvi))
84 return false;
86 bool bRet = (PlatformId == osvi.dwPlatformId) &&
87 (MajorVersion == osvi.dwMajorVersion);
89 if (MinorVersion > -1)
90 bRet = bRet &&
91 (sal::static_int_cast< unsigned int >(MinorVersion) ==
92 osvi.dwMinorVersion);
94 return bRet;
97 //------------------------------------------------------------
98 // determine if we are running under Vista or newer OS
99 //------------------------------------------------------------
101 bool SAL_CALL IsWindowsVistaOrNewer()
103 OSVERSIONINFO osvi;
104 osvi.dwOSVersionInfoSize = sizeof(osvi);
106 if(!GetVersionEx(&osvi))
107 return false;
109 bool bRet = (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId) &&
110 (osvi.dwMajorVersion >= 6);
112 bRet = bRet &&
113 (osvi.dwMinorVersion >=
114 sal::static_int_cast< unsigned int >(0));
116 return bRet;
119 //------------------------------------------------------------
120 // determine if we are running under Windows 7
121 //------------------------------------------------------------
123 bool SAL_CALL IsWindows7()
125 return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 6, 1);
128 //------------------------------------------------------------
129 // determine if we are running under Windows Vista
130 //------------------------------------------------------------
132 bool SAL_CALL IsWindowsVista()
134 return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 6, 0);
137 //------------------------------------------------------------
138 // determine if we are running under Windows XP
139 //------------------------------------------------------------
141 bool SAL_CALL IsWindowsXP()
143 return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 5, 1);
146 //------------------------------------------------------------
147 // determine if we are running under Windows 2000
148 //------------------------------------------------------------
150 bool SAL_CALL IsWindows2000()
152 return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 5, 0);
155 //------------------------------------------------------------
157 //------------------------------------------------------------
159 bool SAL_CALL IsWindows98()
161 return IsWindowsVersion(VER_PLATFORM_WIN32_WINDOWS, 4, 10);
164 //------------------------------------------------------------
166 //------------------------------------------------------------
168 bool SAL_CALL IsWindowsME()
170 return IsWindowsVersion(VER_PLATFORM_WIN32_WINDOWS, 4, 90);
173 //------------------------------------------------------------
175 //------------------------------------------------------------
177 bool SAL_CALL IsWindows2000Platform()
179 // POST: return true if we are at least on Windows 2000
181 // WRONG!: return IsWindowsVersion(VER_PLATFORM_WIN32_NT, 5);
183 OSVERSIONINFO osvi;
184 ZeroMemory(&osvi, sizeof(osvi));
185 osvi.dwOSVersionInfoSize = sizeof(osvi);
186 GetVersionEx(&osvi);
187 if ( osvi.dwMajorVersion >= 5 )
189 return true;
191 return false;
194 //------------------------------------------------------------
196 //------------------------------------------------------------
198 void SAL_CALL ListboxAddString( HWND hwnd, const OUString& aString )
200 LRESULT rc = SendMessageW(
201 hwnd, CB_ADDSTRING, 0, reinterpret_cast< LPARAM >(aString.getStr( )) );
202 (void) rc; // avoid warning
203 OSL_ASSERT( (CB_ERR != rc) && (CB_ERRSPACE != rc) );
206 //------------------------------------------------------------
208 //------------------------------------------------------------
210 OUString SAL_CALL ListboxGetString( HWND hwnd, sal_Int32 aPosition )
212 OSL_ASSERT( IsWindow( hwnd ) );
214 OUString aString;
216 LRESULT lItem =
217 SendMessageW( hwnd, CB_GETLBTEXTLEN, aPosition, 0 );
219 if ( (CB_ERR != lItem) && (lItem > 0) )
221 // message returns the len of a combobox item
222 // without trailing '\0' that's why += 1
223 lItem++;
225 CAutoUnicodeBuffer aBuff( lItem );
227 LRESULT lRet =
228 SendMessageW(
229 hwnd, CB_GETLBTEXT, aPosition,
230 reinterpret_cast<LPARAM>(&aBuff) );
232 OSL_ASSERT( lRet != CB_ERR );
234 if ( CB_ERR != lRet )
235 aString = OUString( aBuff, lRet );
238 return aString;
241 //------------------------------------------------------------
243 //------------------------------------------------------------
245 void SAL_CALL ListboxAddItem( HWND hwnd, const Any& aItem, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
246 throw( IllegalArgumentException )
248 OSL_ASSERT( IsWindow( hwnd ) );
250 if ( !aItem.hasValue( ) ||
251 aItem.getValueType( ) != getCppuType((OUString*)0) )
252 throw IllegalArgumentException(
253 OUString::createFromAscii( "invalid value type or any has no value" ),
254 rXInterface,
255 aArgPos );
257 OUString cbItem;
258 aItem >>= cbItem;
260 ListboxAddString( hwnd, cbItem );
263 //------------------------------------------------------------
265 //------------------------------------------------------------
267 void SAL_CALL ListboxAddItems( HWND hwnd, const Any& aItemList, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
268 throw( IllegalArgumentException )
270 OSL_ASSERT( IsWindow( hwnd ) );
272 if ( !aItemList.hasValue( ) ||
273 aItemList.getValueType( ) != getCppuType((Sequence<OUString>*)0) )
274 throw IllegalArgumentException(
275 OUString::createFromAscii( "invalid value type or any has no value" ),
276 rXInterface,
277 aArgPos );
279 Sequence< OUString > aStringList;
280 aItemList >>= aStringList;
282 sal_Int32 nItemCount = aStringList.getLength( );
283 for( sal_Int32 i = 0; i < nItemCount; i++ )
285 ListboxAddString( hwnd, aStringList[i] );
289 //------------------------------------------------------------
291 //------------------------------------------------------------
293 void SAL_CALL ListboxDeleteItem( HWND hwnd, const Any& aPosition, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
294 throw( IllegalArgumentException )
296 OSL_ASSERT( IsWindow( hwnd ) );
298 if ( !aPosition.hasValue( ) ||
299 ( (aPosition.getValueType( ) != getCppuType((sal_Int32*)0)) &&
300 (aPosition.getValueType( ) != getCppuType((sal_Int16*)0)) &&
301 (aPosition.getValueType( ) != getCppuType((sal_Int8*)0)) ) )
302 throw IllegalArgumentException(
303 OUString::createFromAscii( "invalid value type or any has no value" ),
304 rXInterface,
305 aArgPos );
307 sal_Int32 nPos;
308 aPosition >>= nPos;
310 LRESULT lRet = SendMessage( hwnd, CB_DELETESTRING, nPos, 0 );
312 // if the return value is CB_ERR the given
313 // index was not correct
314 if ( CB_ERR == lRet )
315 throw IllegalArgumentException(
316 OUString::createFromAscii( "inavlid item position" ),
317 rXInterface,
318 aArgPos );
321 //------------------------------------------------------------
323 //------------------------------------------------------------
325 void SAL_CALL ListboxDeleteItems( HWND hwnd, const Any&, const Reference< XInterface >&, sal_Int16 )
326 throw( IllegalArgumentException )
328 OSL_ASSERT( IsWindow( hwnd ) );
330 LRESULT lRet = 0;
334 // the return value on success is the number
335 // of remaining elements in the listbox
336 lRet = SendMessageW( hwnd, CB_DELETESTRING, 0, 0 );
338 while ( (lRet != CB_ERR) && (lRet > 0) );
341 //------------------------------------------------------------
343 //------------------------------------------------------------
345 void SAL_CALL ListboxSetSelectedItem( HWND hwnd, const Any& aPosition, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
346 throw( IllegalArgumentException )
348 OSL_ASSERT( IsWindow( hwnd ) );
350 if ( !aPosition.hasValue( ) ||
351 ( (aPosition.getValueType( ) != getCppuType((sal_Int32*)0)) &&
352 (aPosition.getValueType( ) != getCppuType((sal_Int16*)0)) &&
353 (aPosition.getValueType( ) != getCppuType((sal_Int8*)0)) ) )
354 throw IllegalArgumentException(
355 OUString::createFromAscii( "invalid value type or any has no value" ),
356 rXInterface,
357 aArgPos );
359 sal_Int32 nPos;
360 aPosition >>= nPos;
362 if ( nPos < -1 )
363 throw IllegalArgumentException(
364 OUString::createFromAscii("invalid index"),
365 rXInterface,
366 aArgPos );
368 LRESULT lRet = SendMessageW( hwnd, CB_SETCURSEL, nPos, 0 );
370 if ( (CB_ERR == lRet) && (-1 != nPos) )
371 throw IllegalArgumentException(
372 OUString::createFromAscii("invalid index"),
373 rXInterface,
374 aArgPos );
377 //------------------------------------------------------------
379 //------------------------------------------------------------
381 Any SAL_CALL ListboxGetItems( HWND hwnd )
383 OSL_ASSERT( IsWindow( hwnd ) );
385 LRESULT nItemCount = SendMessageW( hwnd, CB_GETCOUNT, 0, 0 );
387 Sequence< OUString > aItemList;
389 if ( CB_ERR != nItemCount )
391 aItemList.realloc( nItemCount );
393 for ( sal_Int32 i = 0; i < nItemCount; i++ )
395 aItemList[i] = ListboxGetString( hwnd, i );
399 Any aAny;
400 aAny <<= aItemList;
402 return aAny;
405 //------------------------------------------------------------
407 //------------------------------------------------------------
409 Any SAL_CALL ListboxGetSelectedItem( HWND hwnd )
411 OSL_ASSERT( IsWindow( hwnd ) );
413 LRESULT idxItem = SendMessageW( hwnd, CB_GETCURSEL, 0, 0 );
415 Any aAny;
416 aAny <<= ListboxGetString( hwnd, idxItem );
418 return aAny;
421 //------------------------------------------------------------
423 //------------------------------------------------------------
425 Any SAL_CALL ListboxGetSelectedItemIndex( HWND hwnd )
427 OSL_ASSERT( IsWindow( hwnd ) );
429 LRESULT idxItem = SendMessageW( hwnd, CB_GETCURSEL, 0, 0 );
431 Any aAny;
432 aAny <<= static_cast< sal_Int32 >( idxItem );
434 return aAny;
437 //------------------------------------------------------------
439 //------------------------------------------------------------
441 Any SAL_CALL CheckboxGetState( HWND hwnd )
443 OSL_ASSERT( IsWindow( hwnd ) );
445 LRESULT lChkState = SendMessageW( hwnd, BM_GETCHECK, 0, 0 );
446 sal_Bool bChkState = (lChkState == BST_CHECKED) ? sal_True : sal_False;
447 Any aAny;
448 aAny.setValue( &bChkState, getCppuType((sal_Bool*)0) );
449 return aAny;
452 //------------------------------------------------------------
454 //------------------------------------------------------------
456 void SAL_CALL CheckboxSetState(
457 HWND hwnd, const ::com::sun::star::uno::Any& aState, const Reference< XInterface >& rXInterface, sal_Int16 aArgPos )
458 throw( IllegalArgumentException )
460 OSL_ASSERT( IsWindow( hwnd ) );
462 if ( !aState.hasValue( ) ||
463 aState.getValueType( ) != getCppuType((sal_Bool*)0) )
464 throw IllegalArgumentException(
465 OUString::createFromAscii( "invalid value type or any has no value" ),
466 rXInterface,
467 aArgPos );
469 sal_Bool bCheckState = *reinterpret_cast< const sal_Bool* >( aState.getValue( ) );
470 WPARAM wParam = bCheckState ? BST_CHECKED : BST_UNCHECKED;
471 SendMessageW( hwnd, BM_SETCHECK, wParam, 0 );
474 //------------------------------------------------------------
476 //------------------------------------------------------------
478 sal_uInt32 SAL_CALL _wcslenex( const sal_Unicode* pStr )
480 if ( !pStr )
481 return 0;
483 const sal_Unicode* pTemp = pStr;
484 sal_uInt32 strLen = 0;
485 while( *pTemp || *(pTemp + 1) )
487 pTemp++;
488 strLen++;
491 return strLen;
494 //------------------------------------------------------------
496 //------------------------------------------------------------
498 void Replace( const OUString& aLabel, sal_Unicode OldChar, sal_Unicode NewChar, OUStringBuffer& aBuffer )
500 OSL_ASSERT( aLabel.getLength( ) );
501 OSL_ASSERT( aBuffer.getCapacity( ) >= (aLabel.getLength( )) );
503 sal_Int32 i = 0;
504 const sal_Unicode* pCurrent = aLabel.getStr( );
505 const sal_Unicode* pNext = aLabel.getStr( ) + 1;
506 const sal_Unicode* pEnd = aLabel.getStr( ) + aLabel.getLength( );
508 while( pCurrent < pEnd )
510 OSL_ASSERT( pNext <= pEnd );
511 OSL_ASSERT( (i >= 0) && (i < aBuffer.getCapacity( )) );
513 if ( OldChar == *pCurrent )
515 if ( OldChar == *pNext )
517 // two OldChars in line will
518 // be replaced by one
519 // e.g. ~~ -> ~
520 aBuffer.insert( i, *pCurrent );
522 // skip the next one
523 pCurrent++;
524 pNext++;
526 else
528 // one OldChar will be replace
529 // by NexChar
530 aBuffer.insert( i, NewChar );
533 else if ( *pCurrent == NewChar )
535 // a NewChar will be replaced by
536 // two NewChars
537 // e.g. & -> &&
538 aBuffer.insert( i++, *pCurrent );
539 aBuffer.insert( i, *pCurrent );
541 else
543 aBuffer.insert( i, *pCurrent );
546 pCurrent++;
547 pNext++;
548 i++;
552 //------------------------------------------------------------
553 // converts a soffice label to a windows label
554 // the following rules for character replacements
555 // will be done:
556 // '~' -> '&'
557 // '~~' -> '~'
558 // '&' -> '&&'
559 //------------------------------------------------------------
561 OUString SOfficeToWindowsLabel( const rtl::OUString& aSOLabel )
563 OUString aWinLabel = aSOLabel;
565 if ( (aWinLabel.indexOf( TILDE ) > -1) || (aWinLabel.indexOf( AMPERSAND ) > -1) )
567 sal_Int32 nStrLen = aWinLabel.getLength( );
569 // in the worst case the new string is
570 // doubled in length, maybe some waste
571 // of memory but how long is a label
572 // normaly(?)
573 rtl::OUStringBuffer aBuffer( nStrLen * 2 );
575 Replace( aWinLabel, TILDE_SIGN, AMPERSAND_SIGN, aBuffer );
577 aWinLabel = aBuffer.makeStringAndClear( );
580 return aWinLabel;
583 //------------------------------------------------------------
584 // converts a windows label to a soffice label
585 // the following rules for character replacements
586 // will be done:
587 // '&' -> '~'
588 // '&&' -> '&'
589 // '~' -> '~~'
590 //------------------------------------------------------------
592 OUString WindowsToSOfficeLabel( const rtl::OUString& aWinLabel )
594 OUString aSOLabel = aWinLabel;
596 if ( (aSOLabel.indexOf( TILDE ) > -1) || (aSOLabel.indexOf( AMPERSAND ) > -1) )
598 sal_Int32 nStrLen = aSOLabel.getLength( );
600 // in the worst case the new string is
601 // doubled in length, maybe some waste
602 // of memory but how long is a label
603 // normaly(?)
604 rtl::OUStringBuffer aBuffer( nStrLen * 2 );
606 Replace( aSOLabel, AMPERSAND_SIGN, TILDE_SIGN, aBuffer );
608 aSOLabel = aBuffer.makeStringAndClear( );
611 return aSOLabel;