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