xref: /trunk/main/toolkit/source/layout/core/root.cxx (revision 61161268)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "root.hxx"
25 
26 #include <cassert>
27 
28 #include <com/sun/star/awt/WindowAttribute.hpp>
29 #include <com/sun/star/awt/XMessageBox.hpp>
30 #include <com/sun/star/awt/MessageBoxButtons.hpp>
31 #include <com/sun/star/frame/XDesktop.hpp>
32 #include <com/sun/star/awt/XMessageBoxFactory.hpp>
33 #include <com/sun/star/xml/sax/SAXParseException.hpp>
34 #include <com/sun/star/xml/sax/XParser.hpp>
35 
36 #include "helper.hxx"
37 #include "import.hxx"
38 #include "timer.hxx"
39 #include "translate.hxx"
40 
41 namespace layoutimpl
42 {
43 
44 using namespace css;
45 using ::rtl::OUString;
46 
LayoutRoot(const uno::Reference<lang::XMultiServiceFactory> & xFactory)47 LayoutRoot::LayoutRoot( const uno::Reference< lang::XMultiServiceFactory >& xFactory )
48     : mbDisposed( sal_False )
49     , mxFactory( xFactory )
50     , mpListeners( NULL )
51     , mpToplevel( NULL )
52 {
53     if ( !xFactory.is() )
54         throw uno::RuntimeException();
55     mxLayoutUnit = uno::Reference< awt::XLayoutUnit >( new LayoutUnit() );
56 }
57 
~LayoutRoot()58 LayoutRoot::~LayoutRoot()
59 {
60 // TODO: we want to delete the top level LayoutWidget...
61     ::osl::MutexGuard aGuard( maMutex );
62     if ( !mbDisposed )
63     {
64         try
65         {
66             m_refCount++; // inhibit multiple destruction
67             dispose();
68         }
69         catch( uno::Exception& )
70         {
71         }
72     }
73 }
74 
ShowMessageBox(uno::Reference<lang::XMultiServiceFactory> const & xFactory,uno::Reference<awt::XToolkit> xToolkit,OUString const & aTitle,OUString const & aMessage)75 void ShowMessageBox( uno::Reference< lang::XMultiServiceFactory > const& xFactory, uno::Reference< awt::XToolkit > xToolkit, OUString const& aTitle, OUString const& aMessage )
76 {
77     uno::Reference< uno::XInterface > iDesktop = xFactory->createInstance
78         ( OUString::createFromAscii( "com.sun.star.frame.Desktop" ) );
79     uno::Reference< frame::XDesktop > xDesktop ( iDesktop, uno::UNO_QUERY );
80     uno::Reference< frame::XFrame > xFrame ( xDesktop->getCurrentFrame() );
81     uno::Reference< awt::XWindow > xContainerWindow( xFrame->getContainerWindow() );
82     uno::Reference< awt::XWindowPeer > xWindowPeer( xContainerWindow, uno::UNO_QUERY_THROW );
83     uno::Reference< awt::XMessageBoxFactory > xMessageBoxFactory( xToolkit, uno::UNO_QUERY );
84 
85     uno::Reference< awt::XMessageBox > xMessageBox
86         = xMessageBoxFactory->createMessageBox
87         ( xWindowPeer, awt::MessageBoxType_ERRORBOX,
88           awt::MessageBoxButtons::BUTTONS_OK, aTitle, aMessage );
89 
90     if ( xMessageBox.is() )
91         xMessageBox->execute();
92     //FIXME: exceptions not caught and printed at top level??
93     //else
94     //printf( "%s\n", OUSTRING_CSTR( aMessage ) );
95 }
96 
error(OUString const & message)97 void LayoutRoot::error( OUString const& message )
98 {
99     OSL_TRACE( "%s\n", OUSTRING_CSTR( message ) );
100     ShowMessageBox( mxFactory, mxToolkit,
101                     OUString::createFromAscii( "Fatal error" ),
102                     message );
103     throw uno::RuntimeException( message, uno::Reference< uno::XInterface >() );
104 }
105 
106 // XInitialization
initialize(const uno::Sequence<uno::Any> & aArguments)107 void SAL_CALL LayoutRoot::initialize( const uno::Sequence< uno::Any >& aArguments )
108     throw ( uno::Exception,
109             uno::RuntimeException )
110 {
111     ::osl::MutexGuard aGuard( maMutex );
112 
113     if ( mbDisposed )
114         throw lang::DisposedException();
115 
116     if ( mxContainer.is() ) // only 1 init ...
117         throw uno::Exception();
118 
119     if ( !aArguments.getLength() )
120         throw lang::IllegalArgumentException();
121 
122     OSL_ENSURE( aArguments.getLength() == 1, "Wrong arg count\n" );
123 
124     OUString aXMLName;
125     if ( !( aArguments[0] >>= aXMLName ) )
126         throw lang::IllegalArgumentException();
127 
128     uno::Reference< xml::sax::XParser > xParser
129         ( mxFactory->createInstance(
130             OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ) ),
131           uno::UNO_QUERY );
132     OSL_ASSERT( xParser.is() );
133     if (! xParser.is())
134     {
135         throw uno::RuntimeException(
136             OUString::createFromAscii( "cannot create sax-parser component" ),
137             uno::Reference< uno::XInterface >() );
138     }
139 
140     // FIXME: quite possibly we want to pass this in ...
141     uno::Reference< awt::XToolkit > xToolkit;
142 
143     mxToolkit = uno::Reference< awt::XToolkit >(
144         mxFactory->createInstance(
145             OUString::createFromAscii( "com.sun.star.awt.Toolkit" ) ),
146         uno::UNO_QUERY );
147 
148     if ( !mxToolkit.is() )
149         throw uno::RuntimeException(
150             OUString::createFromAscii( "failed to create toolkit!" ),
151             uno::Reference< uno::XInterface >() );
152 
153     OUString aXMLFile = readRightTranslation( aXMLName );
154     uno::Reference< io::XInputStream > xStream = getFileAsStream( aXMLFile );
155     if (! xStream.is() )
156         error( OUString::createFromAscii( "Installation problem: cannot find XML file:" ) + aXMLName );
157 
158     // error handler, entity resolver omitted
159 
160     ImportContext *pCtx = new ImportContext( *this );
161 
162     uno::Reference< xml::input::XRoot > xRoot( pCtx );
163     uno::Sequence < uno::Any > aArgs( 1 );
164     aArgs[0] <<= xRoot;
165     uno::Reference< xml::sax::XDocumentHandler > xDocHandler
166         (mxFactory->createInstanceWithArguments
167          ( OUString::createFromAscii( "com.sun.star.xml.input.SaxDocumentHandler" ),
168           aArgs ), uno::UNO_QUERY );
169 
170     if (! xDocHandler.is() )
171         error( OUString::createFromAscii( "cannot find SAx handler for document type of:") + aXMLName );
172 
173     xParser->setDocumentHandler( xDocHandler );
174 
175     xml::sax::InputSource source;
176     source.aInputStream = xStream;
177     source.sSystemId = OUString::createFromAscii( "virtual file" );
178 
179     try
180     {
181         xParser->parseStream( source );
182     }
183     catch ( xml::sax::SAXParseException& e )
184     {
185         OUString c = OUString::createFromAscii( ":" );
186         error( aXMLName
187                + c + OUString::valueOf( e.LineNumber )
188                + c + OUString::valueOf( e.ColumnNumber )
189                + c + OUString::createFromAscii( "Sax parse error" ) );
190     }
191 }
192 
193 // XLayoutContainer
getLayoutContainer()194 uno::Reference< awt::XLayoutContainer > LayoutRoot::getLayoutContainer() throw (uno::RuntimeException)
195 {
196     return uno::Reference< awt::XLayoutContainer >();
197 }
198 
199 // local helper ...
addItem(const OUString & rName,const uno::Reference<awt::XLayoutConstrains> & xRef)200 void LayoutRoot::addItem( const OUString &rName,
201                           const uno::Reference< awt::XLayoutConstrains > &xRef )
202 {
203     maItems[ rName ] = xRef;
204 }
205 
206 // XNameAccess
getByName(const OUString & rName)207 uno::Any SAL_CALL LayoutRoot::getByName( const OUString &rName )
208     throw ( container::NoSuchElementException,
209             lang::WrappedTargetException,
210             uno::RuntimeException )
211 {
212     ::osl::MutexGuard aGuard( maMutex );
213     if ( mbDisposed )
214         throw lang::DisposedException();
215 
216     uno::Reference< awt::XLayoutConstrains > xItem;
217     ItemHash::iterator i = maItems.find( rName );
218     if ( i != maItems.end() )
219         xItem = i->second;
220     return uno::makeAny( xItem );
221 }
222 
hasByName(const OUString & rName)223 sal_Bool SAL_CALL LayoutRoot::hasByName( const OUString &rName )
224     throw (uno::RuntimeException)
225 {
226     ::osl::MutexGuard aGuard( maMutex );
227     if ( mbDisposed ) throw lang::DisposedException();
228 
229     ItemHash::iterator i = maItems.find( rName );
230     return i != maItems.end();
231 }
232 
getElementNames()233 uno::Sequence< OUString > SAL_CALL LayoutRoot::getElementNames()
234     throw ( uno::RuntimeException )
235 {
236     ::osl::MutexGuard aGuard( maMutex );
237     if ( mbDisposed ) throw lang::DisposedException();
238 
239     uno::Sequence< OUString > aNames( maItems.size() );
240     sal_Int32 nPos = 0;
241 
242     for ( ItemHash::const_iterator it = maItems.begin();
243           it != maItems.end(); it++ )
244         aNames[ nPos++ ] = it->first;
245 
246     return aNames;
247 }
248 
getElementType()249 uno::Type SAL_CALL LayoutRoot::getElementType()
250     throw ( uno::RuntimeException )
251 {
252     return getCppuType( ( const uno::Reference< awt::XLayoutConstrains >* )NULL );
253 }
254 
hasElements()255 sal_Bool SAL_CALL LayoutRoot::hasElements()
256     throw ( uno::RuntimeException )
257 {
258     ::osl::MutexGuard aGuard( maMutex );
259 
260     if ( mbDisposed ) throw lang::DisposedException();
261 
262     return maItems.size() > 0;
263 }
264 
265 // XComponent
dispose()266 void SAL_CALL LayoutRoot::dispose()
267     throw ( uno::RuntimeException )
268 {
269     ::osl::MutexGuard aGuard( maMutex );
270 
271     if ( mbDisposed ) throw lang::DisposedException();
272 
273     if ( mpListeners )
274     {
275 
276         lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
277         mpListeners->disposeAndClear( aSource );
278         delete mpListeners;
279         mpListeners = NULL;
280     }
281 
282     maItems.clear();
283     mbDisposed = sal_True;
284 }
285 
addEventListener(const uno::Reference<lang::XEventListener> & xListener)286 void SAL_CALL LayoutRoot::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
287     throw ( uno::RuntimeException )
288 {
289     ::osl::MutexGuard aGuard( maMutex );
290 
291     if ( mbDisposed ) throw lang::DisposedException();
292 
293     if ( !mpListeners )
294         mpListeners = new ::cppu::OInterfaceContainerHelper( maMutex );
295     mpListeners->addInterface( xListener );
296 }
297 
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)298 void SAL_CALL LayoutRoot::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
299     throw ( uno::RuntimeException )
300 {
301     ::osl::MutexGuard aGuard( maMutex );
302 
303     if ( mbDisposed ) throw lang::DisposedException();
304 
305     if ( mpListeners )
306         mpListeners->removeInterface( xListener );
307 }
308 
309 // builder
310 
create(OUString id,const OUString unoName,long attrbs,uno::Reference<awt::XLayoutContainer> xParent)311 LayoutWidget *LayoutRoot::create( OUString id, const OUString unoName, long attrbs,uno::Reference< awt::XLayoutContainer > xParent )
312 {
313     LayoutWidget *pWidget = new LayoutWidget( mxToolkit, xParent, unoName, attrbs );
314     if ( !mpToplevel )
315     {
316         mpToplevel = pWidget;
317         mxWindow = uno::Reference< awt::XWindow >( pWidget->getPeer(), uno::UNO_QUERY );
318         mxContainer = pWidget->mxContainer;
319     }
320     if ( pWidget->mxContainer.is() )
321         pWidget->mxContainer->setLayoutUnit( mxLayoutUnit );
322     if ( id.getLength() )
323         maItems[ id ] = pWidget->getPeer();
324     return pWidget;
325 }
326 
327 #if 0
328 uno::Reference< awt::XLayoutConstrains > LayoutRoot::getToplevel()
329 {
330     if ( mpToplevel )
331         return mpToplevel->getPeer();
332     return uno::Reference< awt::XLayoutConstrains > ();
333 }
334 
335 uno::Reference< awt::XLayoutConstrains > LayoutRoot::getById( OUString id )
336 {
337     uno::Reference< awt::XLayoutConstrains > rRef = 0;
338     ItemHash::iterator it = maItems.find( id );
339     if ( it != maItems.end() )
340         rRef = it->second;
341     return rRef;
342 }
343 #endif
344 
LayoutWidget(uno::Reference<awt::XToolkit> xToolkit,uno::Reference<awt::XLayoutContainer> xParent,OUString unoName,long attrbs)345 LayoutWidget::LayoutWidget( uno::Reference< awt::XToolkit > xToolkit,
346                             uno::Reference< awt::XLayoutContainer > xParent,
347                             OUString unoName, long attrbs )
348 {
349     while ( xParent.is() && !uno::Reference< awt::XWindow >( xParent, uno::UNO_QUERY ).is() )
350     {
351         uno::Reference< awt::XLayoutContainer > xContainer( xParent, uno::UNO_QUERY );
352         assert( xContainer.is() );
353         xParent = uno::Reference< awt::XLayoutContainer >( xContainer->getParent(), uno::UNO_QUERY );
354     }
355 
356     mxWidget = WidgetFactory::createWidget( xToolkit, xParent, unoName, attrbs );
357     assert( mxWidget.is() );
358     mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY );
359 }
360 
~LayoutWidget()361 LayoutWidget::~LayoutWidget()
362 {
363     /* should we dispose of the references...? */
364     // at least of its children... Or should root?
365 }
366 
addChild(LayoutWidget * pChild)367 bool LayoutWidget::addChild( LayoutWidget *pChild )
368 {
369     if ( !mxContainer.is() )
370         return false;
371 
372     try
373     {
374         mxContainer->addChild( pChild->mxWidget );
375     }
376     catch( awt::MaxChildrenException ex )
377     {
378         return false;
379     }
380     return true;
381 }
382 
setProperties(PropList const & rProps)383 void LayoutWidget::setProperties( PropList const& rProps )
384 {
385     ::layoutimpl::setProperties( mxWidget, rProps );
386 }
387 
setProperty(OUString const & attr,OUString const & value)388 void LayoutWidget::setProperty( OUString const& attr, OUString const& value )
389 {
390     ::layoutimpl::setProperty( mxWidget, attr, value );
391 }
392 
setChildProperties(LayoutWidget * pChild,PropList const & rProps)393 void LayoutWidget::setChildProperties( LayoutWidget *pChild,
394                                        PropList const& rProps )
395 {
396     uno::Reference< beans::XPropertySet > xChildPeer;
397     xChildPeer = mxContainer->getChildProperties( pChild->mxWidget );
398 
399     if ( xChildPeer.is() )
400         ::layoutimpl::setProperties( xChildPeer, rProps );
401 }
402 
403 } // namespace layoutimpl
404 
405