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