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 #include "dbu_reghelper.hxx" 31 #include <sfx2/sfxsids.hrc> 32 #include "dbu_rel.hrc" 33 #include <vcl/svapp.hxx> 34 #include "browserids.hxx" 35 #include <comphelper/types.hxx> 36 #include "dbustrings.hrc" 37 #include <connectivity/dbtools.hxx> 38 #include <com/sun/star/frame/FrameSearchFlag.hpp> 39 #include <comphelper/extract.hxx> 40 #include <com/sun/star/container/XChild.hpp> 41 #include <com/sun/star/container/XNameContainer.hpp> 42 #include <com/sun/star/sdbcx/XDataDescriptorFactory.hpp> 43 #include <com/sun/star/sdbcx/XTablesSupplier.hpp> 44 #include <com/sun/star/sdbcx/KeyType.hpp> 45 #include <com/sun/star/sdbcx/XDrop.hpp> 46 #include <com/sun/star/sdbcx/XAlterTable.hpp> 47 #include <com/sun/star/sdbcx/XAppend.hpp> 48 #include <com/sun/star/sdbcx/XKeysSupplier.hpp> 49 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> 50 #include <com/sun/star/sdb/SQLContext.hpp> 51 #include <com/sun/star/sdbc/SQLWarning.hpp> 52 #include <com/sun/star/sdbc/ColumnValue.hpp> 53 #include <com/sun/star/sdbc/XRow.hpp> 54 #include <connectivity/dbexception.hxx> 55 #include <connectivity/dbmetadata.hxx> 56 #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp> 57 #include <comphelper/streamsection.hxx> 58 #include <comphelper/basicio.hxx> 59 #include <comphelper/seqstream.hxx> 60 #include <com/sun/star/io/XActiveDataSource.hpp> 61 #include <com/sun/star/io/XActiveDataSink.hpp> 62 #include "sqlmessage.hxx" 63 #include "RelationController.hxx" 64 #include <vcl/msgbox.hxx> 65 #include "TableWindowData.hxx" 66 #include "dbustrings.hrc" 67 #include "UITools.hxx" 68 #include "RTableConnectionData.hxx" 69 #include "RelationTableView.hxx" 70 #include "RelationDesignView.hxx" 71 #include <tools/debug.hxx> 72 #include <tools/diagnose_ex.h> 73 #include <vcl/waitobj.hxx> 74 #include <osl/thread.hxx> 75 #include <vos/mutex.hxx> 76 77 78 #define MAX_THREADS 10 79 80 extern "C" void SAL_CALL createRegistryInfo_ORelationControl() 81 { 82 static ::dbaui::OMultiInstanceAutoRegistration< ::dbaui::ORelationController > aAutoRegistration; 83 } 84 85 86 using namespace ::com::sun::star::uno; 87 using namespace ::com::sun::star::io; 88 using namespace ::com::sun::star::beans; 89 using namespace ::com::sun::star::frame; 90 using namespace ::com::sun::star::util; 91 using namespace ::com::sun::star::lang; 92 using namespace ::com::sun::star::container; 93 using namespace ::com::sun::star::sdbcx; 94 using namespace ::com::sun::star::sdbc; 95 using namespace ::com::sun::star::sdb; 96 using namespace ::com::sun::star::ui::dialogs; 97 using namespace ::com::sun::star::util; 98 // using namespace ::com::sun::star::sdbcx; 99 // using namespace ::connectivity; 100 using namespace ::dbtools; 101 using namespace ::dbaui; 102 using namespace ::comphelper; 103 using namespace ::osl; 104 105 //------------------------------------------------------------------------------ 106 ::rtl::OUString SAL_CALL ORelationController::getImplementationName() throw( RuntimeException ) 107 { 108 return getImplementationName_Static(); 109 } 110 111 //------------------------------------------------------------------------------ 112 ::rtl::OUString ORelationController::getImplementationName_Static() throw( RuntimeException ) 113 { 114 return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.ORelationDesign"); 115 } 116 //------------------------------------------------------------------------------ 117 Sequence< ::rtl::OUString> ORelationController::getSupportedServiceNames_Static(void) throw( RuntimeException ) 118 { 119 Sequence< ::rtl::OUString> aSupported(1); 120 aSupported.getArray()[0] = ::rtl::OUString::createFromAscii("com.sun.star.sdb.RelationDesign"); 121 return aSupported; 122 } 123 //------------------------------------------------------------------------- 124 Sequence< ::rtl::OUString> SAL_CALL ORelationController::getSupportedServiceNames() throw(RuntimeException) 125 { 126 return getSupportedServiceNames_Static(); 127 } 128 // ------------------------------------------------------------------------- 129 Reference< XInterface > SAL_CALL ORelationController::Create(const Reference<XMultiServiceFactory >& _rxFactory) 130 { 131 return *(new ORelationController(_rxFactory)); 132 } 133 DBG_NAME(ORelationController); 134 // ----------------------------------------------------------------------------- 135 ORelationController::ORelationController(const Reference< XMultiServiceFactory >& _rM) 136 : OJoinController(_rM) 137 ,m_nThreadEvent(0) 138 ,m_bRelationsPossible(sal_True) 139 { 140 DBG_CTOR(ORelationController,NULL); 141 InvalidateAll(); 142 } 143 // ----------------------------------------------------------------------------- 144 ORelationController::~ORelationController() 145 { 146 DBG_DTOR(ORelationController,NULL); 147 } 148 // ----------------------------------------------------------------------------- 149 FeatureState ORelationController::GetState(sal_uInt16 _nId) const 150 { 151 FeatureState aReturn; 152 aReturn.bEnabled = m_bRelationsPossible; 153 switch (_nId) 154 { 155 case SID_RELATION_ADD_RELATION: 156 aReturn.bEnabled = !m_vTableData.empty() && isConnected() && isEditable(); 157 aReturn.bChecked = false; 158 break; 159 case ID_BROWSER_SAVEDOC: 160 aReturn.bEnabled = haveDataSource() && impl_isModified(); 161 break; 162 default: 163 aReturn = OJoinController::GetState(_nId); 164 break; 165 } 166 return aReturn; 167 } 168 // ----------------------------------------------------------------------------- 169 void ORelationController::Execute(sal_uInt16 _nId, const Sequence< PropertyValue >& aArgs) 170 { 171 switch(_nId) 172 { 173 case ID_BROWSER_SAVEDOC: 174 { 175 OSL_ENSURE(isEditable(),"Slot ID_BROWSER_SAVEDOC should not be enabled!"); 176 if(!::dbaui::checkDataSourceAvailable(::comphelper::getString(getDataSource()->getPropertyValue(PROPERTY_NAME)),getORB())) 177 { 178 String aMessage(ModuleRes(STR_DATASOURCE_DELETED)); 179 OSQLWarningBox( getView(), aMessage ).Execute(); 180 } 181 else 182 { 183 // now we save the layout information 184 // create the output stream 185 try 186 { 187 if ( haveDataSource() && getDataSource()->getPropertySetInfo()->hasPropertyByName(PROPERTY_LAYOUTINFORMATION) ) 188 { 189 ::comphelper::NamedValueCollection aWindowsData; 190 saveTableWindows( aWindowsData ); 191 getDataSource()->setPropertyValue( PROPERTY_LAYOUTINFORMATION, makeAny( aWindowsData.getPropertyValues() ) ); 192 setModified(sal_False); 193 } 194 } 195 catch ( const Exception& ) 196 { 197 DBG_UNHANDLED_EXCEPTION(); 198 } 199 } 200 } 201 break; 202 case SID_RELATION_ADD_RELATION: 203 static_cast<ORelationTableView*>(static_cast<ORelationDesignView*>( getView() )->getTableView())->AddNewRelation(); 204 break; 205 default: 206 OJoinController::Execute(_nId,aArgs); 207 return; 208 } 209 InvalidateFeature(_nId); 210 } 211 // ----------------------------------------------------------------------------- 212 void ORelationController::impl_initialize() 213 { 214 OJoinController::impl_initialize(); 215 216 if( !getSdbMetaData().supportsRelations() ) 217 {// check if this database supports relations 218 219 setEditable(sal_False); 220 m_bRelationsPossible = sal_False; 221 { 222 String sTitle(ModuleRes(STR_RELATIONDESIGN)); 223 sTitle.Erase(0,3); 224 OSQLMessageBox aDlg(NULL,sTitle,ModuleRes(STR_RELATIONDESIGN_NOT_AVAILABLE)); 225 aDlg.Execute(); 226 } 227 disconnect(); 228 throw SQLException(); 229 } 230 231 if(!m_bRelationsPossible) 232 InvalidateAll(); 233 234 // we need a datasource 235 OSL_ENSURE(haveDataSource(),"ORelationController::initialize: need a datasource!"); 236 237 Reference<XTablesSupplier> xSup(getConnection(),UNO_QUERY); 238 OSL_ENSURE(xSup.is(),"Connection isn't a XTablesSupplier!"); 239 if(xSup.is()) 240 m_xTables = xSup->getTables(); 241 // load the layoutInformation 242 loadLayoutInformation(); 243 try 244 { 245 loadData(); 246 if ( !m_nThreadEvent ) 247 Application::PostUserEvent(LINK(this, ORelationController, OnThreadFinished)); 248 } 249 catch( const Exception& ) 250 { 251 DBG_UNHANDLED_EXCEPTION(); 252 } 253 254 } 255 // ----------------------------------------------------------------------------- 256 ::rtl::OUString ORelationController::getPrivateTitle( ) const 257 { 258 ::rtl::OUString sName = getDataSourceName(); 259 return ::dbaui::getStrippedDatabaseName(getDataSource(),sName); 260 } 261 // ----------------------------------------------------------------------------- 262 sal_Bool ORelationController::Construct(Window* pParent) 263 { 264 setView( * new ORelationDesignView( pParent, *this, getORB() ) ); 265 OJoinController::Construct(pParent); 266 return sal_True; 267 } 268 // ----------------------------------------------------------------------------- 269 short ORelationController::saveModified() 270 { 271 short nSaved = RET_YES; 272 if(haveDataSource() && isModified()) 273 { 274 QueryBox aQry(getView(), ModuleRes(RELATION_DESIGN_SAVEMODIFIED)); 275 nSaved = aQry.Execute(); 276 if(nSaved == RET_YES) 277 Execute(ID_BROWSER_SAVEDOC,Sequence<PropertyValue>()); 278 } 279 return nSaved; 280 } 281 // ----------------------------------------------------------------------------- 282 void ORelationController::describeSupportedFeatures() 283 { 284 OJoinController::describeSupportedFeatures(); 285 implDescribeSupportedFeature( ".uno:DBAddRelation", SID_RELATION_ADD_RELATION, CommandGroup::EDIT ); 286 } 287 namespace 288 { 289 class RelationLoader : public ::osl::Thread 290 { 291 DECLARE_STL_MAP(::rtl::OUString,::boost::shared_ptr<OTableWindowData>,::comphelper::UStringMixLess,TTableDataHelper); 292 TTableDataHelper m_aTableData; 293 TTableConnectionData m_vTableConnectionData; 294 const Sequence< ::rtl::OUString> m_aTableList; 295 ORelationController* m_pParent; 296 const Reference< XDatabaseMetaData> m_xMetaData; 297 const Reference< XNameAccess > m_xTables; 298 const sal_Int32 m_nStartIndex; 299 const sal_Int32 m_nEndIndex; 300 301 public: 302 RelationLoader(ORelationController* _pParent 303 ,const Reference< XDatabaseMetaData>& _xMetaData 304 ,const Reference< XNameAccess >& _xTables 305 ,const Sequence< ::rtl::OUString>& _aTableList 306 ,const sal_Int32 _nStartIndex 307 ,const sal_Int32 _nEndIndex) 308 :m_aTableData(_xMetaData.is() && _xMetaData->supportsMixedCaseQuotedIdentifiers()) 309 ,m_aTableList(_aTableList) 310 ,m_pParent(_pParent) 311 ,m_xMetaData(_xMetaData) 312 ,m_xTables(_xTables) 313 ,m_nStartIndex(_nStartIndex) 314 ,m_nEndIndex(_nEndIndex) 315 { 316 } 317 318 /// Working method which should be overridden. 319 virtual void SAL_CALL run(); 320 virtual void SAL_CALL onTerminated(); 321 protected: 322 virtual ~RelationLoader(){} 323 324 void loadTableData(const Any& _aTable); 325 }; 326 327 void SAL_CALL RelationLoader::run() 328 { 329 const ::rtl::OUString* pIter = m_aTableList.getConstArray() + m_nStartIndex; 330 for(sal_Int32 i = m_nStartIndex; i < m_nEndIndex;++i,++pIter) 331 { 332 ::rtl::OUString sCatalog,sSchema,sTable; 333 ::dbtools::qualifiedNameComponents(m_xMetaData, 334 *pIter, 335 sCatalog, 336 sSchema, 337 sTable, 338 ::dbtools::eInDataManipulation); 339 Any aCatalog; 340 if ( sCatalog.getLength() ) 341 aCatalog <<= sCatalog; 342 343 try 344 { 345 Reference< XResultSet > xResult = m_xMetaData->getImportedKeys(aCatalog, sSchema,sTable); 346 if ( xResult.is() && xResult->next() ) 347 { 348 ::comphelper::disposeComponent(xResult); 349 loadTableData(m_xTables->getByName(*pIter)); 350 } // if ( xResult.is() && xResult->next() ) 351 } 352 catch( const Exception& ) 353 { 354 DBG_UNHANDLED_EXCEPTION(); 355 } 356 } 357 } 358 void SAL_CALL RelationLoader::onTerminated() 359 { 360 m_pParent->mergeData(m_vTableConnectionData); 361 delete this; 362 } 363 364 void RelationLoader::loadTableData(const Any& _aTable) 365 { 366 Reference<XPropertySet> xTableProp(_aTable,UNO_QUERY); 367 const ::rtl::OUString sSourceName = ::dbtools::composeTableName( m_xMetaData, xTableProp, ::dbtools::eInTableDefinitions, false, false, false ); 368 TTableDataHelper::iterator aFind = m_aTableData.find(sSourceName); 369 bool bNotFound = true, bAdded = false; 370 if ( aFind == m_aTableData.end() ) 371 { 372 aFind = m_aTableData.insert(TTableDataHelper::value_type(sSourceName,::boost::shared_ptr<OTableWindowData>(new OTableWindowData(xTableProp,sSourceName, sSourceName)))).first; 373 aFind->second->ShowAll(sal_False); 374 bAdded = true; 375 } 376 TTableWindowData::value_type pReferencingTable = aFind->second; 377 Reference<XIndexAccess> xKeys = pReferencingTable->getKeys(); 378 const Reference<XKeysSupplier> xKeySup(xTableProp,UNO_QUERY); 379 380 if ( !xKeys.is() && xKeySup.is() ) 381 { 382 xKeys = xKeySup->getKeys(); 383 } 384 385 if ( xKeys.is() ) 386 { 387 Reference<XPropertySet> xKey; 388 const sal_Int32 nCount = xKeys->getCount(); 389 for(sal_Int32 i = 0 ; i < nCount ; ++i) 390 { 391 xKeys->getByIndex(i) >>= xKey; 392 sal_Int32 nKeyType = 0; 393 xKey->getPropertyValue(PROPERTY_TYPE) >>= nKeyType; 394 if ( KeyType::FOREIGN == nKeyType ) 395 { 396 bNotFound = false; 397 ::rtl::OUString sReferencedTable; 398 xKey->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= sReferencedTable; 399 ////////////////////////////////////////////////////////////////////// 400 // insert windows 401 TTableDataHelper::iterator aRefFind = m_aTableData.find(sReferencedTable); 402 if ( aRefFind == m_aTableData.end() ) 403 { 404 if ( m_xTables->hasByName(sReferencedTable) ) 405 { 406 Reference<XPropertySet> xReferencedTable(m_xTables->getByName(sReferencedTable),UNO_QUERY); 407 aRefFind = m_aTableData.insert(TTableDataHelper::value_type(sReferencedTable,::boost::shared_ptr<OTableWindowData>(new OTableWindowData(xReferencedTable,sReferencedTable, sReferencedTable)))).first; 408 aRefFind->second->ShowAll(sal_False); 409 } 410 else 411 continue; // table name could not be found so we do not show this table releation 412 } // if ( aFind == m_aTableData.end() ) 413 TTableWindowData::value_type pReferencedTable = aRefFind->second; 414 415 ::rtl::OUString sKeyName; 416 xKey->getPropertyValue(PROPERTY_NAME) >>= sKeyName; 417 ////////////////////////////////////////////////////////////////////// 418 // insert connection 419 ORelationTableConnectionData* pTabConnData = new ORelationTableConnectionData( pReferencingTable, pReferencedTable, sKeyName ); 420 m_vTableConnectionData.push_back(TTableConnectionData::value_type(pTabConnData)); 421 ////////////////////////////////////////////////////////////////////// 422 // insert columns 423 const Reference<XColumnsSupplier> xColsSup(xKey,UNO_QUERY); 424 OSL_ENSURE(xColsSup.is(),"Key is no XColumnsSupplier!"); 425 const Reference<XNameAccess> xColumns = xColsSup->getColumns(); 426 const Sequence< ::rtl::OUString> aNames = xColumns->getElementNames(); 427 const ::rtl::OUString* pIter = aNames.getConstArray(); 428 const ::rtl::OUString* pEnd = pIter + aNames.getLength(); 429 ::rtl::OUString sColumnName,sRelatedName; 430 for(sal_uInt16 j=0;pIter != pEnd;++pIter,++j) 431 { 432 const Reference<XPropertySet> xPropSet(xColumns->getByName(*pIter),UNO_QUERY); 433 OSL_ENSURE(xPropSet.is(),"Invalid column found in KeyColumns!"); 434 if ( xPropSet.is() ) 435 { 436 xPropSet->getPropertyValue(PROPERTY_NAME) >>= sColumnName; 437 xPropSet->getPropertyValue(PROPERTY_RELATEDCOLUMN) >>= sRelatedName; 438 } 439 pTabConnData->SetConnLine( j, sColumnName, sRelatedName ); 440 } 441 ////////////////////////////////////////////////////////////////////// 442 // Update/Del-Flags setzen 443 sal_Int32 nUpdateRule = 0; 444 sal_Int32 nDeleteRule = 0; 445 xKey->getPropertyValue(PROPERTY_UPDATERULE) >>= nUpdateRule; 446 xKey->getPropertyValue(PROPERTY_DELETERULE) >>= nDeleteRule; 447 448 pTabConnData->SetUpdateRules( nUpdateRule ); 449 pTabConnData->SetDeleteRules( nDeleteRule ); 450 451 ////////////////////////////////////////////////////////////////////// 452 // Kardinalitaet setzen 453 pTabConnData->SetCardinality(); 454 } 455 } 456 } // if ( xKeys.is() ) 457 } 458 } 459 460 void ORelationController::mergeData(const TTableConnectionData& _aConnectionData) 461 { 462 ::osl::MutexGuard aGuard( getMutex() ); 463 464 ::std::copy( _aConnectionData.begin(), _aConnectionData.end(), ::std::back_inserter( m_vTableConnectionData )); 465 //const Reference< XDatabaseMetaData> xMetaData = getConnection()->getMetaData(); 466 const sal_Bool bCase = sal_True;//xMetaData.is() && xMetaData->supportsMixedCaseQuotedIdentifiers(); 467 // here we are finished, so we can collect the table from connection data 468 TTableConnectionData::iterator aConnDataIter = m_vTableConnectionData.begin(); 469 TTableConnectionData::iterator aConnDataEnd = m_vTableConnectionData.end(); 470 for(;aConnDataIter != aConnDataEnd;++aConnDataIter) 471 { 472 if ( !existsTable((*aConnDataIter)->getReferencingTable()->GetComposedName(),bCase) ) 473 { 474 m_vTableData.push_back((*aConnDataIter)->getReferencingTable()); 475 } 476 if ( !existsTable((*aConnDataIter)->getReferencedTable()->GetComposedName(),bCase) ) 477 { 478 m_vTableData.push_back((*aConnDataIter)->getReferencedTable()); 479 } 480 } // for(;aConnDataIter != aConnDataEnd;++aConnDataIter) 481 if ( m_nThreadEvent ) 482 { 483 --m_nThreadEvent; 484 if ( !m_nThreadEvent ) 485 Application::PostUserEvent(LINK(this, ORelationController, OnThreadFinished)); 486 } 487 } 488 // ----------------------------------------------------------------------------- 489 IMPL_LINK( ORelationController, OnThreadFinished, void*, /*NOTINTERESTEDIN*/ ) 490 { 491 vos::OGuard aSolarGuard( Application::GetSolarMutex() ); 492 ::osl::MutexGuard aGuard( getMutex() ); 493 try 494 { 495 getView()->initialize(); // show the windows and fill with our informations 496 getView()->Invalidate(INVALIDATE_NOERASE); 497 ClearUndoManager(); 498 setModified(sal_False); // and we are not modified yet 499 500 if(m_vTableData.empty()) 501 Execute(ID_BROWSER_ADDTABLE,Sequence<PropertyValue>()); 502 } 503 catch( const Exception& ) 504 { 505 DBG_UNHANDLED_EXCEPTION(); 506 } 507 m_pWaitObject.reset(); 508 return 0L; 509 } 510 // ----------------------------------------------------------------------------- 511 void ORelationController::loadData() 512 { 513 m_pWaitObject.reset( new WaitObject(getView()) ); 514 try 515 { 516 if ( !m_xTables.is() ) 517 return; 518 DatabaseMetaData aMeta(getConnection()); 519 // this may take some time 520 const Reference< XDatabaseMetaData> xMetaData = getConnection()->getMetaData(); 521 const Sequence< ::rtl::OUString> aNames = m_xTables->getElementNames(); 522 const sal_Int32 nCount = aNames.getLength(); 523 if ( aMeta.supportsThreads() ) 524 { 525 const sal_Int32 nMaxElements = (nCount / MAX_THREADS) +1; 526 sal_Int32 nStart = 0,nEnd = ::std::min(nMaxElements,nCount); 527 while(nStart != nEnd) 528 { 529 ++m_nThreadEvent; 530 RelationLoader* pThread = new RelationLoader(this,xMetaData,m_xTables,aNames,nStart,nEnd); 531 pThread->createSuspended(); 532 pThread->setPriority(osl_Thread_PriorityBelowNormal); 533 pThread->resume(); 534 nStart = nEnd; 535 nEnd += nMaxElements; 536 nEnd = ::std::min(nEnd,nCount); 537 } // for(;pIter != pEnd;++pIter) 538 } // if ( aMeta.supportsThreads() ) 539 else 540 { 541 RelationLoader* pThread = new RelationLoader(this,xMetaData,m_xTables,aNames,0,nCount); 542 pThread->run(); 543 pThread->onTerminated(); 544 } 545 } 546 catch(SQLException& e) 547 { 548 showError(SQLExceptionInfo(e)); 549 } 550 catch(const Exception&) 551 { 552 DBG_UNHANDLED_EXCEPTION(); 553 } 554 } 555 // ----------------------------------------------------------------------------- 556 TTableWindowData::value_type ORelationController::existsTable(const ::rtl::OUString& _rComposedTableName,sal_Bool _bCase) const 557 { 558 ::comphelper::UStringMixEqual bCase(_bCase); 559 TTableWindowData::const_iterator aIter = m_vTableData.begin(); 560 TTableWindowData::const_iterator aEnd = m_vTableData.end(); 561 for(;aIter != aEnd;++aIter) 562 { 563 if(bCase((*aIter)->GetComposedName(),_rComposedTableName)) 564 break; 565 } 566 return ( aIter != aEnd) ? *aIter : TTableWindowData::value_type(); 567 } 568 // ----------------------------------------------------------------------------- 569 void ORelationController::loadLayoutInformation() 570 { 571 try 572 { 573 OSL_ENSURE(haveDataSource(),"We need a datasource from our connection!"); 574 if ( haveDataSource() ) 575 { 576 if ( getDataSource()->getPropertySetInfo()->hasPropertyByName(PROPERTY_LAYOUTINFORMATION) ) 577 { 578 Sequence<PropertyValue> aWindows; 579 getDataSource()->getPropertyValue(PROPERTY_LAYOUTINFORMATION) >>= aWindows; 580 loadTableWindows(aWindows); 581 } 582 } 583 } 584 catch(Exception&) 585 { 586 } 587 } 588 // ----------------------------------------------------------------------------- 589 void ORelationController::reset() 590 { 591 loadLayoutInformation(); 592 ODataView* pView = getView(); 593 OSL_ENSURE(pView,"No current view!"); 594 if(pView) 595 { 596 pView->initialize(); 597 pView->Invalidate(INVALIDATE_NOERASE); 598 } 599 } 600 601 // ----------------------------------------------------------------------------- 602 bool ORelationController::allowViews() const 603 { 604 return false; 605 } 606 607 // ----------------------------------------------------------------------------- 608 bool ORelationController::allowQueries() const 609 { 610 return false; 611 } 612 613 // ----------------------------------------------------------------------------- 614 615 616