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 ************************************************************************/
36 #include <com/sun/star/awt/WindowAttribute.hpp>
37 #include <com/sun/star/awt/XWindow.hpp>
38 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
39 #include <toolkit/awt/vclxwindow.hxx>
40 #include <tools/debug.hxx>
42 #include "proplist.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 */
55 using namespace com::sun::star
;
58 uno::Reference
< awt::XWindowPeer
>
59 getParent( uno::Reference
< uno::XInterface
> xRef
)
63 uno::Reference
< awt::XWindowPeer
> xPeer( xRef
, uno::UNO_QUERY
);
67 uno::Reference
< awt::XLayoutContainer
> xCont( xRef
, uno::UNO_QUERY
);
69 xRef
= xCont
->getParent();
73 return uno::Reference
< awt::XWindowPeer
>();
77 static uno::Reference
< awt::XWindowPeer
>
78 getToplevel( uno::Reference
< uno::XInterface
> xRef
)
80 uno::Reference
< awt::XWindowPeer
> xTop
, i
;
81 while ( ( i
= uno::Reference
< awt::XWindowPeer
>( xRef
, uno::UNO_QUERY
) ).is() )
85 uno::Reference
< awt::XLayoutContainer
> xCont( xRef
, uno::UNO_QUERY
);
87 xRef
= xCont
->getParent();
89 xRef
= uno::Reference
< awt::XWindowPeer
>();
100 #include "dialogbuttonhbox.hxx"
102 #include "localized-string.hxx"
108 oslModule
WidgetFactory::mSfx2Library
= 0;
109 WindowCreator
WidgetFactory::mSfx2CreateWidget
= 0;
111 uno::Reference
<awt::XLayoutContainer
> WidgetFactory::createContainer (OUString
const& name
)
113 uno::Reference
< awt::XLayoutContainer
> xPeer
;
115 if ( name
.equalsAscii( "hbox" ) )
116 xPeer
= uno::Reference
< awt::XLayoutContainer
>( new HBox() );
117 else if ( name
.equalsAscii( "vbox" ) )
118 xPeer
= uno::Reference
< awt::XLayoutContainer
>( new VBox() );
119 else if ( name
.equalsAscii( "table" ) )
120 xPeer
= uno::Reference
< awt::XLayoutContainer
>( new Table() );
121 else if ( name
.equalsAscii( "flow" ) )
122 xPeer
= uno::Reference
< awt::XLayoutContainer
>( new Flow() );
123 else if ( name
.equalsAscii( "bin" ) )
124 xPeer
= uno::Reference
< awt::XLayoutContainer
>( new Bin() );
125 else if ( name
.equalsAscii( "min-size" ) )
126 xPeer
= uno::Reference
< awt::XLayoutContainer
>( new MinSize() );
127 else if ( name
.equalsAscii( "align" ) )
128 xPeer
= uno::Reference
< awt::XLayoutContainer
>( new Align() );
129 else if ( name
.equalsAscii( "dialogbuttonhbox" ) )
130 xPeer
= uno::Reference
< awt::XLayoutContainer
>( new DialogButtonHBox() );
135 uno::Reference
<awt::XLayoutConstrains
> WidgetFactory::toolkitCreateWidget (uno::Reference
<awt::XToolkit
> xToolkit
, uno::Reference
<uno::XInterface
> xParent
, OUString
const& name
, long properties
)
137 uno::Reference
< awt::XLayoutConstrains
> xPeer
;
138 bool bToplevel
= !xParent
.is();
140 // UNO Control Widget
141 awt::WindowDescriptor desc
;
143 desc
.Type
= awt::WindowClass_TOP
;
146 desc
.Type
= awt::WindowClass_SIMPLE
;
149 // top container -- a wrapper for framewindow -- is de-coupled
150 // from awt::XWindowPeer. So, getParent() fails at it.
151 uno::Reference
< awt::XWindowPeer
> xWinParent
= getParent( xParent
);
153 uno::Reference
< awt::XWindowPeer
> xWinParent( xParent
, uno::UNO_QUERY
);
155 assert( xParent
.is() );
156 assert( xWinParent
.is() );
158 With the new three layer instarr/rpath feature, when
159 prepending toolkit/unxlngx6.pro/lib or $SOLARVER/lib to
160 LD_LIBRARY_PATH, VCLXWindow::GetImplementation returns 0x0
161 vclxtoolkit::ImplCreateWindow failing to create any widget;
162 although it succeeds here.
164 While developing, one now must copy libtlx.so to
165 $OOO_INSTALL_PREFIX/openoffice.org/basis3.0/program/libtklx.so
168 VCLXWindow
* parentComponent
= VCLXWindow::GetImplementation( xWinParent
);
169 if ( !parentComponent
)
170 throw uno::RuntimeException(
171 OUString::createFromAscii( "parent has no implementation" ),
172 uno::Reference
< uno::XInterface
>() );
173 desc
.Parent
= xWinParent
;
176 desc
.ParentIndex
= 0;
177 // debugging help ...
180 desc
.Bounds
.Width
= 300;
181 desc
.Bounds
.Height
= 200;
183 desc
.WindowAttributes
= properties
;
184 desc
.WindowServiceName
= name
;
186 uno::Reference
< awt::XWindowPeer
> xWinPeer
;
189 OSL_TRACE("Asking toolkit: %s", OUSTRING_CSTR( desc
.WindowServiceName
) );
190 xWinPeer
= xToolkit
->createWindow( desc
);
191 if ( !xWinPeer
.is() )
192 throw uno::RuntimeException(
193 OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot create peer" ) ),
194 uno::Reference
< uno::XInterface
>() );
195 xPeer
= uno::Reference
< awt::XLayoutConstrains
>( xWinPeer
, uno::UNO_QUERY
);
197 catch( uno::Exception
& )
199 DBG_ERROR1( "Warning: %s is not a recognized type\n", OUSTRING_CSTR( name
) );
200 return uno::Reference
< awt::XLayoutConstrains
>();
203 #if 0 // This shadows the show="false" property and seems otherwise
206 // default to visible, let then people change it on properties
209 uno::Reference
< awt::XWindow
> xWindow( xPeer
, uno::UNO_QUERY
);
211 xWindow
->setVisible( true );
218 uno::Reference
< awt::XLayoutConstrains
>
219 WidgetFactory::createWidget (uno::Reference
< awt::XToolkit
> xToolkit
, uno::Reference
< uno::XInterface
> xParent
, OUString
const& name
, long properties
)
221 uno::Reference
< awt::XLayoutConstrains
> xPeer
;
223 xPeer
= uno::Reference
<awt::XLayoutConstrains
> (createContainer (name
), uno::UNO_QUERY
);
227 xPeer
= implCreateWidget (xParent
, name
, properties
);
233 OUString tName
= name
;
235 if ( name
.equalsAscii( "fixedinfo" ) )
236 tName
= OUString::createFromAscii( "fixedtext" );
237 xPeer
= toolkitCreateWidget (xToolkit
, xParent
, tName
, properties
);
239 xPeer
= toolkitCreateWidget (xToolkit
, xParent
, name
, properties
);
245 PropHelper::PropHelper() : LockHelper()
246 , cppu::OPropertySetHelper( maBrdcstHelper
)
252 PropHelper::addProp (const char *pName
, sal_Int32 nNameLen
, rtl_TextEncoding e
,
253 uno::Type aType
, void *pPtr
)
255 // this sucks rocks for effiency ...
256 PropDetails aDetails
;
257 aDetails
.aName
= rtl::OUString::intern( pName
, nNameLen
, e
);
258 aDetails
.aType
= aType
;
259 aDetails
.pValue
= pPtr
;
260 maDetails
.push_back( aDetails
);
263 cppu::IPropertyArrayHelper
& SAL_CALL
264 PropHelper::getInfoHelper()
268 uno::Sequence
< beans::Property
> aProps( maDetails
.size() );
269 for ( unsigned int i
= 0; i
< maDetails
.size(); i
++)
271 aProps
[i
].Name
= maDetails
[i
].aName
;
272 aProps
[i
].Type
= maDetails
[i
].aType
;
273 aProps
[i
].Handle
= i
;
274 aProps
[i
].Attributes
= 0;
276 pHelper
= new cppu::OPropertyArrayHelper( aProps
, false /* fixme: faster ? */ );
283 PropHelper::convertFastPropertyValue(
284 uno::Any
& rConvertedValue
,
285 uno::Any
& rOldValue
,
287 const uno::Any
& rValue
)
288 throw (lang::IllegalArgumentException
)
290 OSL_ASSERT( nHandle
>= 0 && nHandle
< (sal_Int32
) maDetails
.size() );
292 // FIXME: no Any::getValue ...
293 getFastPropertyValue( rOldValue
, nHandle
);
294 if ( rOldValue
!= rValue
)
296 rConvertedValue
= rValue
;
297 return sal_True
; // changed
301 rConvertedValue
.clear();
309 PropHelper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
,
310 const uno::Any
& rValue
)
311 throw (uno::Exception
)
313 OSL_ASSERT( nHandle
>= 0 && nHandle
< (sal_Int32
) maDetails
.size() );
315 const PropDetails
&rInfo
= maDetails
[ nHandle
];
317 uno_type_assignData( rInfo
.pValue
, rInfo
.aType
.getTypeLibType(),
318 rValue
.pData
, rValue
.pType
,
322 mpListener
->propertiesChanged();
326 PropHelper::getFastPropertyValue( uno::Any
& rValue
,
327 sal_Int32 nHandle
) const
329 OSL_ASSERT( nHandle
>= 0 && nHandle
< (sal_Int32
) maDetails
.size() );
330 const PropDetails
&rInfo
= maDetails
[ nHandle
];
332 switch ( rInfo
.aType
.getTypeClass() )
334 #define MAP(classtype,ctype) \
335 case uno::TypeClass_##classtype: \
336 rValue <<= *(ctype *)(rInfo.pValue); \
338 MAP( DOUBLE
, double );
339 MAP( SHORT
, sal_Int16
);
340 MAP( LONG
, sal_Int32
);
341 MAP( UNSIGNED_SHORT
, sal_uInt16
);
342 MAP( UNSIGNED_LONG
, sal_uInt32
);
343 MAP( STRING
, ::rtl::OUString
);
345 DBG_ERROR( "ERROR: unknown type to map!" );
350 rValue
.setValue( rInfo
.pValue
, rInfo
.aType
);
353 ::com::sun::star::uno::Any
354 PropHelper::queryInterface( const ::com::sun::star::uno::Type
& rType
) throw(::com::sun::star::uno::RuntimeException
)
356 return OPropertySetHelper::queryInterface( rType
);
359 uno::Reference
<beans::XPropertySetInfo
> SAL_CALL
PropHelper::getPropertySetInfo () throw (uno::RuntimeException
)
361 return css::uno::Reference
<css::beans::XPropertySetInfo
> (createPropertySetInfo (getInfoHelper ()));
364 } // namespace layoutimpl
366 #include <awt/vclxbutton.hxx>
367 #include <awt/vclxdialog.hxx>
368 #include <awt/vclxfixedline.hxx>
369 #include <awt/vclxplugin.hxx>
370 #include <awt/vclxscroller.hxx>
371 #include <awt/vclxsplitter.hxx>
372 #include <awt/vclxtabcontrol.hxx>
373 #include <awt/vclxtabpage.hxx>
374 #include <toolkit/awt/vclxtoolkit.hxx>
375 #include <toolkit/awt/vclxwindow.hxx>
376 #include <vcl/button.hxx>
377 #include <vcl/dialog.hxx>
378 #include <vcl/fixed.hxx>
379 #include <vcl/tabctrl.hxx>
380 #include <vcl/tabpage.hxx>
381 #include <vcl/unohelp.hxx>
383 #include <layout/layout.hxx>
384 #include <toolkit/awt/vclxwindows.hxx>
385 #include <vcl/lstbox.hxx>
393 uno::Reference
<awt::XLayoutConstrains
> WidgetFactory::implCreateWidget (uno::Reference
<uno::XInterface
> xParent
, OUString name
, long attributes
)
397 if (VCLXWindow
* parentComponent
= VCLXWindow::GetImplementation (xParent
))
398 parent
= parentComponent
->GetWindow ();
400 VCLXWindow
* component
= 0;
401 Window
* window
= 0; //sfx2CreateWindow (&component, parent, name, attributes);
403 window
= layoutCreateWindow (&component
, parent
, name
, attributes
);
405 uno::Reference
<awt::XLayoutConstrains
> reference
;
408 window
->SetCreatedWithToolkit( sal_True
);
410 component
->SetCreatedWithToolkit( true );
411 reference
= component
;
412 window
->SetComponentInterface( component
);
413 if ( attributes
& awt::WindowAttribute::SHOW
)
420 extern "C" { static void SAL_CALL
thisModule() {} }
422 Window
* WidgetFactory::sfx2CreateWindow (VCLXWindow
** component
, Window
* parent
, OUString
const& name
, long& attributes
)
424 OSL_TRACE("Asking sfx2: %s", OUSTRING_CSTR (name
));
428 OUString libraryName
= ::vcl::unohelper::CreateLibraryName ("sfx", TRUE
);
429 mSfx2Library
= osl_loadModuleRelative (&thisModule
, libraryName
.pData
, SAL_LOADMODULE_DEFAULT
);
432 OUString
functionName (RTL_CONSTASCII_USTRINGPARAM ("CreateWindow"));
433 mSfx2CreateWidget
= (WindowCreator
) osl_getFunctionSymbol (mSfx2Library
, functionName
.pData
);
437 if (mSfx2CreateWidget
)
438 return mSfx2CreateWidget (component
, name
, parent
, attributes
);
443 Window
* WidgetFactory::layoutCreateWindow (VCLXWindow
** component
, Window
*parent
, OUString
const& name
, long& attributes
)
451 if ( name
.equalsAscii( "dialog" ) )
453 if ( parent
== NULL
)
454 parent
= DIALOG_NO_PARENT
;
455 window
= new Dialog( parent
, ImplGetWinBits( attributes
, 0 ) );
456 *component
= new layoutimpl::VCLXDialog();
458 attributes
^= awt::WindowAttribute::SHOW
;
460 else if ( name
.equalsAscii( "modaldialog" ) )
462 if ( parent
== NULL
)
463 parent
= DIALOG_NO_PARENT
;
464 window
= new ModalDialog( parent
, ImplGetWinBits( attributes
, 0 ) );
465 *component
= new layoutimpl::VCLXDialog();
467 attributes
^= awt::WindowAttribute::SHOW
;
469 else if ( name
.equalsAscii( "modelessdialog" ) )
471 if ( parent
== NULL
)
472 parent
= DIALOG_NO_PARENT
;
473 window
= new ModelessDialog (parent
, ImplGetWinBits (attributes
, 0));
474 *component
= new layoutimpl::VCLXDialog();
476 attributes
^= awt::WindowAttribute::SHOW
;
478 else if ( name
.equalsAscii( "sfxdialog" ) )
480 if ( parent
== NULL
)
481 parent
= DIALOG_NO_PARENT
;
482 window
= new ClosingDialog (parent
, ImplGetWinBits (attributes
, 0));
483 *component
= new layoutimpl::VCLXDialog();
485 attributes
^= awt::WindowAttribute::SHOW
;
487 else if ( name
.equalsAscii( "sfxmodaldialog" ) )
489 if ( parent
== NULL
)
490 parent
= DIALOG_NO_PARENT
;
491 window
= new ClosingModalDialog( parent
,
492 ImplGetWinBits( attributes
, 0 ) );
493 *component
= new layoutimpl::VCLXDialog();
495 attributes
^= awt::WindowAttribute::SHOW
;
497 else if ( name
.equalsAscii( "sfxmodelessdialog" ) )
499 if ( parent
== NULL
)
500 parent
= DIALOG_NO_PARENT
;
501 window
= new ClosingModelessDialog (parent
, ImplGetWinBits (attributes
, 0));
502 *component
= new layoutimpl::VCLXDialog();
504 attributes
^= awt::WindowAttribute::SHOW
;
506 else if ( name
.equalsAscii( "tabcontrol" ) )
508 window
= new TabControl( parent
, ImplGetWinBits( attributes
, WINDOW_TABCONTROL
) );
509 *component
= new layoutimpl::VCLXTabControl();
511 else if ( name
.equalsAscii( "scroller" ) )
513 // used FixedImage because I just want some empty non-intrusive widget
514 window
= new FixedImage( parent
, ImplGetWinBits( attributes
, 0 ) );
515 *component
= new layoutimpl::VCLXScroller();
517 else if ( name
.equalsAscii( "hsplitter" ) || name
.equalsAscii( "vsplitter" ) )
519 window
= new FixedImage( parent
, ImplGetWinBits( attributes
, 0 ) );
520 *component
= new layoutimpl::VCLXSplitter( name
.equalsAscii( "hsplitter" ) );
522 else if ( name
.equalsAscii( "hfixedline" ) || name
.equalsAscii( "vfixedline" ) )
524 WinBits nStyle
= ImplGetWinBits( attributes
, 0 );
526 if ( name
.equalsAscii( "hfixedline" ) )
530 window
= new FixedLine( parent
, nStyle
);
531 *component
= new layoutimpl::VCLXFixedLine();
533 else if ( name
.equalsAscii( "okbutton" ) )
535 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
536 *component
= new layoutimpl::VCLXOKButton( window
);
537 window
->SetType (WINDOW_OKBUTTON
);
539 else if ( name
.equalsAscii( "cancelbutton" ) )
541 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
542 *component
= new layoutimpl::VCLXCancelButton( window
);
543 window
->SetType (WINDOW_CANCELBUTTON
);
545 else if ( name
.equalsAscii( "yesbutton" ) )
547 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
548 *component
= new layoutimpl::VCLXYesButton( window
);
549 window
->SetType (WINDOW_OKBUTTON
);
551 else if ( name
.equalsAscii( "nobutton" ) )
553 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
554 window
->SetType (WINDOW_CANCELBUTTON
);
555 *component
= new layoutimpl::VCLXNoButton( window
);
557 else if ( name
.equalsAscii( "retrybutton" ) )
559 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
560 *component
= new layoutimpl::VCLXRetryButton( window
);
562 else if ( name
.equalsAscii( "ignorebutton" ) )
564 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
565 *component
= new layoutimpl::VCLXIgnoreButton( window
);
567 else if ( name
.equalsAscii( "resetbutton" ) )
569 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
570 *component
= new layoutimpl::VCLXResetButton( window
);
572 else if ( name
.equalsAscii( "applybutton" ) )
574 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
575 *component
= new layoutimpl::VCLXApplyButton( window
);
577 else if ( name
.equalsAscii( "helpbutton" ) )
579 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
580 *component
= new layoutimpl::VCLXHelpButton( window
);
581 window
->SetType (WINDOW_HELPBUTTON
);
583 else if ( name
.equalsAscii( "morebutton" ) )
585 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
586 *component
= new layoutimpl::VCLXMoreButton( window
);
587 window
->SetType (WINDOW_MOREBUTTON
);
589 else if ( name
.equalsAscii( "advancedbutton" ) )
591 window
= new PushButton( parent
, ImplGetWinBits( attributes
, 0 ) );
592 *component
= new layoutimpl::VCLXAdvancedButton( window
);
594 else if ( name
.equalsAscii( "plugin" ) )
596 window
= new Control( parent
, ImplGetWinBits( attributes
, 0 ) );
598 OSL_TRACE( "%s: parent=%p (%s)\n", __FUNCTION__
, parent
, typeid( *parent
).name() );
600 *component
= new layoutimpl::VCLXPlugin( window
, ImplGetWinBits( attributes
, 0 ) );
602 else if ( name
.equalsAscii( "tabpage" ) )
606 parent
= layout::TabPage::global_parent
;
608 if (layout::TabPage::global_parent
)
609 parent
= layout::TabPage::global_parent
;
610 layout::TabPage::global_parent
= 0;
612 //window = new TabPage( parent, ImplGetWinBits( attributes, 0 ) );
613 attributes
^= awt::WindowAttribute::SHOW
;
614 WinBits nStyle
= ImplGetWinBits( attributes
, 0 );
619 window
= new Dialog( parent
, nStyle
);
620 *component
= new VCLXDialog();
624 window
= new TabPage( parent
, nStyle
);
625 *component
= new VCLXTabPage( window
);
628 else if ( name
.equalsAscii( "string" ) )
630 // FIXME: move <string>s.text to simple map<string> in root?
631 attributes
&= ~awt::WindowAttribute::SHOW
;
632 window
= new Window( parent
, ImplGetWinBits( attributes
, 0 ) );
633 *component
= new layoutimpl::LocalizedString();
635 #if 0 // parent paranoia
636 else if ( name
.equalsAscii( "listbox" ) )
638 window
= new ListBox (parent
, ImplGetWinBits (attributes
, 0));
639 *component
= new VCLXListBox ();
642 else if (name
.equalsAscii ("svxfontlistbox")
643 || name
.equalsAscii ("svxlanguagebox"))
645 window
= new ListBox (parent
, ImplGetWinBits (attributes
, 0));
646 *component
= new VCLXListBox ();
651 } // namespace layoutimpl
653 // Avoid polluting the rest of the code with vcl linkage pieces ...
655 #include <vcl/imagerepository.hxx>
656 #include <vcl/bitmapex.hxx>
657 #include <vcl/graph.hxx>
662 uno::Reference
< graphic::XGraphic
> loadGraphic( const char *pName
)
666 OUString
aStr( pName
, strlen( pName
), RTL_TEXTENCODING_ASCII_US
);
667 if ( aStr
.compareToAscii( ".uno:" ) == 0 )
668 aStr
= aStr
.copy( 5 ).toAsciiLowerCase();
670 if ( !vcl::ImageRepository::loadImage( OUString::createFromAscii( pName
), aBmp
, true ) )
671 return uno::Reference
< graphic::XGraphic
>();
673 return Graphic( aBmp
).GetXGraphic();
676 } // namespace layoutimpl