#include "wrapper.hxx" #include <com/sun/star/awt/XFixedText.hpp> #include <com/sun/star/awt/XDialog2.hpp> #include <com/sun/star/awt/WindowAttribute.hpp> #include <com/sun/star/awt/VclWindowPeerAttribute.hpp> #include <comphelper/processfactory.hxx> #include <vcl/window.hxx> #include <toolkit/awt/vclxwindow.hxx> #include "layoutcore.hxx" #include "../layout/factory.hxx" #include "../layout/root.hxx" using namespace ::com::sun::star; namespace layout { // Context bits ... class ContextImpl { uno::Reference< awt::XLayoutRoot > mxRoot; uno::Reference< container::XNameAccess > mxNameAccess; PeerHandle mxTopLevel; public: ContextImpl( char const *pPath ) { uno::Sequence< uno::Any > aParams( 1 ); aParams[0] <<= rtl::OUString( pPath, strlen( pPath ), RTL_TEXTENCODING_UTF8 ); uno::Reference< lang::XSingleServiceFactory > xFactory( comphelper::createProcessComponent( rtl::OUString::createFromAscii( "com.sun.star.awt.Layout" ) ), uno::UNO_QUERY ); if ( !xFactory.is() ) { throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Layout engine not installed" ) ), uno::Reference< uno::XInterface >() ); } mxRoot = uno::Reference< awt::XLayoutRoot >( xFactory->createInstanceWithArguments( aParams ), uno::UNO_QUERY ); mxNameAccess = uno::Reference< container::XNameAccess >( mxRoot, uno::UNO_QUERY ); } ~ContextImpl() { } PeerHandle getByName( const rtl::OUString &rName ) { uno::Any val = mxNameAccess->getByName( rName ); PeerHandle xRet; val >>= xRet; return xRet; } PeerHandle getTopLevel() { return mxTopLevel; } void setTopLevel( PeerHandle xToplevel ) { mxTopLevel = xToplevel; } PeerHandle getRoot() { return mxRoot; } }; Context::Context( const char *pPath ) : pImpl( new ContextImpl( pPath ) ) { } Context::~Context() { delete pImpl; pImpl = NULL; } void Context::setToplevel( PeerHandle xToplevel ) { pImpl->setTopLevel( xToplevel ); } PeerHandle Context::getToplevel() { return pImpl->getTopLevel(); } PeerHandle Context::getRoot() { return pImpl->getRoot(); } PeerHandle Context::GetPeerHandle( const char *pId, sal_uInt32 nId ) const { PeerHandle xHandle; xHandle = pImpl->getByName( rtl::OUString( pId, strlen( pId ), RTL_TEXTENCODING_UTF8 ) ); if ( !xHandle.is() ) { DBG_ERROR1( "Failed to fetch widget '%s'", pId ); } if ( nId != 0 ) { rtl::OString aStr = rtl::OString::valueOf( (sal_Int32) nId ); xHandle = GetPeerHandle( aStr, 0 ); } return xHandle; } // Window/Dialog class DialogImpl : public WindowImpl { public: uno::Reference< awt::XDialog2 > mxDialog; DialogImpl( Context *pCtx, const PeerHandle &xPeer, Window *pWindow ) : WindowImpl( pCtx, xPeer, pWindow ) , mxDialog( xPeer, uno::UNO_QUERY ) { } }; // Accessors DECL_GET_IMPL_IMPL( Control ) DECL_GET_IMPL_IMPL( Dialog ) Window::Window( WindowImpl *pImpl ) : mpImpl( pImpl ) { } Window::~Window() { /* likely to be an UNO object - with floating references */ mpImpl->wrapperGone(); mpImpl = NULL; } Context *Window::getContext() { return this && mpImpl ? mpImpl->mpCtx : NULL; } PeerHandle Window::GetPeer() { if (!mpImpl) return PeerHandle(); return mpImpl->mxWindow; } struct ToolkitVclPropsMap { WinBits vclStyle; long initAttr; const char *propName; // the value to give the prop to enable/disable it -- not the most brilliant // type declaration and storage, but does the work... properties are // either a boolean or a short since they are either a directly wrappers for // a WinBit, or aggregates related (like Align for WB_LEFT, _RIGHT and _CENTER). bool isBoolean; short enableProp, disableProp; }; #define TYPE_BOOL true #define TYPE_SHORT false #define NOTYPE 0 static const ToolkitVclPropsMap toolkitVclPropsMap[] = { { WB_BORDER, awt::WindowAttribute::BORDER, "Border", TYPE_SHORT, 1, 0 }, { WB_NOBORDER, awt::VclWindowPeerAttribute::NOBORDER, "Border", TYPE_SHORT, 0, 1 }, { WB_SIZEABLE, awt::WindowAttribute::SIZEABLE, NULL, NOTYPE, 0, 0 }, { WB_MOVEABLE, awt::WindowAttribute::MOVEABLE, NULL, NOTYPE, 0, 0 }, { WB_CLOSEABLE, awt::WindowAttribute::CLOSEABLE, NULL, NOTYPE, 0, 0 }, { WB_HSCROLL, awt::VclWindowPeerAttribute::HSCROLL, NULL, NOTYPE, 0, 0 }, { WB_VSCROLL, awt::VclWindowPeerAttribute::VSCROLL, NULL, NOTYPE, 0, 0 }, { WB_LEFT, awt::VclWindowPeerAttribute::LEFT, "Align", TYPE_SHORT, 0, 0 }, { WB_CENTER, awt::VclWindowPeerAttribute::CENTER, "Align", TYPE_SHORT, 1, 0 }, { WB_RIGHT, awt::VclWindowPeerAttribute::RIGHT, "Align", TYPE_SHORT, 2, 0 }, { WB_SPIN, awt::VclWindowPeerAttribute::SPIN, NULL, NOTYPE, 0, 0 }, { WB_SORT, awt::VclWindowPeerAttribute::SORT, NULL, NOTYPE, 0, 0 }, { WB_DROPDOWN, awt::VclWindowPeerAttribute::DROPDOWN, "Dropdown", TYPE_BOOL, 1, 0 }, { WB_DEFBUTTON, awt::VclWindowPeerAttribute::DEFBUTTON, "DefaultButton", TYPE_BOOL, 1, 0 }, { WB_READONLY, awt::VclWindowPeerAttribute::READONLY, NULL, NOTYPE, 0, 0 }, { WB_CLIPCHILDREN, awt::VclWindowPeerAttribute::CLIPCHILDREN, NULL, NOTYPE, 0, 0 }, { WB_GROUP, awt::VclWindowPeerAttribute::GROUP, NULL, NOTYPE, 0, 0 }, { WB_OK, awt::VclWindowPeerAttribute::OK, NULL, NOTYPE, 0, 0 }, { WB_OK_CANCEL, awt::VclWindowPeerAttribute::OK_CANCEL, NULL, NOTYPE, 0, 0 }, { WB_YES_NO, awt::VclWindowPeerAttribute::YES_NO, NULL, NOTYPE, 0, 0 }, { WB_YES_NO_CANCEL, awt::VclWindowPeerAttribute::YES_NO_CANCEL, NULL, NOTYPE, 1, 0 }, { WB_RETRY_CANCEL, awt::VclWindowPeerAttribute::RETRY_CANCEL, NULL, NOTYPE, 1, 0 }, { WB_DEF_OK, awt::VclWindowPeerAttribute::DEF_OK, NULL, NOTYPE, 0, 0 }, { WB_DEF_CANCEL, awt::VclWindowPeerAttribute::DEF_CANCEL, NULL, NOTYPE, 1, 0 }, { WB_DEF_RETRY, awt::VclWindowPeerAttribute::DEF_RETRY, NULL, NOTYPE, 0, 0 }, { WB_DEF_YES, awt::VclWindowPeerAttribute::DEF_YES, NULL, NOTYPE, 0, 0 }, { WB_DEF_NO, awt::VclWindowPeerAttribute::DEF_NO, NULL, NOTYPE, 0, 0 }, { WB_AUTOHSCROLL, awt::VclWindowPeerAttribute::AUTOHSCROLL, "AutoHScroll", TYPE_BOOL, 1, 0 }, { WB_AUTOVSCROLL, awt::VclWindowPeerAttribute::AUTOVSCROLL, "AutoVScroll", TYPE_BOOL, 1, 0 }, { WB_WORDBREAK, 0, "MultiLine", TYPE_BOOL, 1, 0 }, { WB_NOPOINTERFOCUS, 0, "FocusOnClick", TYPE_BOOL, 1, 0 }, { WB_TOGGLE, 0, "Toggle", TYPE_BOOL, 1, 0 }, { WB_REPEAT, 0, "Repeat", TYPE_BOOL, 1, 0 }, { WB_NOHIDESELECTION, 0, "HideInactiveSelection", TYPE_BOOL, 1, 0 }, }; #undef TYPE_BOOL #undef TYPE_SHORT #undef NOTYPE static const int toolkitVclPropsMapLen = sizeof( toolkitVclPropsMap ) / sizeof( ToolkitVclPropsMap ); void Window::SetStyle( WinBits nStyle ) { uno::Reference< awt::XVclWindowPeer > xPeer = mpImpl->mxVclPeer; for( int i = 0; i < toolkitVclPropsMapLen; i++ ) { if ( toolkitVclPropsMap[ i ].propName ) { short nValue; if ( nStyle & toolkitVclPropsMap[ i ].vclStyle ) nValue = toolkitVclPropsMap[ i ].enableProp; else nValue = toolkitVclPropsMap[ i ].disableProp; uno::Any aValue; if ( toolkitVclPropsMap[ i ].isBoolean ) aValue = uno::makeAny( (bool) nValue ); else aValue = uno::makeAny( (short) nValue ); mpImpl->setProperty( toolkitVclPropsMap[ i ].propName, aValue ); } } } WinBits Window::GetStyle() { uno::Reference< awt::XVclWindowPeer > xPeer = mpImpl->mxVclPeer; WinBits ret = 0; for( int i = 0; i < toolkitVclPropsMapLen; i++ ) { if ( toolkitVclPropsMap[ i ].propName ) { short nValue; if ( toolkitVclPropsMap[ i ].isBoolean ) { bool bValue; mpImpl->getProperty( toolkitVclPropsMap[ i ].propName ) >>= bValue; nValue = bValue ? 1 : 0; } else mpImpl->getProperty( toolkitVclPropsMap[ i ].propName ) >>= nValue; if ( nValue == toolkitVclPropsMap[ i ].enableProp ) ret |= toolkitVclPropsMap[i].vclStyle; } } return ret; } /* Unpleasant way to get an xToolkit pointer ... */ uno::Reference< awt::XToolkit > getToolkit() { static uno::Reference< awt::XToolkit > xToolkit; if (!xToolkit.is()) { // Urgh ... xToolkit = uno::Reference< awt::XToolkit >( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" ) ) ), uno::UNO_QUERY ); if ( !xToolkit.is() ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "failed to create toolkit!") ), uno::Reference< uno::XInterface >() ); } return xToolkit; } PeerHandle Window::CreatePeer( Window *pParent, WinBits nStyle, const char *pName) { long nWinAttrbs = 0; for( int i = 0; i < toolkitVclPropsMapLen; i++ ) if ( nStyle & toolkitVclPropsMap[ i ].vclStyle ) nWinAttrbs |= toolkitVclPropsMap[ i ].initAttr; return layoutimpl::createWidget( getToolkit(), pParent->GetPeer(), rtl::OUString::createFromAscii( pName ), nWinAttrbs ); #if 0 awt::WindowDescriptor desc; // debugging help ... desc.Bounds.X = 0; desc.Bounds.Y = 0; desc.Bounds.Width = 300; desc.Bounds.Height = 200; desc.ParentIndex = 0; // FIXME: this code should be shared with // toolkit/source/awt/vclxtoolkit.cxx (ImplGetWinBits) desc.WindowAttributes = 0; for( int i = 0; i < toolkitVclPropsMapLen; i++ ) if ( nStyle & toolkitVclPropsMap[ i ].vclStyle ) desc.WindowAttributes |= toolkitVclPropsMap[ i ].initAttr; desc.WindowServiceName = rtl::OUString( pName, strlen( pName ), RTL_TEXTENCODING_ASCII_US ); // FIXME: we really want to walk up the peer hierarchy // and get the top-level that this requires. if ( pParent != NULL ) { PeerHandle hdl = pParent->GetPeer(); desc.Parent = uno::Reference< awt::XWindowPeer >( hdl, uno::UNO_QUERY ); } PeerHandle xPeer = getToolkit()->createWindow( desc ); // not all WinBits have an equivalent attribute, some are available through // properties though for( int i = 0; i < toolkitVclPropsMapLen; i++ ) if ( nStyle & toolkitVclPropsMap[ i ].vclStyle && !toolkitVclPropsMap[ i ].initAttr && toolkitVclPropsMap[ i ].propName ) { uno::Any aValue; if ( toolkitVclPropsMap[ i ].isBoolean ) aValue = uno::makeAny( (bool) toolkitVclPropsMap[ i ].enableProp ); else aValue = uno::makeAny( (short) toolkitVclPropsMap[ i ].enableProp ); layoutimpl::prophlp::setProperty( xPeer, rtl::OUString::createFromAscii( toolkitVclPropsMap[ i ].propName ), aValue ); } return xPeer; #endif } void Window::Enable( bool bEnable ) { if ( !getImpl().mxWindow.is() ) return; getImpl().mxWindow->setEnable( bEnable ); } void Window::Show( BOOL bVisible ) { if ( !getImpl().mxWindow.is() ) return; getImpl().mxWindow->setVisible( bVisible ); } void Window::GrabFocus() { if ( !getImpl().mxWindow.is() ) return; getImpl().mxWindow->setFocus(); } Dialog::Dialog( Window *pParent, const char *pXMLPath, const char *pId, sal_uInt32 nId ) : Context( pXMLPath ) , Window( new DialogImpl( this, Context::GetPeerHandle( pId, nId ), this ) ) { if ( pParent ) SetParent( pParent ); } Dialog::Dialog( ::Window *pParent, const char *pXMLPath, const char *pId, sal_uInt32 nId ) : Context( pXMLPath ) , Window( new DialogImpl( this, Context::GetPeerHandle( pId, nId ), this ) ) { if ( pParent ) SetParent( pParent ); } void Dialog::SetParent( ::Window *pParent ) { uno::Reference <awt::XWindow> ref( GetPeer(), uno::UNO_QUERY ); ::Window *window = VCLXWindow::GetImplementation( ref )->GetWindow(); window->SetParent( pParent ); } void Dialog::SetParent( Window *pParent ) { uno::Reference <awt::XWindow> parentRef( pParent->GetPeer(), uno::UNO_QUERY ); ::Window *parentWindow = VCLXWindow::GetImplementation( parentRef )->GetWindow(); SetParent( parentWindow ); } short Dialog::Execute() { if ( !getImpl().mxDialog.is() ) return -1; return getImpl().mxDialog->execute(); } void Dialog::EndDialog( long nResult ) { if ( !getImpl().mxDialog.is() ) return; getImpl().mxDialog->endDialog( nResult ); } void Dialog::SetText( const String& rStr ) { if ( !getImpl().mxDialog.is() ) return; getImpl().mxDialog->setTitle( rStr ); } class FixedLineImpl : public ControlImpl { public: FixedLineImpl( Context *pCtx, const PeerHandle &xPeer, Window *pWindow ) : ControlImpl( pCtx, xPeer, pWindow ) { } }; DECL_CONSTRUCTOR_IMPLS( FixedLine, Control, "hfixedline" ); DECL_GET_IMPL_IMPL( FixedLine ) class FixedTextImpl : public ControlImpl { public: uno::Reference< awt::XFixedText > mxFixedText; FixedTextImpl( Context *pCtx, const PeerHandle &xPeer, Window *pWindow ) : ControlImpl( pCtx, xPeer, pWindow ) , mxFixedText( xPeer, uno::UNO_QUERY ) { } virtual void SAL_CALL disposing( const css::lang::EventObject& /* Source */ ) throw (css::uno::RuntimeException) { mxFixedText.clear(); } }; DECL_CONSTRUCTOR_IMPLS( FixedText, Control, "fixedtext" ); DECL_GET_IMPL_IMPL( FixedText ) void FixedText::SetText( const String& rStr ) { if ( !getImpl().mxFixedText.is() ) return; getImpl().mxFixedText->setText( rStr ); } class FixedInfoImpl : public FixedTextImpl { public: FixedInfoImpl( Context *pCtx, const PeerHandle &xPeer, Window *pWindow ) : FixedTextImpl( pCtx, xPeer, pWindow ) { } }; DECL_CONSTRUCTOR_IMPLS( FixedInfo, FixedText, "fixedinfo" ); DECL_GET_IMPL_IMPL( FixedInfo ) }; // end namespace layout