xref: /aoo41x/main/toolkit/source/layout/core/root.cxx (revision b0724fc6)
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 
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 
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 
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     awt::Rectangle aRectangle;
86     uno::Reference< awt::XMessageBox > xMessageBox
87         = xMessageBoxFactory->createMessageBox
88         ( xWindowPeer, aRectangle, OUString::createFromAscii( "errorbox" ),
89           awt::MessageBoxButtons::BUTTONS_OK, aTitle, aMessage );
90 
91     if ( xMessageBox.is() )
92         xMessageBox->execute();
93     //FIXME: exceptions not caught and printed at top level??
94     //else
95     //printf( "%s\n", OUSTRING_CSTR( aMessage ) );
96 }
97 
98 void LayoutRoot::error( OUString const& message )
99 {
100     OSL_TRACE( "%s\n", OUSTRING_CSTR( message ) );
101     ShowMessageBox( mxFactory, mxToolkit,
102                     OUString::createFromAscii( "Fatal error" ),
103                     message );
104     throw uno::RuntimeException( message, uno::Reference< uno::XInterface >() );
105 }
106 
107 // XInitialization
108 void SAL_CALL LayoutRoot::initialize( const uno::Sequence< uno::Any >& aArguments )
109     throw ( uno::Exception,
110             uno::RuntimeException )
111 {
112     ::osl::MutexGuard aGuard( maMutex );
113 
114     if ( mbDisposed )
115         throw lang::DisposedException();
116 
117     if ( mxContainer.is() ) // only 1 init ...
118         throw uno::Exception();
119 
120     if ( !aArguments.getLength() )
121         throw lang::IllegalArgumentException();
122 
123     OSL_ENSURE( aArguments.getLength() == 1, "Wrong arg count\n" );
124 
125     OUString aXMLName;
126     if ( !( aArguments[0] >>= aXMLName ) )
127         throw lang::IllegalArgumentException();
128 
129     uno::Reference< xml::sax::XParser > xParser
130         ( mxFactory->createInstance(
131             OUString::createFromAscii( "com.sun.star.xml.sax.Parser" ) ),
132           uno::UNO_QUERY );
133     OSL_ASSERT( xParser.is() );
134     if (! xParser.is())
135     {
136         throw uno::RuntimeException(
137             OUString::createFromAscii( "cannot create sax-parser component" ),
138             uno::Reference< uno::XInterface >() );
139     }
140 
141     // FIXME: quite possibly we want to pass this in ...
142     uno::Reference< awt::XToolkit > xToolkit;
143 
144     mxToolkit = uno::Reference< awt::XToolkit >(
145         mxFactory->createInstance(
146             OUString::createFromAscii( "com.sun.star.awt.Toolkit" ) ),
147         uno::UNO_QUERY );
148 
149     if ( !mxToolkit.is() )
150         throw uno::RuntimeException(
151             OUString::createFromAscii( "failed to create toolkit!" ),
152             uno::Reference< uno::XInterface >() );
153 
154     OUString aXMLFile = readRightTranslation( aXMLName );
155     uno::Reference< io::XInputStream > xStream = getFileAsStream( aXMLFile );
156     if (! xStream.is() )
157         error( OUString::createFromAscii( "Installation problem: cannot find XML file:" ) + aXMLName );
158 
159     // error handler, entity resolver omitted
160 
161     ImportContext *pCtx = new ImportContext( *this );
162 
163     uno::Reference< xml::input::XRoot > xRoot( pCtx );
164     uno::Sequence < uno::Any > aArgs( 1 );
165     aArgs[0] <<= xRoot;
166     uno::Reference< xml::sax::XDocumentHandler > xDocHandler
167         (mxFactory->createInstanceWithArguments
168          ( OUString::createFromAscii( "com.sun.star.xml.input.SaxDocumentHandler" ),
169           aArgs ), uno::UNO_QUERY );
170 
171     if (! xDocHandler.is() )
172         error( OUString::createFromAscii( "cannot find SAx handler for document type of:") + aXMLName );
173 
174     xParser->setDocumentHandler( xDocHandler );
175 
176     xml::sax::InputSource source;
177     source.aInputStream = xStream;
178     source.sSystemId = OUString::createFromAscii( "virtual file" );
179 
180     try
181     {
182         xParser->parseStream( source );
183     }
184     catch ( xml::sax::SAXParseException& e )
185     {
186         OUString c = OUString::createFromAscii( ":" );
187         error( aXMLName
188                + c + OUString::valueOf( e.LineNumber )
189                + c + OUString::valueOf( e.ColumnNumber )
190                + c + OUString::createFromAscii( "Sax parse error" ) );
191     }
192 }
193 
194 // XLayoutContainer
195 uno::Reference< awt::XLayoutContainer > LayoutRoot::getLayoutContainer() throw (uno::RuntimeException)
196 {
197     return uno::Reference< awt::XLayoutContainer >();
198 }
199 
200 // local helper ...
201 void LayoutRoot::addItem( const OUString &rName,
202                           const uno::Reference< awt::XLayoutConstrains > &xRef )
203 {
204     maItems[ rName ] = xRef;
205 }
206 
207 // XNameAccess
208 uno::Any SAL_CALL LayoutRoot::getByName( const OUString &rName )
209     throw ( container::NoSuchElementException,
210             lang::WrappedTargetException,
211             uno::RuntimeException )
212 {
213     ::osl::MutexGuard aGuard( maMutex );
214     if ( mbDisposed )
215         throw lang::DisposedException();
216 
217     uno::Reference< awt::XLayoutConstrains > xItem;
218     ItemHash::iterator i = maItems.find( rName );
219     if ( i != maItems.end() )
220         xItem = i->second;
221     return uno::makeAny( xItem );
222 }
223 
224 sal_Bool SAL_CALL LayoutRoot::hasByName( const OUString &rName )
225     throw (uno::RuntimeException)
226 {
227     ::osl::MutexGuard aGuard( maMutex );
228     if ( mbDisposed ) throw lang::DisposedException();
229 
230     ItemHash::iterator i = maItems.find( rName );
231     return i != maItems.end();
232 }
233 
234 uno::Sequence< OUString > SAL_CALL LayoutRoot::getElementNames()
235     throw ( uno::RuntimeException )
236 {
237     ::osl::MutexGuard aGuard( maMutex );
238     if ( mbDisposed ) throw lang::DisposedException();
239 
240     uno::Sequence< OUString > aNames( maItems.size() );
241     sal_Int32 nPos = 0;
242 
243     for ( ItemHash::const_iterator it = maItems.begin();
244           it != maItems.end(); it++ )
245         aNames[ nPos++ ] = it->first;
246 
247     return aNames;
248 }
249 
250 uno::Type SAL_CALL LayoutRoot::getElementType()
251     throw ( uno::RuntimeException )
252 {
253     return getCppuType( ( const uno::Reference< awt::XLayoutConstrains >* )NULL );
254 }
255 
256 sal_Bool SAL_CALL LayoutRoot::hasElements()
257     throw ( uno::RuntimeException )
258 {
259     ::osl::MutexGuard aGuard( maMutex );
260 
261     if ( mbDisposed ) throw lang::DisposedException();
262 
263     return maItems.size() > 0;
264 }
265 
266 // XComponent
267 void SAL_CALL LayoutRoot::dispose()
268     throw ( uno::RuntimeException )
269 {
270     ::osl::MutexGuard aGuard( maMutex );
271 
272     if ( mbDisposed ) throw lang::DisposedException();
273 
274     if ( mpListeners )
275     {
276 
277         lang::EventObject aSource( static_cast< ::cppu::OWeakObject* >(this) );
278         mpListeners->disposeAndClear( aSource );
279         delete mpListeners;
280         mpListeners = NULL;
281     }
282 
283     maItems.clear();
284     mbDisposed = sal_True;
285 }
286 
287 void SAL_CALL LayoutRoot::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
288     throw ( uno::RuntimeException )
289 {
290     ::osl::MutexGuard aGuard( maMutex );
291 
292     if ( mbDisposed ) throw lang::DisposedException();
293 
294     if ( !mpListeners )
295         mpListeners = new ::cppu::OInterfaceContainerHelper( maMutex );
296     mpListeners->addInterface( xListener );
297 }
298 
299 void SAL_CALL LayoutRoot::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
300     throw ( uno::RuntimeException )
301 {
302     ::osl::MutexGuard aGuard( maMutex );
303 
304     if ( mbDisposed ) throw lang::DisposedException();
305 
306     if ( mpListeners )
307         mpListeners->removeInterface( xListener );
308 }
309 
310 // builder
311 
312 LayoutWidget *LayoutRoot::create( OUString id, const OUString unoName, long attrbs,uno::Reference< awt::XLayoutContainer > xParent )
313 {
314     LayoutWidget *pWidget = new LayoutWidget( mxToolkit, xParent, unoName, attrbs );
315     if ( !mpToplevel )
316     {
317         mpToplevel = pWidget;
318         mxWindow = uno::Reference< awt::XWindow >( pWidget->getPeer(), uno::UNO_QUERY );
319         mxContainer = pWidget->mxContainer;
320     }
321     if ( pWidget->mxContainer.is() )
322         pWidget->mxContainer->setLayoutUnit( mxLayoutUnit );
323     if ( id.getLength() )
324         maItems[ id ] = pWidget->getPeer();
325     return pWidget;
326 }
327 
328 #if 0
329 uno::Reference< awt::XLayoutConstrains > LayoutRoot::getToplevel()
330 {
331     if ( mpToplevel )
332         return mpToplevel->getPeer();
333     return uno::Reference< awt::XLayoutConstrains > ();
334 }
335 
336 uno::Reference< awt::XLayoutConstrains > LayoutRoot::getById( OUString id )
337 {
338     uno::Reference< awt::XLayoutConstrains > rRef = 0;
339     ItemHash::iterator it = maItems.find( id );
340     if ( it != maItems.end() )
341         rRef = it->second;
342     return rRef;
343 }
344 #endif
345 
346 LayoutWidget::LayoutWidget( uno::Reference< awt::XToolkit > xToolkit,
347                             uno::Reference< awt::XLayoutContainer > xParent,
348                             OUString unoName, long attrbs )
349 {
350     while ( xParent.is() && !uno::Reference< awt::XWindow >( xParent, uno::UNO_QUERY ).is() )
351     {
352         uno::Reference< awt::XLayoutContainer > xContainer( xParent, uno::UNO_QUERY );
353         assert( xContainer.is() );
354         xParent = uno::Reference< awt::XLayoutContainer >( xContainer->getParent(), uno::UNO_QUERY );
355     }
356 
357     mxWidget = WidgetFactory::createWidget( xToolkit, xParent, unoName, attrbs );
358     assert( mxWidget.is() );
359     mxContainer = uno::Reference< awt::XLayoutContainer >( mxWidget, uno::UNO_QUERY );
360 }
361 
362 LayoutWidget::~LayoutWidget()
363 {
364     /* should we dispose of the references...? */
365     // at least of its children... Or should root?
366 }
367 
368 bool LayoutWidget::addChild( LayoutWidget *pChild )
369 {
370     if ( !mxContainer.is() )
371         return false;
372 
373     try
374     {
375         mxContainer->addChild( pChild->mxWidget );
376     }
377     catch( awt::MaxChildrenException ex )
378     {
379         return false;
380     }
381     return true;
382 }
383 
384 void LayoutWidget::setProperties( PropList const& rProps )
385 {
386     ::layoutimpl::setProperties( mxWidget, rProps );
387 }
388 
389 void LayoutWidget::setProperty( OUString const& attr, OUString const& value )
390 {
391     ::layoutimpl::setProperty( mxWidget, attr, value );
392 }
393 
394 void LayoutWidget::setChildProperties( LayoutWidget *pChild,
395                                        PropList const& rProps )
396 {
397     uno::Reference< beans::XPropertySet > xChildPeer;
398     xChildPeer = mxContainer->getChildProperties( pChild->mxWidget );
399 
400     if ( xChildPeer.is() )
401         ::layoutimpl::setProperties( xChildPeer, rProps );
402 }
403 
404 } // namespace layoutimpl
405 
406