xref: /trunk/main/dbaccess/source/ui/relationdesign/RelationController.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 
createRegistryInfo_ORelationControl()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 //------------------------------------------------------------------------------
getImplementationName()103 ::rtl::OUString SAL_CALL ORelationController::getImplementationName()
104 {
105     return getImplementationName_Static();
106 }
107 
108 //------------------------------------------------------------------------------
getImplementationName_Static()109 ::rtl::OUString ORelationController::getImplementationName_Static()
110 {
111     return ::rtl::OUString::createFromAscii("org.openoffice.comp.dbu.ORelationDesign");
112 }
113 //------------------------------------------------------------------------------
getSupportedServiceNames_Static(void)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 //-------------------------------------------------------------------------
getSupportedServiceNames()121 Sequence< ::rtl::OUString> SAL_CALL ORelationController::getSupportedServiceNames()
122 {
123     return getSupportedServiceNames_Static();
124 }
125 // -------------------------------------------------------------------------
Create(const Reference<XMultiServiceFactory> & _rxFactory)126 Reference< XInterface > SAL_CALL ORelationController::Create(const Reference<XMultiServiceFactory >& _rxFactory)
127 {
128     return *(new ORelationController(_rxFactory));
129 }
130 DBG_NAME(ORelationController);
131 // -----------------------------------------------------------------------------
ORelationController(const Reference<XMultiServiceFactory> & _rM)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 // -----------------------------------------------------------------------------
~ORelationController()141 ORelationController::~ORelationController()
142 {
143     DBG_DTOR(ORelationController,NULL);
144 }
145 // -----------------------------------------------------------------------------
GetState(sal_uInt16 _nId) const146 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 // -----------------------------------------------------------------------------
Execute(sal_uInt16 _nId,const Sequence<PropertyValue> & aArgs)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 // -----------------------------------------------------------------------------
impl_initialize()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 // -----------------------------------------------------------------------------
getPrivateTitle() const253 ::rtl::OUString ORelationController::getPrivateTitle( ) const
254 {
255     ::rtl::OUString sName = getDataSourceName();
256     return ::dbaui::getStrippedDatabaseName(getDataSource(),sName);
257 }
258 // -----------------------------------------------------------------------------
Construct(Window * pParent)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 // -----------------------------------------------------------------------------
saveModified()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 // -----------------------------------------------------------------------------
describeSupportedFeatures()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:
RelationLoader(ORelationController * _pParent,const Reference<XDatabaseMetaData> & _xMetaData,const Reference<XNameAccess> & _xTables,const Sequence<::rtl::OUString> & _aTableList,const sal_Int32 _nStartIndex,const sal_Int32 _nEndIndex)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:
~RelationLoader()319         virtual ~RelationLoader(){}
320 
321         void loadTableData(const Any& _aTable);
322     };
323 
run()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     }
onTerminated()355     void SAL_CALL RelationLoader::onTerminated()
356     {
357         m_pParent->mergeData(m_vTableConnectionData);
358         delete this;
359     }
360 
loadTableData(const Any & _aTable)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 
mergeData(const TTableConnectionData & _aConnectionData)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 // -----------------------------------------------------------------------------
loadData()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 // -----------------------------------------------------------------------------
existsTable(const::rtl::OUString & _rComposedTableName,sal_Bool _bCase) const553 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 // -----------------------------------------------------------------------------
loadLayoutInformation()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 // -----------------------------------------------------------------------------
reset()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 // -----------------------------------------------------------------------------
allowViews() const599 bool ORelationController::allowViews() const
600 {
601     return false;
602 }
603 
604 // -----------------------------------------------------------------------------
allowQueries() const605 bool ORelationController::allowQueries() const
606 {
607     return false;
608 }
609 
610 // -----------------------------------------------------------------------------
611