Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "browserids.hxx"
22 : #include "commontypes.hxx"
23 : #include "dataview.hxx"
24 : #include "dbu_misc.hrc"
25 : #include "dbustrings.hrc"
26 : #include "moduledbu.hxx"
27 : #include "dbsubcomponentcontroller.hxx"
28 :
29 : #include <com/sun/star/frame/XUntitledNumbers.hpp>
30 : #include <com/sun/star/beans/PropertyAttribute.hpp>
31 : #include <com/sun/star/container/XChild.hpp>
32 : #include <com/sun/star/container/XNameAccess.hpp>
33 : #include <com/sun/star/sdb/XDocumentDataSource.hpp>
34 : #include <com/sun/star/sdb/XOfficeDatabaseDocument.hpp>
35 : #include <com/sun/star/sdbc/XDataSource.hpp>
36 : #include <com/sun/star/util/NumberFormatter.hpp>
37 : #include <com/sun/star/lang/IllegalArgumentException.hpp>
38 :
39 : #include <comphelper/processfactory.hxx>
40 : #include <comphelper/sequence.hxx>
41 : #include <comphelper/types.hxx>
42 : #include <connectivity/dbexception.hxx>
43 : #include <connectivity/dbtools.hxx>
44 : #include <cppuhelper/typeprovider.hxx>
45 : #include <rtl/ustrbuf.hxx>
46 : #include <toolkit/unohlp.hxx>
47 : #include <tools/debug.hxx>
48 : #include <tools/diagnose_ex.h>
49 : #include <vcl/msgbox.hxx>
50 :
51 : //........................................................................
52 : namespace dbaui
53 : {
54 : //........................................................................
55 :
56 : /** === begin UNO using === **/
57 : using ::com::sun::star::uno::Any;
58 : using ::com::sun::star::uno::Reference;
59 : using ::com::sun::star::beans::XPropertySet;
60 : using ::com::sun::star::util::XNumberFormatter;
61 : using ::com::sun::star::lang::XMultiServiceFactory;
62 : using ::com::sun::star::uno::RuntimeException;
63 : using ::com::sun::star::uno::Sequence;
64 : using ::com::sun::star::uno::Type;
65 : using ::com::sun::star::sdbc::XConnection;
66 : using ::com::sun::star::uno::UNO_QUERY;
67 : using ::com::sun::star::container::XChild;
68 : using ::com::sun::star::sdbc::XDataSource;
69 : using ::com::sun::star::util::NumberFormatter;
70 : using ::com::sun::star::util::XNumberFormatter;
71 : using ::com::sun::star::util::XNumberFormatsSupplier;
72 : using ::com::sun::star::frame::XFrame;
73 : using ::com::sun::star::uno::Exception;
74 : using ::com::sun::star::sdbc::SQLException;
75 : using ::com::sun::star::lang::EventObject;
76 : using ::com::sun::star::beans::PropertyValue;
77 : using ::com::sun::star::frame::XModel;
78 : using ::com::sun::star::sdb::XOfficeDatabaseDocument;
79 : using ::com::sun::star::awt::XWindow;
80 : using ::com::sun::star::sdbc::XDatabaseMetaData;
81 : using ::com::sun::star::sdb::XDocumentDataSource;
82 : using ::com::sun::star::document::XEmbeddedScripts;
83 : using ::com::sun::star::lang::IllegalArgumentException;
84 : using ::com::sun::star::uno::UNO_SET_THROW;
85 : using ::com::sun::star::uno::UNO_QUERY_THROW;
86 : using ::com::sun::star::frame::XUntitledNumbers;
87 : using ::com::sun::star::beans::PropertyVetoException;
88 : /** === end UNO using === **/
89 :
90 0 : class DataSourceHolder
91 : {
92 : public:
93 0 : DataSourceHolder()
94 0 : {
95 0 : }
96 :
97 0 : DataSourceHolder( const Reference< XDataSource >& _rxDataSource )
98 0 : {
99 0 : m_xDataSource = _rxDataSource;
100 0 : Reference< XDocumentDataSource > xDocDS( m_xDataSource, UNO_QUERY );
101 0 : if ( xDocDS.is() )
102 0 : m_xDocument = xDocDS->getDatabaseDocument();
103 :
104 0 : m_xDataSourceProps.set( m_xDataSource, UNO_QUERY );
105 0 : }
106 :
107 0 : const Reference< XDataSource >& getDataSource() const { return m_xDataSource; }
108 0 : const Reference< XPropertySet >& getDataSourceProps() const { return m_xDataSourceProps; }
109 0 : const Reference< XOfficeDatabaseDocument > getDatabaseDocument() const { return m_xDocument; }
110 :
111 0 : bool is() const { return m_xDataSource.is(); }
112 :
113 0 : void clear()
114 : {
115 0 : m_xDataSource.clear();
116 0 : m_xDocument.clear();
117 0 : }
118 :
119 : private:
120 : Reference< XDataSource > m_xDataSource;
121 : Reference< XPropertySet > m_xDataSourceProps;
122 : Reference< XOfficeDatabaseDocument > m_xDocument;
123 : };
124 :
125 0 : struct DBSubComponentController_Impl
126 : {
127 : private:
128 : ::boost::optional< bool > m_aDocScriptSupport;
129 :
130 : public:
131 : OModuleClient m_aModuleClient;
132 : ::dbtools::SQLExceptionInfo m_aCurrentError;
133 :
134 : ::cppu::OInterfaceContainerHelper
135 : m_aModifyListeners;
136 :
137 : // <properties>
138 : SharedConnection m_xConnection;
139 : ::dbtools::DatabaseMetaData m_aSdbMetaData;
140 : // </properties>
141 : ::rtl::OUString m_sDataSourceName; // the data source we're working for
142 : DataSourceHolder m_aDataSource;
143 : Reference< XModel > m_xDocument;
144 : Reference< XNumberFormatter > m_xFormatter; // a number formatter working with the connection's NumberFormatsSupplier
145 : sal_Int32 m_nDocStartNumber;
146 : sal_Bool m_bSuspended; // is true when the controller was already suspended
147 : sal_Bool m_bEditable; // is the control readonly or not
148 : sal_Bool m_bModified; // is the data modified
149 : bool m_bNotAttached;
150 :
151 0 : DBSubComponentController_Impl( ::osl::Mutex& i_rMutex )
152 : :m_aDocScriptSupport()
153 : ,m_aModifyListeners( i_rMutex )
154 : ,m_nDocStartNumber(0)
155 : ,m_bSuspended( sal_False )
156 : ,m_bEditable(sal_True)
157 : ,m_bModified(sal_False)
158 0 : ,m_bNotAttached(true)
159 : {
160 0 : }
161 :
162 0 : bool documentHasScriptSupport() const
163 : {
164 : OSL_PRECOND( !!m_aDocScriptSupport,
165 : "DBSubComponentController_Impl::documentHasScriptSupport: not completely initialized, yet - don't know!?" );
166 0 : return !!m_aDocScriptSupport && *m_aDocScriptSupport;
167 : }
168 :
169 0 : void setDocumentScriptSupport( const bool _bSupport )
170 : {
171 : OSL_PRECOND( !m_aDocScriptSupport,
172 : "DBSubComponentController_Impl::setDocumentScriptSupport: already initialized!" );
173 0 : m_aDocScriptSupport = ::boost::optional< bool >( _bSupport );
174 0 : }
175 : };
176 :
177 : //====================================================================
178 : //= DBSubComponentController
179 : //====================================================================
180 : //--------------------------------------------------------------------
181 0 : DBSubComponentController::DBSubComponentController(const Reference< XMultiServiceFactory >& _rxORB)
182 : :DBSubComponentController_Base( _rxORB )
183 0 : ,m_pImpl( new DBSubComponentController_Impl( getMutex() ) )
184 : {
185 0 : }
186 :
187 : //--------------------------------------------------------------------
188 0 : DBSubComponentController::~DBSubComponentController()
189 : {
190 0 : }
191 :
192 : //--------------------------------------------------------------------
193 0 : void DBSubComponentController::impl_initialize()
194 : {
195 0 : OGenericUnoController::impl_initialize();
196 :
197 0 : const ::comphelper::NamedValueCollection& rArguments( getInitParams() );
198 :
199 0 : Reference< XConnection > xConnection;
200 0 : xConnection = rArguments.getOrDefault( (::rtl::OUString)PROPERTY_ACTIVE_CONNECTION, xConnection );
201 :
202 0 : if ( !xConnection.is() )
203 0 : ::dbtools::isEmbeddedInDatabase( getModel(), xConnection );
204 :
205 0 : if ( xConnection.is() )
206 0 : initializeConnection( xConnection );
207 :
208 0 : bool bShowError = true;
209 0 : if ( !isConnected() )
210 : {
211 0 : reconnect( sal_False );
212 0 : bShowError = false;
213 : }
214 0 : if ( !isConnected() )
215 : {
216 0 : if ( bShowError )
217 0 : connectionLostMessage();
218 0 : throw IllegalArgumentException();
219 0 : }
220 0 : }
221 :
222 : //--------------------------------------------------------------------
223 0 : Any SAL_CALL DBSubComponentController::queryInterface(const Type& _rType) throw (RuntimeException)
224 : {
225 0 : if ( _rType.equals( XScriptInvocationContext::static_type() ) )
226 : {
227 0 : if ( m_pImpl->documentHasScriptSupport() )
228 0 : return makeAny( Reference< XScriptInvocationContext >( this ) );
229 0 : return Any();
230 : }
231 :
232 0 : return DBSubComponentController_Base::queryInterface( _rType );
233 : }
234 :
235 : //--------------------------------------------------------------------
236 0 : Sequence< Type > SAL_CALL DBSubComponentController::getTypes( ) throw (RuntimeException)
237 : {
238 0 : Sequence< Type > aTypes( DBSubComponentController_Base::getTypes() );
239 0 : if ( !m_pImpl->documentHasScriptSupport() )
240 : {
241 0 : Sequence< Type > aStrippedTypes( aTypes.getLength() - 1 );
242 : ::std::remove_copy_if(
243 : aTypes.getConstArray(),
244 0 : aTypes.getConstArray() + aTypes.getLength(),
245 : aStrippedTypes.getArray(),
246 0 : ::std::bind2nd( ::std::equal_to< Type >(), XScriptInvocationContext::static_type() )
247 0 : );
248 0 : aTypes = aStrippedTypes;
249 : }
250 0 : return aTypes;
251 : }
252 :
253 : //--------------------------------------------------------------------
254 0 : void DBSubComponentController::initializeConnection( const Reference< XConnection >& _rxForeignConn )
255 : {
256 : DBG_ASSERT( !isConnected(), "DBSubComponentController::initializeConnection: not to be called when already connected!" );
257 : // usually this gets called from within initialize of derived classes ...
258 0 : if ( isConnected() )
259 0 : disconnect();
260 :
261 0 : m_pImpl->m_xConnection.reset( _rxForeignConn, SharedConnection::NoTakeOwnership );
262 0 : m_pImpl->m_aSdbMetaData.reset( m_pImpl->m_xConnection );
263 0 : startConnectionListening( m_pImpl->m_xConnection );
264 :
265 : // get the data source the connection belongs to
266 : try
267 : {
268 : // determine our data source
269 : OSL_PRECOND( !m_pImpl->m_aDataSource.is(), "DBSubComponentController::initializeConnection: already a data source in this phase?" );
270 : {
271 0 : Reference< XChild > xConnAsChild( m_pImpl->m_xConnection, UNO_QUERY );
272 0 : Reference< XDataSource > xDS;
273 0 : if ( xConnAsChild.is() )
274 0 : xDS = Reference< XDataSource >( xConnAsChild->getParent(), UNO_QUERY );
275 :
276 : // (take the indirection through XDataSource to ensure we have a correct object ....)
277 0 : m_pImpl->m_aDataSource = xDS;
278 : }
279 : OSL_POSTCOND( m_pImpl->m_aDataSource.is(), "DBSubComponentController::initializeConnection: unable to obtain the data source object!" );
280 :
281 0 : if ( m_pImpl->m_bNotAttached )
282 : {
283 0 : Reference< XUntitledNumbers > xUntitledProvider( getDatabaseDocument(), UNO_QUERY );
284 0 : m_pImpl->m_nDocStartNumber = 1;
285 0 : if ( xUntitledProvider.is() )
286 0 : m_pImpl->m_nDocStartNumber = xUntitledProvider->leaseNumber( static_cast< XWeak* >( this ) );
287 : }
288 :
289 : // determine the availability of script support in our document. Our own XScriptInvocationContext
290 : // interface depends on this
291 0 : m_pImpl->setDocumentScriptSupport( Reference< XEmbeddedScripts >( getDatabaseDocument(), UNO_QUERY ).is() );
292 :
293 : // get a number formatter
294 0 : Reference< XPropertySet > xDataSourceProps( m_pImpl->m_aDataSource.getDataSourceProps(), UNO_SET_THROW );
295 0 : xDataSourceProps->getPropertyValue( PROPERTY_NAME ) >>= m_pImpl->m_sDataSourceName;
296 : DBG_ASSERT( !m_pImpl->m_sDataSourceName.isEmpty(), "DBSubComponentController::initializeConnection: invalid data source name!" );
297 0 : Reference< XNumberFormatsSupplier> xSupplier = ::dbtools::getNumberFormats(m_pImpl->m_xConnection);
298 0 : if(xSupplier.is())
299 : {
300 0 : m_pImpl->m_xFormatter = Reference< XNumberFormatter >(
301 0 : NumberFormatter::create(comphelper::getComponentContext(getORB())), UNO_QUERY_THROW);
302 0 : m_pImpl->m_xFormatter->attachNumberFormatsSupplier(xSupplier);
303 : }
304 0 : OSL_ENSURE(m_pImpl->m_xFormatter.is(),"No NumberFormatter!");
305 : }
306 0 : catch( const Exception& )
307 : {
308 : DBG_UNHANDLED_EXCEPTION();
309 : }
310 0 : }
311 :
312 : //--------------------------------------------------------------------
313 0 : void DBSubComponentController::reconnect( sal_Bool _bUI )
314 : {
315 : OSL_ENSURE(!m_pImpl->m_bSuspended, "Cannot reconnect while suspended!");
316 :
317 0 : stopConnectionListening( m_pImpl->m_xConnection );
318 0 : m_pImpl->m_aSdbMetaData.reset( NULL );
319 0 : m_pImpl->m_xConnection.clear();
320 :
321 : // reconnect
322 0 : sal_Bool bReConnect = sal_True;
323 0 : if ( _bUI )
324 : {
325 0 : QueryBox aQuery( getView(), ModuleRes(QUERY_CONNECTION_LOST) );
326 0 : bReConnect = ( RET_YES == aQuery.Execute() );
327 : }
328 :
329 : // now really reconnect ...
330 0 : if ( bReConnect )
331 : {
332 0 : m_pImpl->m_xConnection.reset( connect( m_pImpl->m_aDataSource.getDataSource(), NULL ), SharedConnection::TakeOwnership );
333 0 : m_pImpl->m_aSdbMetaData.reset( m_pImpl->m_xConnection );
334 : }
335 :
336 : // invalidate all slots
337 0 : InvalidateAll();
338 0 : }
339 :
340 : //--------------------------------------------------------------------
341 0 : void DBSubComponentController::disconnect()
342 : {
343 0 : stopConnectionListening(m_pImpl->m_xConnection);
344 0 : m_pImpl->m_aSdbMetaData.reset( NULL );
345 0 : m_pImpl->m_xConnection.clear();
346 :
347 0 : InvalidateAll();
348 0 : }
349 :
350 : //--------------------------------------------------------------------
351 0 : void DBSubComponentController::losingConnection()
352 : {
353 : // our connection was disposed so we need a new one
354 0 : reconnect( sal_True );
355 0 : InvalidateAll();
356 0 : }
357 :
358 : //--------------------------------------------------------------------
359 0 : void SAL_CALL DBSubComponentController::disposing()
360 : {
361 0 : DBSubComponentController_Base::disposing();
362 :
363 0 : disconnect();
364 :
365 0 : attachFrame( Reference < XFrame >() );
366 :
367 0 : m_pImpl->m_aDataSource.clear();
368 0 : }
369 :
370 : //--------------------------------------------------------------------
371 0 : void SAL_CALL DBSubComponentController::disposing(const EventObject& _rSource) throw( RuntimeException )
372 : {
373 0 : if ( _rSource.Source == getConnection() )
374 : {
375 0 : if ( !m_pImpl->m_bSuspended // when already suspended then we don't have to reconnect
376 0 : && !getBroadcastHelper().bInDispose
377 0 : && !getBroadcastHelper().bDisposed
378 0 : && isConnected()
379 : )
380 : {
381 0 : losingConnection();
382 : }
383 : else
384 : {
385 0 : m_pImpl->m_xConnection.reset( m_pImpl->m_xConnection, SharedConnection::NoTakeOwnership );
386 : // this prevents the "disposeComponent" call in disconnect
387 0 : disconnect();
388 : }
389 : }
390 : else
391 0 : DBSubComponentController_Base::disposing( _rSource );
392 0 : }
393 :
394 : //--------------------------------------------------------------------
395 0 : void DBSubComponentController::appendError( const ::rtl::OUString& _rErrorMessage, const ::dbtools::StandardSQLState _eSQLState,
396 : const sal_Int32 _nErrorCode )
397 : {
398 0 : m_pImpl->m_aCurrentError.append( ::dbtools::SQLExceptionInfo::SQL_EXCEPTION, _rErrorMessage, getStandardSQLStateAscii( _eSQLState ),
399 0 : _nErrorCode );
400 0 : }
401 : //--------------------------------------------------------------------
402 0 : void DBSubComponentController::clearError()
403 : {
404 0 : m_pImpl->m_aCurrentError = ::dbtools::SQLExceptionInfo();
405 0 : }
406 :
407 : //--------------------------------------------------------------------
408 0 : sal_Bool DBSubComponentController::hasError() const
409 : {
410 0 : return m_pImpl->m_aCurrentError.isValid();
411 : }
412 :
413 : //--------------------------------------------------------------------
414 0 : const ::dbtools::SQLExceptionInfo& DBSubComponentController::getError() const
415 : {
416 0 : return m_pImpl->m_aCurrentError;
417 : }
418 :
419 : //--------------------------------------------------------------------
420 0 : void DBSubComponentController::displayError()
421 : {
422 0 : showError( m_pImpl->m_aCurrentError );
423 0 : }
424 :
425 : //--------------------------------------------------------------------
426 0 : sal_Bool SAL_CALL DBSubComponentController::suspend(sal_Bool bSuspend) throw( RuntimeException )
427 : {
428 0 : m_pImpl->m_bSuspended = bSuspend;
429 0 : if ( !bSuspend && !isConnected() )
430 0 : reconnect(sal_True);
431 :
432 :
433 0 : return sal_True;
434 : }
435 :
436 : // -----------------------------------------------------------------------------
437 0 : sal_Bool SAL_CALL DBSubComponentController::attachModel( const Reference< XModel > & _rxModel) throw( RuntimeException )
438 : {
439 0 : if ( !_rxModel.is() )
440 0 : return sal_False;
441 0 : if ( !DBSubComponentController_Base::attachModel( _rxModel ) )
442 0 : return sal_False;
443 :
444 0 : m_pImpl->m_bNotAttached = false;
445 0 : if ( m_pImpl->m_nDocStartNumber == 1 )
446 0 : releaseNumberForComponent();
447 :
448 0 : Reference< XUntitledNumbers > xUntitledProvider( _rxModel, UNO_QUERY );
449 0 : m_pImpl->m_nDocStartNumber = 1;
450 0 : if ( xUntitledProvider.is() )
451 0 : m_pImpl->m_nDocStartNumber = xUntitledProvider->leaseNumber( static_cast< XWeak* >( this ) );
452 :
453 0 : return sal_True;
454 : }
455 :
456 : // -----------------------------------------------------------------------------
457 0 : void DBSubComponentController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& _rArgs)
458 : {
459 0 : if ( _nId == ID_BROWSER_CLOSE )
460 : {
461 0 : closeTask();
462 0 : return;
463 : }
464 :
465 0 : DBSubComponentController_Base::Execute( _nId, _rArgs );
466 0 : InvalidateFeature( _nId );
467 : }
468 :
469 : // -----------------------------------------------------------------------------
470 0 : ::rtl::OUString DBSubComponentController::getDataSourceName() const
471 : {
472 0 : ::rtl::OUString sName;
473 0 : Reference< XPropertySet > xDataSourceProps( m_pImpl->m_aDataSource.getDataSourceProps() );
474 0 : if ( xDataSourceProps.is() )
475 0 : xDataSourceProps->getPropertyValue(PROPERTY_NAME) >>= sName;
476 0 : return sName;
477 : }
478 : // -----------------------------------------------------------------------------
479 0 : void DBSubComponentController::connectionLostMessage() const
480 : {
481 0 : String aMessage(ModuleRes(RID_STR_CONNECTION_LOST));
482 0 : Reference< XWindow > xWindow = getTopMostContainerWindow();
483 0 : Window* pWin = NULL;
484 0 : if ( xWindow.is() )
485 0 : pWin = VCLUnoHelper::GetWindow(xWindow);
486 0 : if ( !pWin )
487 0 : pWin = getView()->Window::GetParent();
488 :
489 0 : InfoBox(pWin, aMessage).Execute();
490 0 : }
491 : // -----------------------------------------------------------------------------
492 0 : const Reference< XConnection >& DBSubComponentController::getConnection() const
493 : {
494 0 : return m_pImpl->m_xConnection;
495 : }
496 :
497 : // -----------------------------------------------------------------------------
498 0 : sal_Bool DBSubComponentController::isReadOnly() const
499 : {
500 0 : return !m_pImpl->m_bEditable;
501 : }
502 :
503 : // -----------------------------------------------------------------------------
504 0 : sal_Bool DBSubComponentController::isEditable() const
505 : {
506 0 : return m_pImpl->m_bEditable;
507 : }
508 :
509 : // -----------------------------------------------------------------------------
510 0 : void DBSubComponentController::setEditable(sal_Bool _bEditable)
511 : {
512 0 : m_pImpl->m_bEditable = _bEditable;
513 0 : }
514 :
515 : // -----------------------------------------------------------------------------
516 0 : const ::dbtools::DatabaseMetaData& DBSubComponentController::getSdbMetaData() const
517 : {
518 0 : return m_pImpl->m_aSdbMetaData;
519 : }
520 :
521 : // -----------------------------------------------------------------------------
522 0 : sal_Bool DBSubComponentController::isConnected() const
523 : {
524 0 : return m_pImpl->m_xConnection.is();
525 : }
526 :
527 : // -----------------------------------------------------------------------------
528 0 : Reference< XDatabaseMetaData > DBSubComponentController::getMetaData( ) const
529 : {
530 0 : Reference< XDatabaseMetaData > xMeta;
531 : try
532 : {
533 0 : if ( isConnected() )
534 0 : xMeta.set( m_pImpl->m_xConnection->getMetaData(), UNO_SET_THROW );
535 : }
536 0 : catch( const Exception& )
537 : {
538 : DBG_UNHANDLED_EXCEPTION();
539 : }
540 0 : return xMeta;
541 : }
542 :
543 : // -----------------------------------------------------------------------------
544 0 : const Reference< XPropertySet >& DBSubComponentController::getDataSource() const
545 : {
546 0 : return m_pImpl->m_aDataSource.getDataSourceProps();
547 : }
548 :
549 : // -----------------------------------------------------------------------------
550 0 : sal_Bool DBSubComponentController::haveDataSource() const
551 : {
552 0 : return m_pImpl->m_aDataSource.is();
553 : }
554 :
555 : // -----------------------------------------------------------------------------
556 0 : Reference< XModel > DBSubComponentController::getDatabaseDocument() const
557 : {
558 0 : return Reference< XModel >( m_pImpl->m_aDataSource.getDatabaseDocument(), UNO_QUERY );
559 : }
560 :
561 : // -----------------------------------------------------------------------------
562 0 : Reference< XNumberFormatter > DBSubComponentController::getNumberFormatter() const
563 : {
564 0 : return m_pImpl->m_xFormatter;
565 : }
566 :
567 : // -----------------------------------------------------------------------------
568 0 : Reference< XModel > DBSubComponentController::getPrivateModel() const
569 : {
570 0 : return getDatabaseDocument();
571 : }
572 : // -----------------------------------------------------------------------------
573 : // XTitle
574 0 : ::rtl::OUString SAL_CALL DBSubComponentController::getTitle()
575 : throw (RuntimeException)
576 : {
577 0 : ::osl::MutexGuard aGuard( getMutex() );
578 0 : if ( m_bExternalTitle )
579 0 : return impl_getTitleHelper_throw()->getTitle ();
580 :
581 0 : ::rtl::OUStringBuffer sTitle;
582 0 : Reference< XTitle > xTitle(getPrivateModel(),UNO_QUERY);
583 0 : if ( xTitle.is() )
584 : {
585 0 : sTitle.append( xTitle->getTitle() );
586 0 : sTitle.appendAscii(" : ");
587 : }
588 0 : sTitle.append( getPrivateTitle() );
589 0 : return sTitle.makeStringAndClear();
590 : }
591 :
592 : // -----------------------------------------------------------------------------
593 0 : sal_Int32 DBSubComponentController::getCurrentStartNumber() const
594 : {
595 0 : return m_pImpl->m_nDocStartNumber;
596 : }
597 :
598 : // -----------------------------------------------------------------------------
599 0 : Reference< XEmbeddedScripts > SAL_CALL DBSubComponentController::getScriptContainer() throw (RuntimeException)
600 : {
601 0 : ::osl::MutexGuard aGuard( getMutex() );
602 0 : if ( !m_pImpl->documentHasScriptSupport() )
603 0 : return NULL;
604 :
605 0 : return Reference< XEmbeddedScripts >( getDatabaseDocument(), UNO_QUERY_THROW );
606 : }
607 :
608 : // -----------------------------------------------------------------------------
609 0 : void SAL_CALL DBSubComponentController::addModifyListener( const Reference< XModifyListener >& i_Listener ) throw (RuntimeException)
610 : {
611 0 : ::osl::MutexGuard aGuard( getMutex() );
612 0 : m_pImpl->m_aModifyListeners.addInterface( i_Listener );
613 0 : }
614 :
615 : // -----------------------------------------------------------------------------
616 0 : void SAL_CALL DBSubComponentController::removeModifyListener( const Reference< XModifyListener >& i_Listener ) throw (RuntimeException)
617 : {
618 0 : ::osl::MutexGuard aGuard( getMutex() );
619 0 : m_pImpl->m_aModifyListeners.removeInterface( i_Listener );
620 0 : }
621 :
622 : // -----------------------------------------------------------------------------
623 0 : ::sal_Bool SAL_CALL DBSubComponentController::isModified( ) throw (RuntimeException)
624 : {
625 0 : ::osl::MutexGuard aGuard( getMutex() );
626 0 : return impl_isModified();
627 : }
628 :
629 : // -----------------------------------------------------------------------------
630 0 : void SAL_CALL DBSubComponentController::setModified( ::sal_Bool i_bModified ) throw (PropertyVetoException, RuntimeException)
631 : {
632 0 : ::osl::ClearableMutexGuard aGuard( getMutex() );
633 :
634 0 : if ( m_pImpl->m_bModified == i_bModified )
635 0 : return;
636 :
637 0 : m_pImpl->m_bModified = i_bModified;
638 0 : impl_onModifyChanged();
639 :
640 0 : EventObject aEvent( *this );
641 0 : aGuard.clear();
642 0 : m_pImpl->m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvent );
643 : }
644 :
645 : // -----------------------------------------------------------------------------
646 0 : sal_Bool DBSubComponentController::impl_isModified() const
647 : {
648 0 : return m_pImpl->m_bModified;
649 : }
650 :
651 : // -----------------------------------------------------------------------------
652 0 : void DBSubComponentController::impl_onModifyChanged()
653 : {
654 0 : InvalidateFeature( ID_BROWSER_SAVEDOC );
655 0 : if ( isFeatureSupported( ID_BROWSER_SAVEASDOC ) )
656 0 : InvalidateFeature( ID_BROWSER_SAVEASDOC );
657 0 : }
658 :
659 : //........................................................................
660 : } // namespace dbaui
661 : //........................................................................
662 :
663 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|