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