1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_dbaccess.hxx" 30 31 #include "AppController.hxx" 32 #include "AppDetailView.hxx" 33 #include "AppView.hxx" 34 #include "dbaccess_slotid.hrc" 35 #include "dbu_app.hrc" 36 #include "dbustrings.hrc" 37 #include "defaultobjectnamecheck.hxx" 38 #include "dlgsave.hxx" 39 #include "UITools.hxx" 40 #include "subcomponentmanager.hxx" 41 42 /** === begin UNO includes === **/ 43 #include <com/sun/star/container/XChild.hpp> 44 #include <com/sun/star/container/XContainer.hpp> 45 #include <com/sun/star/container/XHierarchicalNameContainer.hpp> 46 #include <com/sun/star/container/XNameAccess.hpp> 47 #include <com/sun/star/container/XNameContainer.hpp> 48 #include <com/sun/star/lang/XEventListener.hpp> 49 #include <com/sun/star/sdb/CommandType.hpp> 50 #include <com/sun/star/sdb/SQLContext.hpp> 51 #include <com/sun/star/sdb/XQueriesSupplier.hpp> 52 #include <com/sun/star/sdbcx/XRename.hpp> 53 #include <com/sun/star/sdb/ErrorCondition.hpp> 54 #include <com/sun/star/sdb/application/DatabaseObject.hpp> 55 #include <com/sun/star/sdb/SQLContext.hpp> 56 #include <com/sun/star/sdbcx/XTablesSupplier.hpp> 57 #include <com/sun/star/sdbcx/XViewsSupplier.hpp> 58 #include <com/sun/star/ucb/Command.hpp> 59 #include <com/sun/star/ucb/XCommandEnvironment.hpp> 60 #include <com/sun/star/ucb/XCommandProcessor.hpp> 61 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> 62 #include <com/sun/star/uno/XNamingService.hpp> 63 #include <com/sun/star/util/XCloseable.hpp> 64 #include <com/sun/star/util/XRefreshable.hpp> 65 #include <com/sun/star/lang/XEventListener.hpp> 66 /** === end UNO includes === **/ 67 68 #include <cppuhelper/exc_hlp.hxx> 69 #include <connectivity/dbexception.hxx> 70 #include <connectivity/dbtools.hxx> 71 #include <connectivity/sqlerror.hxx> 72 #include <connectivity/dbexception.hxx> 73 #include <sfx2/mailmodelapi.hxx> 74 #include <svx/dbaexchange.hxx> 75 #include <toolkit/unohlp.hxx> 76 #include <tools/diagnose_ex.h> 77 #include <tools/urlobj.hxx> 78 #include <unotools/bootstrap.hxx> 79 #include <vcl/mnemonic.hxx> 80 #include <vcl/svapp.hxx> 81 #include <vcl/waitobj.hxx> 82 #include <vos/mutex.hxx> 83 84 //........................................................................ 85 namespace dbaui 86 { 87 using namespace ::dbtools; 88 using namespace ::connectivity; 89 using namespace ::svx; 90 using namespace ::com::sun::star; 91 using namespace ::com::sun::star::uno; 92 using namespace ::com::sun::star::awt; 93 using namespace ::com::sun::star::util; 94 using namespace ::com::sun::star::frame; 95 using namespace ::com::sun::star::lang; 96 using namespace ::com::sun::star::ui::dialogs; 97 using namespace ::com::sun::star::sdb; 98 using namespace ::com::sun::star::sdbc; 99 using namespace ::com::sun::star::sdbcx; 100 using namespace ::com::sun::star::beans; 101 using namespace ::com::sun::star::container; 102 using namespace ::com::sun::star::ucb; 103 104 /** === begin UNO using === **/ 105 using ::com::sun::star::util::XCloseable; 106 using ::com::sun::star::ui::XContextMenuInterceptor; 107 /** === end UNO using === **/ 108 109 namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject; 110 namespace ErrorCondition = ::com::sun::star::sdb::ErrorCondition; 111 112 //........................................................................ 113 // ----------------------------------------------------------------------------- 114 115 class CloseChecker : public ::cppu::WeakImplHelper1< com::sun::star::lang::XEventListener > 116 { 117 bool m_bClosed; 118 119 public: 120 CloseChecker() 121 :m_bClosed( false ) 122 { 123 } 124 125 virtual ~CloseChecker() 126 { 127 } 128 129 bool isClosed() 130 { 131 return true; 132 } 133 134 // interface XEventListener 135 virtual void SAL_CALL disposing( const EventObject& /*Source*/ ) throw( RuntimeException ) 136 { 137 m_bClosed = true; 138 } 139 140 }; 141 // ----------------------------------------------------------------------------- 142 void OApplicationController::convertToView(const ::rtl::OUString& _sName) 143 { 144 try 145 { 146 SharedConnection xConnection( getConnection() ); 147 Reference< XQueriesSupplier > xSup( xConnection, UNO_QUERY_THROW ); 148 Reference< XNameAccess > xQueries( xSup->getQueries(), UNO_QUERY_THROW ); 149 Reference< XPropertySet > xSourceObject( xQueries->getByName( _sName ), UNO_QUERY_THROW ); 150 151 Reference< XTablesSupplier > xTablesSup( xConnection, UNO_QUERY_THROW ); 152 Reference< XNameAccess > xTables( xTablesSup->getTables(), UNO_QUERY_THROW ); 153 154 Reference< XDatabaseMetaData > xMeta = xConnection->getMetaData(); 155 156 String aName = String(ModuleRes(STR_TBL_TITLE)); 157 aName = aName.GetToken(0,' '); 158 String aDefaultName = ::dbaui::createDefaultName(xMeta,xTables,aName); 159 160 DynamicTableOrQueryNameCheck aNameChecker( xConnection, CommandType::TABLE ); 161 OSaveAsDlg aDlg( getView(), CommandType::TABLE, getORB(), xConnection, aDefaultName, aNameChecker ); 162 if ( aDlg.Execute() == RET_OK ) 163 { 164 ::rtl::OUString sName = aDlg.getName(); 165 ::rtl::OUString sCatalog = aDlg.getCatalog(); 166 ::rtl::OUString sSchema = aDlg.getSchema(); 167 ::rtl::OUString sNewName( 168 ::dbtools::composeTableName( xMeta, sCatalog, sSchema, sName, sal_False, ::dbtools::eInTableDefinitions ) ); 169 Reference<XPropertySet> xView = ::dbaui::createView(sNewName,xConnection,xSourceObject); 170 if ( !xView.is() ) 171 throw SQLException(String(ModuleRes(STR_NO_TABLE_FORMAT_INSIDE)),*this,::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")) ,0,Any()); 172 getContainer()->elementAdded(E_TABLE,sNewName,makeAny(xView)); 173 } 174 } 175 catch(const SQLException& ) 176 { 177 showError( SQLExceptionInfo( ::cppu::getCaughtException() ) ); 178 } 179 catch( const Exception& ) 180 { 181 DBG_UNHANDLED_EXCEPTION(); 182 } 183 } 184 // ----------------------------------------------------------------------------- 185 void OApplicationController::pasteFormat(sal_uInt32 _nFormatId) 186 { 187 if ( _nFormatId ) 188 { 189 try 190 { 191 const TransferableDataHelper& rClipboard = getViewClipboard(); 192 ElementType eType = getContainer()->getElementType(); 193 if ( eType == E_TABLE ) 194 { 195 m_aTableCopyHelper.pasteTable( _nFormatId, rClipboard, getDatabaseName(), ensureConnection() ); 196 } 197 else 198 paste( eType, ODataAccessObjectTransferable::extractObjectDescriptor( rClipboard ) ); 199 200 } 201 catch( const Exception& ) 202 { 203 DBG_UNHANDLED_EXCEPTION(); 204 } 205 } 206 } 207 // ----------------------------------------------------------------------------- 208 void OApplicationController::openDataSourceAdminDialog() 209 { 210 openDialog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.DatasourceAdministrationDialog" ) ) ); 211 } 212 213 // ----------------------------------------------------------------------------- 214 void OApplicationController::openDialog( const ::rtl::OUString& _sServiceName ) 215 { 216 try 217 { 218 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 219 ::osl::MutexGuard aGuard( getMutex() ); 220 WaitObject aWO(getView()); 221 222 Sequence< Any > aArgs(3); 223 sal_Int32 nArgPos = 0; 224 225 Reference< ::com::sun::star::awt::XWindow> xWindow = getTopMostContainerWindow(); 226 if ( !xWindow.is() ) 227 { 228 DBG_ASSERT( getContainer(), "OApplicationController::Construct: have no view!" ); 229 if ( getContainer() ) 230 xWindow = VCLUnoHelper::GetInterface(getView()->Window::GetParent()); 231 } 232 // the parent window 233 aArgs[nArgPos++] <<= PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParentWindow")), 234 0, 235 makeAny(xWindow), 236 PropertyState_DIRECT_VALUE); 237 238 // the initial selection 239 ::rtl::OUString sInitialSelection; 240 if ( getContainer() ) 241 sInitialSelection = getDatabaseName(); 242 if ( sInitialSelection.getLength() ) 243 { 244 aArgs[ nArgPos++ ] <<= PropertyValue( 245 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InitialSelection" ) ), 0, 246 makeAny( sInitialSelection ), PropertyState_DIRECT_VALUE ); 247 } 248 249 SharedConnection xConnection( getConnection() ); 250 if ( xConnection.is() ) 251 { 252 aArgs[ nArgPos++ ] <<= PropertyValue( 253 PROPERTY_ACTIVE_CONNECTION, 0, 254 makeAny( xConnection ), PropertyState_DIRECT_VALUE ); 255 } 256 aArgs.realloc( nArgPos ); 257 258 // create the dialog 259 Reference< XExecutableDialog > xAdminDialog; 260 xAdminDialog = Reference< XExecutableDialog >( 261 getORB()->createInstanceWithArguments(_sServiceName,aArgs), UNO_QUERY); 262 263 // execute it 264 if (xAdminDialog.is()) 265 xAdminDialog->execute(); 266 } 267 catch( const Exception& ) 268 { 269 DBG_UNHANDLED_EXCEPTION(); 270 } 271 } 272 // ----------------------------------------------------------------------------- 273 void OApplicationController::openTableFilterDialog() 274 { 275 openDialog( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sdb.TableFilterDialog" ) ) ); 276 } 277 278 // ----------------------------------------------------------------------------- 279 void OApplicationController::refreshTables() 280 { 281 if ( getContainer() && getContainer()->getDetailView() ) 282 { 283 WaitObject aWO(getView()); 284 OSL_ENSURE(getContainer()->getElementType() == E_TABLE,"Only allowed when the tables container is selected!"); 285 try 286 { 287 Reference<XRefreshable> xRefresh(getElements(E_TABLE),UNO_QUERY); 288 if ( xRefresh.is() ) 289 xRefresh->refresh(); 290 } 291 catch(const Exception&) 292 { 293 OSL_ENSURE(0,"Could not refresh tables!"); 294 } 295 296 getContainer()->getDetailView()->clearPages(sal_False); 297 getContainer()->getDetailView()->createTablesPage( ensureConnection() ); 298 } 299 } 300 // ----------------------------------------------------------------------------- 301 void OApplicationController::openDirectSQLDialog() 302 { 303 openDialog( SERVICE_SDB_DIRECTSQLDIALOG ); 304 } 305 // ----------------------------------------------------------------------------- 306 void SAL_CALL OApplicationController::propertyChange( const PropertyChangeEvent& evt ) throw (RuntimeException) 307 { 308 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 309 ::osl::MutexGuard aGuard( getMutex() ); 310 if ( evt.PropertyName == PROPERTY_USER ) 311 { 312 m_bNeedToReconnect = sal_True; 313 InvalidateFeature(SID_DB_APP_STATUS_USERNAME); 314 } 315 else if ( evt.PropertyName == PROPERTY_URL ) 316 { 317 m_bNeedToReconnect = sal_True; 318 InvalidateFeature(SID_DB_APP_STATUS_DBNAME); 319 InvalidateFeature(SID_DB_APP_STATUS_TYPE); 320 InvalidateFeature(SID_DB_APP_STATUS_HOSTNAME); 321 } 322 else if ( PROPERTY_NAME == evt.PropertyName ) 323 { 324 const ElementType eType = getContainer()->getElementType(); 325 if ( eType == E_FORM || eType == E_REPORT ) 326 { 327 ::rtl::OUString sOldName,sNewName; 328 evt.OldValue >>= sOldName; 329 evt.NewValue >>= sNewName; 330 331 // if the old name is empty, then this is a newly inserted content. We're notified of it via the 332 // elementInserted method, so there's no need to handle it here. 333 334 if ( sOldName.getLength() ) 335 { 336 Reference<XChild> xChild(evt.Source,UNO_QUERY); 337 if ( xChild.is() ) 338 { 339 Reference<XContent> xContent(xChild->getParent(),UNO_QUERY); 340 if ( xContent.is() ) 341 sOldName = xContent->getIdentifier()->getContentIdentifier() + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/")) + sOldName; 342 } 343 344 getContainer()->elementReplaced( eType , sOldName, sNewName ); 345 } 346 } 347 } 348 349 EventObject aEvt; 350 aEvt.Source = m_xModel; 351 modified(aEvt); 352 } 353 354 // ----------------------------------------------------------------------------- 355 Reference< XDataSource > SAL_CALL OApplicationController::getDataSource() throw (RuntimeException) 356 { 357 ::osl::MutexGuard aGuard( getMutex() ); 358 Reference< XDataSource > xDataSource( m_xDataSource, UNO_QUERY ); 359 return xDataSource; 360 } 361 362 // ----------------------------------------------------------------------------- 363 Reference< XWindow > SAL_CALL OApplicationController::getApplicationMainWindow() throw (RuntimeException) 364 { 365 ::osl::MutexGuard aGuard( getMutex() ); 366 Reference< XFrame > xFrame( getFrame(), UNO_QUERY_THROW ); 367 Reference< XWindow > xWindow( xFrame->getContainerWindow(), UNO_QUERY_THROW ); 368 return xWindow; 369 } 370 371 // ----------------------------------------------------------------------------- 372 Sequence< Reference< XComponent > > SAL_CALL OApplicationController::getSubComponents() throw (RuntimeException) 373 { 374 ::osl::MutexGuard aGuard( getMutex() ); 375 return m_pSubComponentManager->getSubComponents(); 376 } 377 378 // ----------------------------------------------------------------------------- 379 Reference< XConnection > SAL_CALL OApplicationController::getActiveConnection() throw (RuntimeException) 380 { 381 ::osl::MutexGuard aGuard( getMutex() ); 382 return m_xDataSourceConnection.getTyped(); 383 } 384 385 // ----------------------------------------------------------------------------- 386 ::sal_Bool SAL_CALL OApplicationController::isConnected( ) throw (RuntimeException) 387 { 388 ::osl::MutexGuard aGuard( getMutex() ); 389 return m_xDataSourceConnection.is(); 390 } 391 392 // ----------------------------------------------------------------------------- 393 void SAL_CALL OApplicationController::connect( ) throw (SQLException, RuntimeException) 394 { 395 ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); 396 ::osl::MutexGuard aGuard( getMutex() ); 397 398 SQLExceptionInfo aError; 399 SharedConnection xConnection = ensureConnection( &aError ); 400 if ( !xConnection.is() ) 401 { 402 if ( aError.isValid() ) 403 aError.doThrow(); 404 405 // no particular error, but nonetheless could not connect -> throw a generic exception 406 String sConnectingContext( ModuleRes( STR_COULDNOTCONNECT_DATASOURCE ) ); 407 sConnectingContext.SearchAndReplaceAscii( "$name$", getStrippedDatabaseName() ); 408 ::dbtools::throwGenericSQLException( sConnectingContext, *this ); 409 } 410 } 411 412 // ----------------------------------------------------------------------------- 413 beans::Pair< ::sal_Int32, ::rtl::OUString > SAL_CALL OApplicationController::identifySubComponent( const Reference< XComponent >& i_rSubComponent ) throw (IllegalArgumentException, RuntimeException) 414 { 415 ::osl::MutexGuard aGuard( getMutex() ); 416 417 sal_Int32 nType = -1; 418 ::rtl::OUString sName; 419 420 if ( !m_pSubComponentManager->lookupSubComponent( i_rSubComponent, sName, nType ) ) 421 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); 422 423 if ( nType == SID_DB_APP_DSRELDESIGN ) 424 // this is somewhat hacky ... we're expected to return a DatabaseObject value. However, there is no such 425 // value for the relation design. /me thinks we should change the API definition here ... 426 nType = -1; 427 428 return beans::Pair< ::sal_Int32, ::rtl::OUString >( nType, sName ); 429 } 430 431 // ----------------------------------------------------------------------------- 432 ::sal_Bool SAL_CALL OApplicationController::closeSubComponents( ) throw (RuntimeException) 433 { 434 ::vos::OGuard aSolarGuard(Application::GetSolarMutex()); 435 ::osl::MutexGuard aGuard( getMutex() ); 436 return m_pSubComponentManager->closeSubComponents(); 437 } 438 439 440 // ----------------------------------------------------------------------------- 441 namespace 442 { 443 ElementType lcl_objectType2ElementType( const sal_Int32 _nObjectType ) 444 { 445 ElementType eType( E_NONE ); 446 switch ( _nObjectType ) 447 { 448 case DatabaseObject::TABLE: eType = E_TABLE; break; 449 case DatabaseObject::QUERY: eType = E_QUERY; break; 450 case DatabaseObject::FORM: eType = E_FORM; break; 451 case DatabaseObject::REPORT: eType = E_REPORT; break; 452 default: 453 OSL_ENSURE( false, "lcl_objectType2ElementType: unsupported object type!" ); 454 // this should have been caught earlier 455 } 456 return eType; 457 } 458 } 459 460 // ----------------------------------------------------------------------------- 461 void OApplicationController::impl_validateObjectTypeAndName_throw( const sal_Int32 _nObjectType, const ::boost::optional< ::rtl::OUString >& i_rObjectName ) 462 { 463 // ensure we're connected 464 if ( !isConnected() ) 465 { 466 SQLError aError( getORB() ); 467 aError.raiseException( ErrorCondition::DB_NOT_CONNECTED, *this ); 468 } 469 470 // ensure a proper object type 471 if ( ( _nObjectType != DatabaseObject::TABLE ) 472 && ( _nObjectType != DatabaseObject::QUERY ) 473 && ( _nObjectType != DatabaseObject::FORM ) 474 && ( _nObjectType != DatabaseObject::REPORT ) 475 ) 476 throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); 477 478 if ( !i_rObjectName ) 479 return; 480 481 // ensure an existing object 482 Reference< XNameAccess > xContainer( getElements( lcl_objectType2ElementType( _nObjectType ) ) ); 483 if ( !xContainer.is() ) 484 // all possible reasons for this (e.g. not being connected currently) should 485 // have been handled before 486 throw RuntimeException( ::rtl::OUString(), *this ); 487 488 bool bExistentObject = false; 489 switch ( _nObjectType ) 490 { 491 case DatabaseObject::TABLE: 492 case DatabaseObject::QUERY: 493 bExistentObject = xContainer->hasByName( *i_rObjectName ); 494 break; 495 case DatabaseObject::FORM: 496 case DatabaseObject::REPORT: 497 { 498 Reference< XHierarchicalNameAccess > xHierarchy( xContainer, UNO_QUERY_THROW ); 499 bExistentObject = xHierarchy->hasByHierarchicalName( *i_rObjectName ); 500 } 501 break; 502 } 503 504 if ( !bExistentObject ) 505 throw NoSuchElementException( *i_rObjectName, *this ); 506 } 507 508 // ----------------------------------------------------------------------------- 509 Reference< XComponent > SAL_CALL OApplicationController::loadComponent( ::sal_Int32 _ObjectType, 510 const ::rtl::OUString& _ObjectName, ::sal_Bool _ForEditing ) throw (IllegalArgumentException, NoSuchElementException, SQLException, RuntimeException) 511 { 512 return loadComponentWithArguments( _ObjectType, _ObjectName, _ForEditing, Sequence< PropertyValue >() ); 513 } 514 515 // ----------------------------------------------------------------------------- 516 Reference< XComponent > SAL_CALL OApplicationController::loadComponentWithArguments( ::sal_Int32 _ObjectType, 517 const ::rtl::OUString& _ObjectName, ::sal_Bool _ForEditing, const Sequence< PropertyValue >& _Arguments ) throw (IllegalArgumentException, NoSuchElementException, SQLException, RuntimeException) 518 { 519 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 520 ::osl::MutexGuard aGuard( getMutex() ); 521 522 impl_validateObjectTypeAndName_throw( _ObjectType, _ObjectName ); 523 524 Reference< XComponent > xComponent( openElementWithArguments( 525 _ObjectName, 526 lcl_objectType2ElementType( _ObjectType ), 527 _ForEditing ? E_OPEN_DESIGN : E_OPEN_NORMAL, 528 _ForEditing ? SID_DB_APP_EDIT : SID_DB_APP_OPEN, 529 ::comphelper::NamedValueCollection( _Arguments ) 530 ) ); 531 532 return xComponent; 533 } 534 535 // ----------------------------------------------------------------------------- 536 Reference< XComponent > SAL_CALL OApplicationController::createComponent( ::sal_Int32 i_nObjectType, Reference< XComponent >& o_DocumentDefinition ) throw (IllegalArgumentException, SQLException, RuntimeException) 537 { 538 return createComponentWithArguments( i_nObjectType, Sequence< PropertyValue >(), o_DocumentDefinition ); 539 } 540 541 // ----------------------------------------------------------------------------- 542 Reference< XComponent > SAL_CALL OApplicationController::createComponentWithArguments( ::sal_Int32 i_nObjectType, const Sequence< PropertyValue >& i_rArguments, Reference< XComponent >& o_DocumentDefinition ) throw (IllegalArgumentException, SQLException, RuntimeException) 543 { 544 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 545 ::osl::MutexGuard aGuard( getMutex() ); 546 547 impl_validateObjectTypeAndName_throw( i_nObjectType, ::boost::optional< ::rtl::OUString >() ); 548 549 Reference< XComponent > xComponent( newElement( 550 lcl_objectType2ElementType( i_nObjectType ), 551 ::comphelper::NamedValueCollection( i_rArguments ), 552 o_DocumentDefinition 553 ) ); 554 555 return xComponent; 556 } 557 558 // ----------------------------------------------------------------------------- 559 void SAL_CALL OApplicationController::registerContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException) 560 { 561 if ( _Interceptor.is() ) 562 m_aContextMenuInterceptors.addInterface( _Interceptor ); 563 } 564 565 // ----------------------------------------------------------------------------- 566 void SAL_CALL OApplicationController::releaseContextMenuInterceptor( const Reference< XContextMenuInterceptor >& _Interceptor ) throw (RuntimeException) 567 { 568 m_aContextMenuInterceptors.removeInterface( _Interceptor ); 569 } 570 571 // ----------------------------------------------------------------------------- 572 void OApplicationController::previewChanged( sal_Int32 _nMode ) 573 { 574 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 575 ::osl::MutexGuard aGuard( getMutex() ); 576 577 if ( m_xDataSource.is() && !isDataSourceReadOnly() ) 578 { 579 try 580 { 581 ::comphelper::NamedValueCollection aLayoutInfo( m_xDataSource->getPropertyValue( PROPERTY_LAYOUTINFORMATION ) ); 582 sal_Int32 nOldMode = aLayoutInfo.getOrDefault( "Preview", _nMode ); 583 if ( nOldMode != _nMode ) 584 { 585 aLayoutInfo.put( "Preview", _nMode ); 586 m_xDataSource->setPropertyValue( PROPERTY_LAYOUTINFORMATION, makeAny( aLayoutInfo.getPropertyValues() ) ); 587 } 588 } 589 catch ( const Exception& ) 590 { 591 DBG_UNHANDLED_EXCEPTION(); 592 } 593 } 594 InvalidateFeature(SID_DB_APP_DISABLE_PREVIEW); 595 InvalidateFeature(SID_DB_APP_VIEW_DOCINFO_PREVIEW); 596 InvalidateFeature(SID_DB_APP_VIEW_DOC_PREVIEW); 597 } 598 // ----------------------------------------------------------------------------- 599 //void OApplicationController::updateTitle() 600 //{ 601 // ::rtl::OUString sName = getStrippedDatabaseName(); 602 // 603 // String sTitle = String(ModuleRes(STR_APP_TITLE)); 604 // sName = sName + sTitle; 605 //#ifdef DBG_UTIL 606 // ::rtl::OUString aDefault; 607 // sName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" [")); 608 // sName += utl::Bootstrap::getBuildIdData( aDefault ); 609 // sName += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("]")); 610 //#endif 611 //} 612 // ----------------------------------------------------------------------------- 613 void OApplicationController::askToReconnect() 614 { 615 if ( m_bNeedToReconnect ) 616 { 617 m_bNeedToReconnect = sal_False; 618 sal_Bool bClear = sal_True; 619 if ( !m_pSubComponentManager->empty() ) 620 { 621 QueryBox aQry(getView(), ModuleRes(APP_CLOSEDOCUMENTS)); 622 switch (aQry.Execute()) 623 { 624 case RET_YES: 625 closeSubComponents(); 626 break; 627 default: 628 bClear = sal_False; 629 break; 630 } 631 } 632 if ( bClear ) 633 { 634 ElementType eType = getContainer()->getElementType(); 635 disconnect(); 636 getContainer()->getDetailView()->clearPages(sal_False); 637 getContainer()->selectContainer(E_NONE); // invalidate the old selection 638 m_eCurrentType = E_NONE; 639 getContainer()->selectContainer(eType); // reselect the current one again 640 } 641 } 642 } 643 644 // ----------------------------------------------------------------------------- 645 ::rtl::OUString OApplicationController::getDatabaseName() const 646 { 647 ::rtl::OUString sDatabaseName; 648 try 649 { 650 if ( m_xDataSource.is() ) 651 { 652 OSL_VERIFY( m_xDataSource->getPropertyValue( PROPERTY_NAME ) >>= sDatabaseName ); 653 } 654 } 655 catch ( const Exception& ) 656 { 657 DBG_UNHANDLED_EXCEPTION(); 658 } 659 return sDatabaseName; 660 } 661 662 // ----------------------------------------------------------------------------- 663 ::rtl::OUString OApplicationController::getStrippedDatabaseName() const 664 { 665 ::rtl::OUString sDatabaseName; 666 return ::dbaui::getStrippedDatabaseName( m_xDataSource, sDatabaseName ); 667 } 668 669 // ----------------------------------------------------------------------------- 670 void OApplicationController::onDocumentOpened( const ::rtl::OUString& _rName, const sal_Int32 _nType, 671 const ElementOpenMode _eMode, const Reference< XComponent >& _xDocument, const Reference< XComponent >& _rxDefinition ) 672 { 673 if ( !_xDocument.is() ) 674 return; 675 676 try 677 { 678 OSL_ENSURE( _xDocument.is(), "OApplicationController::onDocumentOpened: is there any *valid* scenario where this fails?" ); 679 m_pSubComponentManager->onSubComponentOpened( _rName, _nType, _eMode, _xDocument.is() ? _xDocument : _rxDefinition ); 680 681 if ( _rxDefinition.is() ) 682 { 683 Reference< XPropertySet > xProp( _rxDefinition, UNO_QUERY_THROW ); 684 Reference< XPropertySetInfo > xPSI( xProp->getPropertySetInfo(), UNO_SET_THROW ); 685 xProp->addPropertyChangeListener( PROPERTY_NAME, static_cast< XPropertyChangeListener* >( this ) ); 686 } 687 } 688 catch( const Exception& ) 689 { 690 DBG_UNHANDLED_EXCEPTION(); 691 } 692 } 693 // ----------------------------------------------------------------------------- 694 sal_Bool OApplicationController::insertHierachyElement(ElementType _eType,const String& _sParentFolder,sal_Bool _bCollection,const Reference<XContent>& _xContent,sal_Bool _bMove) 695 { 696 Reference<XHierarchicalNameContainer> xNames(getElements(_eType), UNO_QUERY); 697 return dbaui::insertHierachyElement(getView() 698 ,getORB() 699 ,xNames 700 ,_sParentFolder 701 ,_eType == E_FORM 702 ,_bCollection 703 ,_xContent 704 ,_bMove); 705 } 706 // ----------------------------------------------------------------------------- 707 sal_Bool OApplicationController::isRenameDeleteAllowed(ElementType _eType,sal_Bool _bDelete) const 708 { 709 ElementType eType = getContainer()->getElementType(); 710 sal_Bool bEnabled = !isDataSourceReadOnly() && eType == _eType; 711 if ( bEnabled ) 712 { 713 714 if ( E_TABLE == eType ) 715 bEnabled = !isConnectionReadOnly() && getContainer()->isALeafSelected(); 716 717 sal_Bool bCompareRes = sal_False; 718 if ( _bDelete ) 719 bCompareRes = getContainer()->getSelectionCount() > 0; 720 else 721 { 722 bCompareRes = getContainer()->getSelectionCount() == 1; 723 if ( bEnabled && bCompareRes && E_TABLE == eType ) 724 { 725 ::std::vector< ::rtl::OUString> aList; 726 getSelectionElementNames(aList); 727 728 try 729 { 730 Reference< XNameAccess > xContainer = const_cast<OApplicationController*>(this)->getElements(eType); 731 bEnabled = (xContainer.is() && xContainer->hasByName(*aList.begin())); 732 if ( bEnabled ) 733 bEnabled = Reference<XRename>(xContainer->getByName(*aList.begin()),UNO_QUERY).is(); 734 } 735 catch(Exception&) 736 { 737 bEnabled = sal_False; 738 } 739 } 740 } 741 742 bEnabled = bEnabled && bCompareRes; 743 } 744 return bEnabled; 745 } 746 // ----------------------------------------------------------------------------- 747 void OApplicationController::onLoadedMenu(const Reference< ::com::sun::star::frame::XLayoutManager >& _xLayoutManager) 748 { 749 750 if ( _xLayoutManager.is() ) 751 { 752 static ::rtl::OUString s_sStatusbar(RTL_CONSTASCII_USTRINGPARAM("private:resource/statusbar/statusbar")); 753 _xLayoutManager->createElement( s_sStatusbar ); 754 _xLayoutManager->requestElement( s_sStatusbar ); 755 756 if ( getContainer() ) 757 { 758 // we need to share the "mnemonic space": 759 MnemonicGenerator aMnemonicGenerator; 760 // - the menu already has mnemonics 761 SystemWindow* pSystemWindow = getContainer()->GetSystemWindow(); 762 MenuBar* pMenu = pSystemWindow ? pSystemWindow->GetMenuBar() : NULL; 763 if ( pMenu ) 764 { 765 sal_uInt16 nMenuItems = pMenu->GetItemCount(); 766 for ( sal_uInt16 i = 0; i < nMenuItems; ++i ) 767 aMnemonicGenerator.RegisterMnemonic( pMenu->GetItemText( pMenu->GetItemId( i ) ) ); 768 } 769 // - the icons should use automatic ones 770 getContainer()->createIconAutoMnemonics( aMnemonicGenerator ); 771 // - as well as the entries in the task pane 772 getContainer()->setTaskExternalMnemonics( aMnemonicGenerator ); 773 } 774 775 Execute( SID_DB_APP_VIEW_FORMS, Sequence< PropertyValue >() ); 776 InvalidateAll(); 777 } 778 } 779 // ----------------------------------------------------------------------------- 780 void OApplicationController::doAction(sal_uInt16 _nId ,ElementOpenMode _eOpenMode) 781 { 782 ::std::vector< ::rtl::OUString> aList; 783 getSelectionElementNames(aList); 784 ElementType eType = getContainer()->getElementType(); 785 ::comphelper::NamedValueCollection aArguments; 786 ElementOpenMode eOpenMode = _eOpenMode; 787 if ( eType == E_REPORT && E_OPEN_FOR_MAIL == _eOpenMode ) 788 { 789 aArguments.put("Hidden",true); 790 eOpenMode = E_OPEN_NORMAL; 791 } 792 793 ::std::vector< ::std::pair< ::rtl::OUString ,Reference< XModel > > > aCompoments; 794 ::std::vector< ::rtl::OUString>::iterator aEnd = aList.end(); 795 for (::std::vector< ::rtl::OUString>::iterator aIter = aList.begin(); aIter != aEnd; ++aIter) 796 { 797 if ( SID_DB_APP_CONVERTTOVIEW == _nId ) 798 convertToView(*aIter); 799 else 800 { 801 Reference< XModel > xModel( openElementWithArguments( *aIter, eType, eOpenMode, _nId,aArguments ), UNO_QUERY ); 802 aCompoments.push_back( ::std::pair< ::rtl::OUString, Reference< XModel > >( *aIter, xModel ) ); 803 } 804 } 805 806 // special handling for mail, if more than one document is selected attach them all 807 if ( _eOpenMode == E_OPEN_FOR_MAIL ) 808 { 809 810 ::std::vector< ::std::pair< ::rtl::OUString ,Reference< XModel > > >::iterator componentIter = aCompoments.begin(); 811 ::std::vector< ::std::pair< ::rtl::OUString ,Reference< XModel > > >::iterator componentEnd = aCompoments.end(); 812 ::rtl::OUString aDocTypeString; 813 SfxMailModel aSendMail; 814 SfxMailModel::SendMailResult eResult = SfxMailModel::SEND_MAIL_OK; 815 for (; componentIter != componentEnd && SfxMailModel::SEND_MAIL_OK == eResult; ++componentIter) 816 { 817 try 818 { 819 Reference< XModel > xModel(componentIter->second,UNO_QUERY); 820 821 // Send document as e-Mail using stored/default type 822 eResult = aSendMail.AttachDocument(aDocTypeString,xModel,componentIter->first); 823 ::comphelper::disposeComponent(xModel); 824 } 825 catch(const Exception&) 826 { 827 DBG_UNHANDLED_EXCEPTION(); 828 } 829 } 830 if ( !aSendMail.IsEmpty() ) 831 aSendMail.Send( getFrame() ); 832 } 833 } 834 // ----------------------------------------------------------------------------- 835 ElementType OApplicationController::getElementType(const Reference< XContainer >& _xContainer) const 836 { 837 ElementType eRet = E_NONE; 838 Reference<XServiceInfo> xServiceInfo(_xContainer,UNO_QUERY); 839 if ( xServiceInfo.is() ) 840 { 841 if ( xServiceInfo->supportsService(SERVICE_SDBCX_TABLES) ) 842 eRet = E_TABLE; 843 else if ( xServiceInfo->supportsService(SERVICE_NAME_FORM_COLLECTION) ) 844 eRet = E_FORM; 845 else if ( xServiceInfo->supportsService(SERVICE_NAME_REPORT_COLLECTION) ) 846 eRet = E_REPORT; 847 else 848 eRet = E_QUERY; 849 } 850 return eRet; 851 } 852 853 //........................................................................ 854 } // namespace dbaui 855 //........................................................................ 856