1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 #include "proplist.hxx"
34 #include <rtl/ustrbuf.hxx>
35 #include <toolkit/dllapi.h>
36 #include <com/sun/star/awt/WindowAttribute.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/awt/XVclWindowPeer.hpp>
39 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
40 #include <tools/debug.hxx>
44 #if TEST_LAYOUT && !defined( DBG_UTIL )
46 #define DBG_ERROR OSL_TRACE
48 #define DBG_ERROR1 OSL_TRACE
50 #define DBG_ERROR2 OSL_TRACE
51 #endif /* TEST_LAYOUT && !DBG_UTIL */
56 using namespace com::sun::star
;
59 using rtl::OUStringBuffer
;
64 bool TOOLKIT_DLLPUBLIC
65 canHandleProps( const uno::Reference
< uno::XInterface
> &xPeer
)
67 uno::Reference
< beans::XPropertySet
> xPropSet( xPeer
, uno::UNO_QUERY
);
70 uno::Reference
< beans::XPropertySetInfo
> xInfo( xPeer
, uno::UNO_QUERY
);
71 uno::Reference
< awt::XVclWindowPeer
> xVclPeer( xPeer
, uno::UNO_QUERY
);
72 return xInfo
.is() && xVclPeer
.is();
75 uno::Reference
< beans::XPropertySetInfo
> TOOLKIT_DLLPUBLIC
77 const uno::Reference
< uno::XInterface
> &xPeer
)
79 uno::Reference
< beans::XPropertySetInfo
> xInfo( xPeer
, uno::UNO_QUERY
);
82 uno::Reference
< beans::XPropertySet
> xPropSet( xPeer
, uno::UNO_QUERY
);
84 xInfo
= xPropSet
->getPropertySetInfo();
89 void TOOLKIT_DLLPUBLIC
90 setProperty( const uno::Reference
< uno::XInterface
> &xPeer
,
91 const OUString
&rName
, uno::Any aValue
)
93 uno::Reference
< awt::XVclWindowPeer
> xVclPeer( xPeer
, uno::UNO_QUERY
);
95 xVclPeer
->setProperty( rName
, aValue
);
98 uno::Reference
< beans::XPropertySet
> xPropSet( xPeer
, uno::UNO_QUERY
);
99 xPropSet
->setPropertyValue( rName
, aValue
);
103 uno::Any TOOLKIT_DLLPUBLIC
104 getProperty( const uno::Reference
< uno::XInterface
> &xPeer
,
105 const OUString
&rName
)
107 uno::Reference
< awt::XVclWindowPeer
> xVclPeer( xPeer
, uno::UNO_QUERY
);
109 return xVclPeer
->getProperty( rName
);
111 uno::Reference
< beans::XPropertySet
> xPropSet( xPeer
, uno::UNO_QUERY
);
112 return xPropSet
->getPropertyValue( rName
);
115 } // namespace prophlp
118 /* Given a string and a type, it converts the string to the type, and returns
119 it encapsulated in Any. */
120 uno::Any
anyFromString( OUString
const& value
, uno::Type
const& type
)
122 sal_Int16 radix
= 10;
123 OUString intval
= value
;
124 if ( value
.getLength() > 2 && value
[0] == '0' && value
[1] == 'x' )
125 intval
= value
.copy( 2 ), radix
= 16;
126 else if ( value
.getLength() > 1 && value
[0] == '#' )
127 intval
= value
.copy( 1 ), radix
= 16;
128 switch ( type
.getTypeClass() )
130 case uno::TypeClass_CHAR
:
131 return uno::makeAny( value
.toChar() );
132 case uno::TypeClass_BOOLEAN
:
133 if ( value
== OUString( RTL_CONSTASCII_USTRINGPARAM( "true" ) ) )
134 return uno::makeAny( true );
135 else if ( value
== OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) ) )
136 return uno::makeAny( false );
137 break; // ends switch, throws exception
138 case uno::TypeClass_BYTE
:
139 return uno::makeAny( ( sal_uInt8
) intval
.toInt32( radix
) );
140 case uno::TypeClass_SHORT
:
141 return uno::makeAny( ( sal_Int16
) intval
.toInt32( radix
) );
142 case uno::TypeClass_UNSIGNED_SHORT
:
143 return uno::makeAny( ( sal_uInt16
) intval
.toInt32( radix
) );
144 case uno::TypeClass_ENUM
:
145 return uno::makeAny( ( sal_Int16
) intval
.toInt32( radix
) );
146 case uno::TypeClass_LONG
:
147 return uno::makeAny( ( sal_Int32
) intval
.toInt32( radix
) );
148 case uno::TypeClass_UNSIGNED_LONG
:
149 return uno::makeAny( ( sal_uInt32
) intval
.toInt32( radix
) );
150 case uno::TypeClass_HYPER
:
151 return uno::makeAny( ( sal_Int64
) intval
.toInt64( radix
) );
152 case uno::TypeClass_UNSIGNED_HYPER
:
153 return uno::makeAny( ( sal_uInt16
) intval
.toInt64( radix
) );
154 case uno::TypeClass_FLOAT
:
155 return uno::makeAny( value
.toFloat() );
156 case uno::TypeClass_DOUBLE
:
157 return uno::makeAny( value
.toDouble() );
158 case uno::TypeClass_STRING
:
159 return uno::makeAny( value
);
160 case uno::TypeClass_CONSTANT
:
161 return uno::makeAny( intval
.toInt32( radix
) );
162 case uno::TypeClass_INTERFACE
:
163 return uno::makeAny( loadGraphic( OUSTRING_CSTR( value
) ) );
164 case uno::TypeClass_SEQUENCE
:
167 bool escaped
= false, first
= true;
168 OUString item
, token
;
169 std::list
< OUString
> values
;
172 token
= value
.getToken( 0, ':', i
);
174 if ( !token
.getLength() && !escaped
)
177 item
+= OUString( ':' );
187 values
.push_back( item
);
193 if ( item
.getLength() )
194 values
.push_back( item
);
196 uno::Sequence
< OUString
> seq( values
.size() );
198 for ( std::list
< OUString
>::const_iterator it
= values
.begin();
199 it
!= values
.end(); it
++, i
++ )
202 return uno::makeAny( seq
);
206 DBG_ERROR1( "ERROR: unknown property type of value: `%s'\n", OUSTRING_CSTR( value
) );
209 throw uno::RuntimeException();
212 /* Converts the XML naming scheme to UNO's, for legacy compatibility
213 (so, ergo, "one-two-three-four" -> "OneTwoThreeFour"). */
214 static OUString
toUnoNaming ( OUString
const &string
)
216 OUStringBuffer
buffer( string
.getLength() );
217 sal_Unicode
*str
= string
.pData
->buffer
;
218 bool capitalize
= true;
220 for ( int i
= 0; i
< string
.getLength(); i
++ )
222 if ( i
== 0 && str
[0] == '_' )
223 /* Skip translate-me prefix. */
229 if ( capitalize
&& str
[i
] >= 'a' && str
[i
] <= 'z' )
230 buffer
.append( (sal_Unicode
) ( str
[i
] - 'a' + 'A' ) );
232 buffer
.append( (sal_Unicode
) str
[i
] );
237 return buffer
.makeStringAndClear();
241 * convert incoming XML style property names, to AWT style property names.
242 * convert the values based on introspection information.
243 * apply to either an XPropertySet or an XPropertySetInfo | XVclWindowPeer
247 setProperties( uno::Reference
< uno::XInterface
> const& xPeer
,
248 PropList
const& rProps
)
250 if ( !prophlp::canHandleProps( xPeer
) )
252 DBG_ERROR( "Error: setProperties - bad handle ignoring props:\n" );
253 for ( PropList::const_iterator it
= rProps
.begin(); it
!= rProps
.end();
256 DBG_ERROR2( "%s=%s\n", OUSTRING_CSTR( it
->first
), OUSTRING_CSTR( it
->second
) );
261 for ( PropList::const_iterator it
= rProps
.begin(); it
!= rProps
.end();
263 setProperty( xPeer
, it
->first
, it
->second
);
267 setProperty( uno::Reference
< uno::XInterface
> const& xPeer
,
268 OUString
const& attr
, OUString
const& value
)
270 OUString unoAttr
= toUnoNaming( attr
);
272 OSL_TRACE( "setting %s=%s", OUSTRING_CSTR( attr
), OUSTRING_CSTR( value
) );
273 // get a Property object
274 beans::Property prop
;
277 uno::Reference
< beans::XPropertySetInfo
> xInfo
278 = prophlp::queryPropertyInfo( xPeer
);
279 prop
= xInfo
->getPropertyByName( unoAttr
);
281 catch( beans::UnknownPropertyException
& )
283 DBG_ERROR1( "Warning: unknown attribute: `%s'\n", OUSTRING_CSTR( unoAttr
) );
287 if ( prop
.Name
.getLength() <= 0 )
289 DBG_ERROR1( "Warning: missing prop: `%s'\n", OUSTRING_CSTR( unoAttr
) );
293 // encapsulates value in an uno::Any
297 any
= anyFromString( value
, prop
.Type
);
299 catch( uno::RuntimeException
& )
301 DBG_ERROR5( "Warning: %s( %s )( %s ) attribute is of type %s( rejected: %s )\n", OUSTRING_CSTR( unoAttr
), OUSTRING_CSTR( value
), OUSTRING_CSTR( prop
.Name
), OUSTRING_CSTR( prop
.Type
.getTypeName() ), OUSTRING_CSTR( value
) );
305 // sets value on property
308 prophlp::setProperty( xPeer
, unoAttr
, any
);
312 DBG_ERROR2( "Warning: cannot set attribute %s to %s \n", OUSTRING_CSTR( unoAttr
), OUSTRING_CSTR( value
) );
325 static const AttributesMap attribsMap
[] =
327 { "autohscroll", awt::VclWindowPeerAttribute::AUTOHSCROLL
, false },
328 { "autovscroll", awt::VclWindowPeerAttribute::AUTOVSCROLL
, false },
329 { "center", awt::VclWindowPeerAttribute::CENTER
, false },
330 { "clipchildren", awt::VclWindowPeerAttribute::CLIPCHILDREN
, false },
331 { "closeable", awt::WindowAttribute::CLOSEABLE
, true },
332 { "defbutton", awt::VclWindowPeerAttribute::DEFBUTTON
, false },
333 { "dropdown", awt::VclWindowPeerAttribute::DROPDOWN
, false },
334 { "fullsize", awt::WindowAttribute::FULLSIZE
, true }, //FIXME?
335 { "group", awt::VclWindowPeerAttribute::GROUP
, false },
336 { "has_border", awt::WindowAttribute::BORDER
, true },
337 { "hscroll", awt::VclWindowPeerAttribute::HSCROLL
, false },
338 { "left", awt::VclWindowPeerAttribute::LEFT
, false },
339 { "moveable", awt::WindowAttribute::MOVEABLE
, true },
340 { "noborder", awt::VclWindowPeerAttribute::NOBORDER
, false },
341 { "nolabel", awt::VclWindowPeerAttribute::NOLABEL
, false },
342 { "optimumsize", awt::WindowAttribute::OPTIMUMSIZE
, false },
343 { "readonly", awt::VclWindowPeerAttribute::READONLY
, false },
344 { "right", awt::VclWindowPeerAttribute::RIGHT
, false },
345 { "show", awt::WindowAttribute::SHOW
, true },
346 { "sizeable", awt::WindowAttribute::SIZEABLE
, true },
347 { "sort", awt::VclWindowPeerAttribute::SORT
, false },
348 { "spin", awt::VclWindowPeerAttribute::SPIN
, false },
349 { "vscroll", awt::VclWindowPeerAttribute::VSCROLL
, false },
351 // cutting on OK, YES_NO_CANCEL and related obsite attributes...
353 static const int attribsMapLen
= sizeof( attribsMap
) / sizeof( AttributesMap
);
356 long getAttribute( const OUString
&rName
, bool bTopWindow
)
359 int min
= 0, max
= attribsMapLen
- 1, mid
, cmp
;
362 mid
= min
+( max
- min
)/2;
363 cmp
= rName
.compareToAscii( attribsMap
[ mid
].name
);
370 if ( bTopWindow
|| attribsMap
[ mid
].value
)
371 return attribsMap
[ mid
].windowAttr
;
375 while ( min
<= max
);
380 void propsFromAttributes( const uno::Reference
<xml::input::XAttributes
> & xAttributes
,
381 PropList
&rProps
, sal_Int32 nNamespace
)
383 sal_Int32 nAttrs
= xAttributes
->getLength();
384 for ( sal_Int32 i
= 0; i
< nAttrs
; i
++ )
386 if ( nNamespace
!= xAttributes
->getUidByIndex( i
) )
389 std::pair
< OUString
, OUString
> aElem
390 ( xAttributes
->getLocalNameByIndex( i
),
391 xAttributes
->getValueByIndex( i
) );
393 if ( aElem
.first
.getLength() > 0 ) // namespace bits ..
394 rProps
.push_back( aElem
);
399 findAndRemove( const char *pAttr
, PropList
&rProps
, OUString
&rValue
)
401 PropList::iterator it
;
402 OUString aName
= OUString::createFromAscii( pAttr
);
404 for ( it
= rProps
.begin(); it
!= rProps
.end(); it
++ )
406 if ( it
->first
.equalsIgnoreAsciiCase( aName
)
407 || it
->first
.equalsIgnoreAsciiCase( OUString::createFromAscii ("_") + aName
) )
419 getAttributeProps( PropList
&rProps
)
424 OUString
trueStr( RTL_CONSTASCII_USTRINGPARAM( "true" ) );
426 if ( findAndRemove( "show", rProps
, aValue
) &&
427 aValue
.equalsIgnoreAsciiCase(
428 OUString( RTL_CONSTASCII_USTRINGPARAM( "false" ) ) ) )
431 nAttrs
|= awt::WindowAttribute::SHOW
;
433 for ( int i
= 0; i
< attribsMapLen
; i
++ )
435 if ( findAndRemove( attribsMap
[i
].name
, rProps
, aValue
) )
437 if ( aValue
.equalsIgnoreAsciiCase( trueStr
) )
438 nAttrs
|= attribsMap
[i
].value
;
442 if ( findAndRemove( "align", rProps
, aValue
) )
444 sal_Int32 nVal
= aValue
.toInt32();
446 if ( nVal
== 0 /* PROPERTY_ALIGN_LEFT */ )
447 nAttrs
|= awt::VclWindowPeerAttribute::LEFT
;
448 else if ( nVal
== 1 /* PROPERTY_ALIGN_CENTER */ )
449 nAttrs
|= awt::VclWindowPeerAttribute::CENTER
;
450 else if ( nVal
== 2 )
451 nAttrs
|= awt::VclWindowPeerAttribute::RIGHT
;