blob: 93ae3a411e0a6faf2c13cc7bbd24a94e3a80284e [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
#include "root.hxx"
#include <cassert>
#include <com/sun/star/awt/WindowAttribute.hpp>
#include <com/sun/star/awt/XMessageBox.hpp>
#include <com/sun/star/awt/MessageBoxButtons.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/awt/XMessageBoxFactory.hpp>
#include <com/sun/star/xml/sax/SAXParseException.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>
#include "helper.hxx"
#include "import.hxx"
#include "timer.hxx"
#include "translate.hxx"
namespace layoutimpl
{
using namespace css;
using ::rtl::OUString;
LayoutRoot::LayoutRoot( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
: mbDisposed( sal_False )
, mxFactory( xFactory )
, mpListeners( NULL )
, mpToplevel( NULL )
{
if ( !xFactory.is() )
throw uno::RuntimeException();
mxLayoutUnit = uno::Reference< awt::XLayoutUnit >( new LayoutUnit() );
}
LayoutRoot::~LayoutRoot()
{
// TODO: we want to delete the top level LayoutWidget...
::osl::MutexGuard aGuard( maMutex );
if ( !mbDisposed )
{
try
{
m_refCount++; // inhibit multiple destruction
dispose();
}
catch( uno::Exception& )
{
}
}
}
void ShowMessageBox( uno::Reference< lang::XMultiServiceFactory > const& xFactory, uno::Reference< awt::XToolkit > xToolkit, OUString const& aTitle, OUString const& aMessage )
{
uno::Reference< uno::XInterface > iDesktop = xFactory->createInstance
( OUString::createFromAscii( "com.sun.star.frame.Desktop" ) );
uno::Reference< frame::XDesktop > xDesktop ( iDesktop, uno::UNO_QUERY );
uno::Reference< frame::XFrame > xFrame ( xDesktop->getCurrentFrame() );
uno::Reference< awt::XWindow > xContainerWindow( xFrame->getContainerWindow() );
uno::Reference< awt::XWindowPeer > xWindowPeer( xContainerWindow, uno::UNO_QUERY_THROW );
uno::Reference< awt::XMessageBoxFactory > xMessageBoxFactory( xToolkit, uno::UNO_QUERY );
uno::Reference< awt::XMessageBox > xMessageBox
= xMessageBoxFactory->createMessageBox
( xWindowPeer, awt::MessageBoxType_ERRORBOX,
awt::MessageBoxButtons::BUTTONS_OK, aTitle, aMessage );
if ( xMessageBox.is() )
xMessageBox->execute();
//FIXME: exceptions not caught and printed at top level??
//else
//printf( "%s\n", OUSTRING_CSTR( aMessage ) );
}
void LayoutRoot::error( OUString const& message )
{
OSL_TRACE( "%s\n", OUSTRING_CSTR( message ) );
ShowMessageBox( mxFactory, mxToolkit,
OUString::createFromAscii( "Fatal error" ),
message );
throw uno::RuntimeException( message, uno::Reference< uno::XInterface >() );
}
// XInitialization
void SAL_CALL LayoutRoot::initialize( const uno::Sequence< uno::Any >& aArguments )
throw ( uno::Exception,
uno::RuntimeException )
{
::osl::MutexGuard aGuard( maMutex );
if ( mbDisposed )
throw lang::DisposedException();
if ( mxContainer.is() ) // only 1 init ...
throw uno::Exception();
if ( !aArguments.getLength() )
throw lang::IllegalArgumentException();
OSL_ENSURE( aArguments.getLength() == 1, "Wrong arg count\n" );
OUString aXMLName;
if ( !( aArguments[0] >>= aXMLName ) )
throw lang::IllegalArgumentException();
uno::Reference< xml::sax::XParser > xParser
( mxFactory->createInstance(
OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ) ),
uno::UNO_QUERY );
OSL_ASSERT( xParser.is() );
if (! xParser.is())
{
throw uno::RuntimeException(
OUString::createFromAscii( "cannot create sax-parser component" ),
uno::Reference< uno::XInterface >() );
}
// FIXME: quite possibly we want to pass this in ...
uno::Reference< awt::XToolkit > xToolkit;
mxToolkit = uno::Reference< awt::XToolkit >(
mxFactory->createInstance(
OUString::createFromAscii( "com.sun.star.awt.Toolkit" ) ),
uno::UNO_QUERY );
if ( !mxToolkit.is() )
throw uno::RuntimeException(
OUString::createFromAscii( "failed to create toolkit!" ),
uno::Reference< uno::XInterface >() );
OUString aXMLFile = readRightTranslation( aXMLName );
uno::Reference< io::XInputStream > xStream = getFileAsStream( aXMLFile );
if (! xStream.is() )
error( OUString::createFromAscii( "Installation problem: cannot find XML file:" ) + aXMLName );
// error handler, entity resolver omitted
ImportContext *pCtx = new ImportContext( *this );
uno::Reference< xml::input::XRoot > xRoot( pCtx );
uno::Sequence < uno::Any > aArgs( 1 );
aArgs[0] <<= xRoot;
uno::Reference< xml::sax::XDocumentHandler > xDocHandler
(mxFactory->createInstanceWithArguments
( OUString::createFromAscii( "com.sun.star.xml.input.SaxDocumentHandler" ),
aArgs ), uno::UNO_QUERY );
if (! xDocHandler.is() )
error( OUString::createFromAscii( "cannot find SAx handler for document type of:") + aXMLName );
xParser->setDocumentHandler( xDocHandler );
xml::sax::InputSource source;
source.aInputStream = xStream;
source.sSystemId = OUString::createFromAscii( "virtual file" );
try
{
xParser->parseStream( source );
}
catch ( xml::sax::SAXParseException& e )
{
OUString c = OUString::createFromAscii( ":" );
error( aXMLName
+ c + OUString::valueOf( e.LineNumber )
+ c + OUString::valueOf( e.ColumnNumber )
+ c + OUString::createFromAscii( "Sax parse error" ) );
}
}
// XLayoutContainer
uno::Reference< awt::XLayoutContainer > LayoutRoot::getLayoutContainer() throw (uno::RuntimeException)
{
return uno::Reference< awt::XLayoutContainer >();
}
// local helper ...
void LayoutRoot::addItem( const OUString &rName,
const uno::Reference< awt::XLayoutConstrains > &xRef )
{
maItems[ rName ] = xRef;
}
// XNameAccess
uno::Any SAL_CALL LayoutRoot::getByName( const OUString &rName )
throw ( container::NoSuchElementException,
lang::WrappedTargetException,
uno::RuntimeException )
{
::osl::MutexGuard aGuard( maMutex );
if ( mbDisposed )
throw lang::DisposedException();
uno::Reference< awt::XLayoutConstrains > xItem;
ItemHash::iterator i = maItems.find( rName );
if ( i != maItems.end() )
xItem = i->second;
return uno::makeAny( xItem );
}
sal_Bool SAL_CALL LayoutRoot::hasByName( const OUString &rName )
throw (uno::RuntimeException)
{
::osl::MutexGuard aGuard( maMutex );
if ( mbDisposed ) throw lang::DisposedException();
ItemHash::iterator i = maItems.find( rName );
return i != maItems.end();
}
uno::Sequence< OUString > SAL_CALL LayoutRoot::getElementNames()
throw ( uno::RuntimeException )
{
::osl::MutexGuard aGuard( maMutex );
if ( mbDisposed ) throw lang::DisposedException();
uno::Sequence< OUString > aNames( maItems.size() );
sal_Int32 nPos = 0;
for ( ItemHash::const_iterator it = maItems.begin();
it != maItems.end(); it++ )
aNames[ nPos++ ] = it->first;
return aNames;
}
uno::Type SAL_CALL LayoutRoot::getElementType()
throw ( uno::RuntimeException )
{
return getCppuType( ( const uno::Reference< awt::XLayoutConstrains >* )NULL );
}
sal_Bool SAL_CALL LayoutRoot::hasElements()
throw ( uno::RuntimeException )
{
::osl::MutexGuard aGuard( maMutex );
if ( mbDisposed ) throw lang::DisposedException();
return maItems.size() > 0;
}
// XComponent
void SAL_CALL LayoutRoot::dispose()
throw ( uno::RuntimeException )
{
::osl::MutexGuard aGuard( maMutex );
if ( mbDisposed ) throw lang::DisposedException();
if ( mpListeners )
{
lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
mpListeners->disposeAndClear( aSource );
delete mpListeners;
mpListeners = NULL;
}
maItems.clear();
mbDisposed = sal_True;
}
void SAL_CALL LayoutRoot::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
throw ( uno::RuntimeException )
{
::osl::MutexGuard aGuard( maMutex );
if ( mbDisposed ) throw lang::DisposedException();
if ( !mpListeners )
mpListeners = new ::cppu::OInterfaceContainerHelper( maMutex );
mpListeners->addInterface( xListener );
}
void SAL_CALL LayoutRoot::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
throw ( uno::RuntimeException )
{
::osl::MutexGuard aGuard( maMutex );
if ( mbDisposed ) throw lang::DisposedException();
if ( mpListeners )
mpListeners->removeInterface( xListener );
}
// builder
LayoutWidget *LayoutRoot::create( OUString id, const OUString unoName, long attrbs,uno::Reference< awt::XLayoutContainer > xParent )
{
LayoutWidget *pWidget = new LayoutWidget( mxToolkit, xParent, unoName, attrbs );
if ( !mpToplevel )
{
mpToplevel = pWidget;
mxWindow = uno::Reference< awt::XWindow >( pWidget->getPeer(), uno::UNO_QUERY );
mxContainer = pWidget->mxContainer;
}
if ( pWidget->mxContainer.is() )
pWidget->mxContainer->setLayoutUnit( mxLayoutUnit );
if ( id.getLength() )
maItems[ id ] = pWidget->getPeer();
return pWidget;
}
#if 0
uno::Reference< awt::XLayoutConstrains > LayoutRoot::getToplevel()
{
if ( mpToplevel )
return mpToplevel->getPeer();
return uno::Reference< awt::XLayoutConstrains > ();
}
uno::Reference< awt::XLayoutConstrains > LayoutRoot::getById( OUString id )
{
uno::Reference< awt::XLayoutConstrains > rRef = 0;
ItemHash::iterator it = maItems.find( id );
if ( it != maItems.end() )
rRef = it->second;
return rRef;
}
#endif
LayoutWidget::LayoutWidget( uno::Reference< awt::XToolkit > xToolkit,
uno::Reference< awt::XLayoutContainer > xParent,
OUString unoName, long attrbs )
{
while ( xParent.is() && !uno::Reference< awt::XWindow >( xParent, uno::UNO_QUERY ).is() )
{
uno::Reference< awt::XLayoutContainer > xContainer( xParent, uno::UNO_QUERY );
assert( xContainer.is() );
xParent = uno::Reference< awt::XLayoutContainer >( xContainer->getParent(), uno::UNO_QUERY );
}
mxWidget = WidgetFactory::createWidget( xToolkit, xParent, unoName, attrbs );
assert( mxWidget.is() );
mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY );
}
LayoutWidget::~LayoutWidget()
{
/* should we dispose of the references...? */
// at least of its children... Or should root?
}
bool LayoutWidget::addChild( LayoutWidget *pChild )
{
if ( !mxContainer.is() )
return false;
try
{
mxContainer->addChild( pChild->mxWidget );
}
catch( awt::MaxChildrenException ex )
{
return false;
}
return true;
}
void LayoutWidget::setProperties( PropList const& rProps )
{
::layoutimpl::setProperties( mxWidget, rProps );
}
void LayoutWidget::setProperty( OUString const& attr, OUString const& value )
{
::layoutimpl::setProperty( mxWidget, attr, value );
}
void LayoutWidget::setChildProperties( LayoutWidget *pChild,
PropList const& rProps )
{
uno::Reference< beans::XPropertySet > xChildPeer;
xChildPeer = mxContainer->getChildProperties( pChild->mxWidget );
if ( xChildPeer.is() )
::layoutimpl::setProperties( xChildPeer, rProps );
}
} // namespace layoutimpl