Files
libreoffice/toolkit/source/vclcompat/wrapper.cxx

462 lines
14 KiB
C++
Raw Normal View History

#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