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