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