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