1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_dbaccess.hxx" 26 27 #ifndef DBAUI_QUERYTABLEVIEW_HXX 28 #include "QueryTableView.hxx" 29 #endif 30 #ifndef DBAUI_TABLEFIELDINFO_HXX 31 #include "TableFieldInfo.hxx" 32 #endif 33 #ifndef DBAUI_TABLEFIELDDESC_HXX 34 #include "TableFieldDescription.hxx" 35 #endif 36 #ifndef _TOOLS_DEBUG_HXX 37 #include <tools/debug.hxx> 38 #endif 39 #ifndef TOOLS_DIAGNOSE_EX_H 40 #include <tools/diagnose_ex.h> 41 #endif 42 #ifndef _DBA_DBACCESS_HELPID_HRC_ 43 #include "dbaccess_helpid.hrc" 44 #endif 45 #ifndef DBAUI_QUERY_TABLEWINDOW_HXX 46 #include "QTableWindow.hxx" 47 #endif 48 #ifndef DBAUI_QUERYTABLECONNECTION_HXX 49 #include "QTableConnection.hxx" 50 #endif 51 #ifndef DBAUI_QTABLECONNECTIONDATA_HXX 52 #include "QTableConnectionData.hxx" 53 #endif 54 #ifndef DBAUI_QUERYDESIGNVIEW_HXX 55 #include "QueryDesignView.hxx" 56 #endif 57 #ifndef DBAUI_QUERYCONTROLLER_HXX 58 #include "querycontroller.hxx" 59 #endif 60 #ifndef DBAUI_QUERYADDTABCONNUNDOACTION_HXX 61 #include "QueryAddTabConnUndoAction.hxx" 62 #endif 63 #ifndef DBAUI_QUERYTABWINSHOWUNDOACT_HXX 64 #include "QueryTabWinShowUndoAct.hxx" 65 #endif 66 #ifndef DBACCESS_UI_BROWSER_ID_HXX 67 #include "browserids.hxx" 68 #endif 69 #ifndef _COM_SUN_STAR_SDBCX_XTABLESSUPPLIER_HPP_ 70 #include <com/sun/star/sdbcx/XTablesSupplier.hpp> 71 #endif 72 #ifndef _COM_SUN_STAR_SDBC_XCONNECTION_HPP_ 73 #include <com/sun/star/sdbc/XConnection.hpp> 74 #endif 75 #ifndef _COM_SUN_STAR_SDBCX_XKEYSSUPPLIER_HPP_ 76 #include <com/sun/star/sdbcx/XKeysSupplier.hpp> 77 #endif 78 #ifndef _COM_SUN_STAR_SDBCX_XCOLUMNSSUPPLIER_HPP_ 79 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> 80 #endif 81 #include <com/sun/star/accessibility/AccessibleEventId.hpp> 82 #ifndef DBACCESS_JACCESS_HXX 83 #include "JAccess.hxx" 84 #endif 85 #ifndef _COM_SUN_STAR_SDBCX_KEYTYPE_HPP_ 86 #include <com/sun/star/sdbcx/KeyType.hpp> 87 #endif 88 #ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_ 89 #include <com/sun/star/container/XIndexAccess.hpp> 90 #endif 91 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ 92 #include <com/sun/star/beans/XPropertySet.hpp> 93 #endif 94 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC 95 #include "dbustrings.hrc" 96 #endif 97 #ifndef _CONNECTIVITY_DBTOOLS_HXX_ 98 #include <connectivity/dbtools.hxx> 99 #endif 100 #ifndef _COMPHELPER_SEQUENCE_HXX_ 101 #include <comphelper/sequence.hxx> 102 #endif 103 #ifndef DBAUI_QUERYDLG_HXX 104 #include "querydlg.hxx" 105 #endif 106 #ifndef DBAUI_JOINEXCHANGE_HXX 107 #include "JoinExchange.hxx" 108 #endif 109 #ifndef _COMPHELPER_EXTRACT_HXX_ 110 #include <comphelper/extract.hxx> 111 #endif 112 #ifndef DBAUI_QUERYDESIGNVIEW_HXX 113 #include "QueryDesignView.hxx" 114 #endif 115 #ifndef _DBU_QRY_HRC_ 116 #include "dbu_qry.hrc" 117 #endif 118 #ifndef _SV_MSGBOX_HXX 119 #include <vcl/msgbox.hxx> 120 #endif 121 122 using namespace dbaui; 123 using namespace ::com::sun::star::uno; 124 using namespace ::com::sun::star::sdbc; 125 using namespace ::com::sun::star::sdbcx; 126 using namespace ::com::sun::star::beans; 127 using namespace ::com::sun::star::container; 128 using namespace ::com::sun::star::accessibility; 129 130 //------------------------------------------------------------------------------ 131 namespace 132 { 133 // ----------------------------------------------------------------------------- 134 sal_Bool isColumnInKeyType(const Reference<XIndexAccess>& _rxKeys,const ::rtl::OUString& _rColumnName,sal_Int32 _nKeyType) 135 { 136 sal_Bool bReturn = sal_False; 137 if(_rxKeys.is()) 138 { 139 Reference<XColumnsSupplier> xColumnsSupplier; 140 // search the one and only primary key 141 const sal_Int32 nCount = _rxKeys->getCount(); 142 for(sal_Int32 i=0;i< nCount;++i) 143 { 144 Reference<XPropertySet> xProp(_rxKeys->getByIndex(i),UNO_QUERY); 145 if(xProp.is()) 146 { 147 sal_Int32 nKeyType = 0; 148 xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType; 149 if(_nKeyType == nKeyType) 150 { 151 xColumnsSupplier.set(xProp,UNO_QUERY); 152 if(xColumnsSupplier.is()) 153 { 154 Reference<XNameAccess> xColumns = xColumnsSupplier->getColumns(); 155 if(xColumns.is() && xColumns->hasByName(_rColumnName)) 156 { 157 bReturn = sal_True; 158 break; 159 } 160 } 161 } 162 } 163 } 164 } 165 return bReturn; 166 } 167 // ----------------------------------------------------------------------------- 168 /** appends a new TabAdd Undo action at controller 169 @param _pView the view which we use 170 @param _pUndoAction the undo action which should be added 171 @param _pConnection the connection for which the undo action should be appended 172 @param _bOwner is the undo action the owner 173 */ 174 // ----------------------------------------------------------------------------- 175 void addUndoAction( OQueryTableView* _pView, 176 OQueryTabConnUndoAction* _pUndoAction, 177 OQueryTableConnection* _pConnection, 178 sal_Bool _bOwner = sal_False) 179 { 180 _pUndoAction->SetOwnership(_bOwner); 181 _pUndoAction->SetConnection(_pConnection); 182 _pView->getDesignView()->getController().addUndoActionAndInvalidate(_pUndoAction); 183 } 184 // ----------------------------------------------------------------------------- 185 /** openJoinDialog opens the join dialog with this connection data 186 @param _pView the view which we use 187 @param _pConnectionData the connection data 188 189 @return true when OK was pressed otherwise false 190 */ 191 sal_Bool openJoinDialog(OQueryTableView* _pView,const TTableConnectionData::value_type& _pConnectionData,sal_Bool _bSelectableTables) 192 { 193 OQueryTableConnectionData* pData = static_cast< OQueryTableConnectionData*>(_pConnectionData.get()); 194 195 DlgQryJoin aDlg(_pView,_pConnectionData,_pView->GetTabWinMap(),_pView->getDesignView()->getController().getConnection(),_bSelectableTables); 196 sal_Bool bOk = aDlg.Execute() == RET_OK; 197 if( bOk ) 198 { 199 pData->SetJoinType(aDlg.GetJoinType()); 200 _pView->getDesignView()->getController().setModified(sal_True); 201 } 202 203 return bOk; 204 } 205 // ----------------------------------------------------------------------------- 206 /** connectionModified adds an undo action for the modified connection and forces an redraw 207 @param _pView the view which we use 208 @param _pConnection the connection which was modified 209 @param _bAddUndo true when an undo action should be appended 210 */ 211 void connectionModified(OQueryTableView* _pView, 212 OTableConnection* _pConnection, 213 sal_Bool _bAddUndo) 214 { 215 OSL_ENSURE(_pConnection,"Invalid connection!"); 216 _pConnection->UpdateLineList(); 217 218 // add an undo action 219 if ( _bAddUndo ) 220 addUndoAction( _pView, 221 new OQueryAddTabConnUndoAction(_pView), 222 static_cast< OQueryTableConnection*>(_pConnection)); 223 // redraw 224 _pConnection->RecalcLines(); 225 // force an invalidation of the bounding rectangle 226 _pConnection->InvalidateConnection(); 227 228 _pView->Invalidate(INVALIDATE_NOCHILDREN); 229 } 230 // ----------------------------------------------------------------------------- 231 void addConnections(OQueryTableView* _pView, 232 const OQueryTableWindow& _rSource, 233 const OQueryTableWindow& _rDest, 234 const Reference<XNameAccess>& _rxSourceForeignKeyColumns) 235 { 236 if ( _rSource.GetData()->isQuery() || _rDest.GetData()->isQuery() ) 237 // nothing to do if one of both denotes a query 238 return; 239 240 // we found a table in our view where we can insert some connections 241 // the key columns have a property called RelatedColumn 242 // OQueryTableConnectionData aufbauen 243 OQueryTableConnectionData* pNewConnData = new OQueryTableConnectionData( _rSource.GetData(), _rDest.GetData() ); 244 TTableConnectionData::value_type aNewConnData(pNewConnData); 245 246 Reference<XIndexAccess> xReferencedKeys( _rDest.GetData()->getKeys()); 247 ::rtl::OUString sRelatedColumn; 248 249 // iterate through all foreignkey columns to create the connections 250 Sequence< ::rtl::OUString> aElements(_rxSourceForeignKeyColumns->getElementNames()); 251 const ::rtl::OUString* pIter = aElements.getConstArray(); 252 const ::rtl::OUString* pEnd = pIter + aElements.getLength(); 253 for(sal_Int32 i=0;pIter != pEnd;++pIter,++i) 254 { 255 Reference<XPropertySet> xColumn; 256 if ( !( _rxSourceForeignKeyColumns->getByName(*pIter) >>= xColumn ) ) 257 { 258 OSL_ENSURE( false, "addConnections: invalid foreign key column!" ); 259 continue; 260 } 261 262 pNewConnData->SetFieldType(JTCS_FROM,TAB_NORMAL_FIELD); 263 264 xColumn->getPropertyValue(PROPERTY_RELATEDCOLUMN) >>= sRelatedColumn; 265 pNewConnData->SetFieldType(JTCS_TO,isColumnInKeyType(xReferencedKeys,sRelatedColumn,KeyType::PRIMARY) ? TAB_PRIMARY_FIELD : TAB_NORMAL_FIELD); 266 267 { 268 Sequence< sal_Int16> aFind(::comphelper::findValue(_rSource.GetOriginalColumns()->getElementNames(),*pIter,sal_True)); 269 if(aFind.getLength()) 270 pNewConnData->SetFieldIndex(JTCS_FROM,aFind[0]+1); 271 else 272 OSL_ENSURE(0,"Column not found!"); 273 } 274 // get the position inside the tabe 275 Reference<XNameAccess> xRefColumns = _rDest.GetOriginalColumns(); 276 if(xRefColumns.is()) 277 { 278 Sequence< sal_Int16> aFind(::comphelper::findValue(xRefColumns->getElementNames(),sRelatedColumn,sal_True)); 279 if(aFind.getLength()) 280 pNewConnData->SetFieldIndex(JTCS_TO,aFind[0]+1); 281 else 282 OSL_ENSURE(0,"Column not found!"); 283 } 284 pNewConnData->AppendConnLine(*pIter,sRelatedColumn); 285 286 // dann die Conn selber dazu 287 OQueryTableConnection aNewConn(_pView, aNewConnData); 288 // der Verweis auf die lokale Variable ist unkritisch, da NotifyQueryTabConn eine neue Kopie anlegt 289 // und mir hinzufuegen (wenn nicht schon existent) 290 _pView->NotifyTabConnection(aNewConn, sal_False); 291 // don't create an Undo-Action for the new connection : the connection is 292 // covered by the Undo-Action for the tabwin, as the "Undo the insert" will 293 // automatically remove all connections adjacent to the win. 294 // (Because of this automatism we would have an ownerhsip ambiguity for 295 // the connection data if we would insert the conn-Undo-Action) 296 // FS - 21.10.99 - 69183 297 } 298 } 299 } 300 //================================================================== 301 // class OQueryTableView 302 //================================================================== 303 DBG_NAME(OQueryTableView) 304 //------------------------------------------------------------------------ 305 OQueryTableView::OQueryTableView( Window* pParent,OQueryDesignView* pView) 306 : OJoinTableView( pParent,pView) 307 { 308 DBG_CTOR(OQueryTableView,NULL); 309 SetHelpId(HID_CTL_QRYDGNTAB); 310 } 311 312 //------------------------------------------------------------------------ 313 OQueryTableView::~OQueryTableView() 314 { 315 DBG_DTOR(OQueryTableView,NULL); 316 } 317 318 //------------------------------------------------------------------------ 319 sal_Int32 OQueryTableView::CountTableAlias(const String& rName, sal_Int32& rMax) 320 { 321 DBG_CHKTHIS(OQueryTableView,NULL); 322 sal_Int32 nRet = 0; 323 324 OTableWindowMapIterator aIter = GetTabWinMap()->find(rName); 325 while(aIter != GetTabWinMap()->end()) 326 { 327 String aNewName; 328 aNewName = rName; 329 aNewName += '_'; 330 aNewName += String::CreateFromInt32(++nRet); 331 332 aIter = GetTabWinMap()->find(aNewName); 333 } 334 335 rMax = nRet; 336 337 return nRet; 338 } 339 //------------------------------------------------------------------------ 340 void OQueryTableView::ReSync() 341 { 342 DBG_CHKTHIS(OQueryTableView,NULL); 343 TTableWindowData* pTabWinDataList = m_pView->getController().getTableWindowData(); 344 DBG_ASSERT((getTableConnections()->size()==0) && (GetTabWinMap()->size()==0), 345 "vor OQueryTableView::ReSync() bitte ClearAll aufrufen !"); 346 347 // ich brauche eine Sammlung aller Fensternamen, deren Anlegen schief geht, damit ich die entsprechenden Connections 348 // gar nicht erst anlege 349 ::std::vector<String> arrInvalidTables; 350 351 TTableWindowData::reverse_iterator aIter = pTabWinDataList->rbegin(); 352 // Fenster kreieren und einfuegen 353 354 for(;aIter != pTabWinDataList->rend();++aIter) 355 { 356 OQueryTableWindowData* pData = static_cast<OQueryTableWindowData*>(aIter->get()); 357 OTableWindow* pTabWin = createWindow(*aIter); 358 359 // ich gehe jetzt NICHT ueber ShowTabWin, da dieses die Daten des Fensters in die Liste des Docs einfuegt, was 360 // schlecht waere, denn genau von dort hole ich sie ja gerade 361 // also Schritt fuer Schritt 362 if (!pTabWin->Init()) 363 { 364 // das Initialisieren ging schief, dass heisst, dieses TabWin steht nicht zur Verfuegung, also muss ich es inklusive 365 // seiner Daten am Dokument aufraeumen 366 pTabWin->clearListBox(); 367 delete pTabWin; 368 arrInvalidTables.push_back(pData->GetAliasName()); 369 370 pTabWinDataList->erase( ::std::remove(pTabWinDataList->begin(),pTabWinDataList->end(),*aIter) ,pTabWinDataList->end()); 371 continue; 372 } 373 374 (*GetTabWinMap())[pData->GetAliasName()] = pTabWin; // am Anfang einfuegen, da ich die DataList ja rueckwaerts durchlaufe 375 // wenn in den Daten keine Position oder Groesse steht -> Default 376 if (!pData->HasPosition() && !pData->HasSize()) 377 SetDefaultTabWinPosSize(pTabWin); 378 379 pTabWin->Show(); 380 } 381 382 // Verbindungen einfuegen 383 TTableConnectionData* pTabConnDataList = m_pView->getController().getTableConnectionData(); 384 TTableConnectionData::reverse_iterator aConIter = pTabConnDataList->rbegin(); 385 386 for(;aConIter != pTabConnDataList->rend();++aConIter) 387 { 388 OQueryTableConnectionData* pTabConnData = static_cast<OQueryTableConnectionData*>(aConIter->get()); 389 390 // gibt es die beiden Tabellen zur Connection ? 391 String strTabExistenceTest = pTabConnData->getReferencingTable()->GetWinName(); 392 sal_Bool bInvalid = ::std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end(); 393 strTabExistenceTest = pTabConnData->getReferencedTable()->GetWinName(); 394 bInvalid = bInvalid && ::std::find(arrInvalidTables.begin(),arrInvalidTables.end(),strTabExistenceTest) != arrInvalidTables.end(); 395 396 if (bInvalid) 397 { // nein -> Pech gehabt, die Connection faellt weg 398 pTabConnDataList->erase( ::std::remove(pTabConnDataList->begin(),pTabConnDataList->end(),*aConIter) ,pTabConnDataList->end()); 399 continue; 400 } 401 402 // adds a new connection to join view and notifies our accessible and invaldates the controller 403 addConnection(new OQueryTableConnection(this, *aConIter)); 404 } 405 } 406 407 //------------------------------------------------------------------------ 408 void OQueryTableView::ClearAll() 409 { 410 DBG_CHKTHIS(OQueryTableView,NULL); 411 OJoinTableView::ClearAll(); 412 413 SetUpdateMode(sal_True); 414 m_pView->getController().setModified(sal_True); 415 } 416 417 // ----------------------------------------------------------------------------- 418 OTableWindow* OQueryTableView::createWindow(const TTableWindowData::value_type& _pData) 419 { 420 return new OQueryTableWindow(this,_pData); 421 } 422 423 //------------------------------------------------------------------------------ 424 void OQueryTableView::NotifyTabConnection(const OQueryTableConnection& rNewConn, sal_Bool _bCreateUndoAction) 425 { 426 DBG_CHKTHIS(OQueryTableView,NULL); 427 // erst mal schauen, ob ich diese Connection schon habe 428 OQueryTableConnection* pTabConn = NULL; 429 const ::std::vector<OTableConnection*>* pConnections = getTableConnections(); 430 ::std::vector<OTableConnection*>::const_iterator aEnd = pConnections->end(); 431 ::std::vector<OTableConnection*>::const_iterator aIter = ::std::find( pConnections->begin(), 432 aEnd, 433 static_cast<const OTableConnection*>(&rNewConn) 434 ); 435 if(aIter == aEnd ) 436 { 437 aIter = pConnections->begin(); 438 for(;aIter != aEnd;++aIter) 439 { 440 if(*static_cast<OQueryTableConnection*>(*aIter) == rNewConn) 441 { 442 pTabConn = static_cast<OQueryTableConnection*>(*aIter); 443 break; 444 } 445 } 446 } 447 else 448 pTabConn = static_cast<OQueryTableConnection*>(*aIter); 449 // nein -> einfuegen 450 if (pTabConn == NULL) 451 { 452 // die neuen Daten ... 453 OQueryTableConnectionData* pNewData = static_cast< OQueryTableConnectionData*>(rNewConn.GetData()->NewInstance()); 454 pNewData->CopyFrom(*rNewConn.GetData()); 455 TTableConnectionData::value_type aData(pNewData); 456 OQueryTableConnection* pNewConn = new OQueryTableConnection(this, aData); 457 GetConnection(pNewConn); 458 459 connectionModified(this,pNewConn,_bCreateUndoAction); 460 } 461 } 462 // ----------------------------------------------------------------------------- 463 OTableWindowData* OQueryTableView::CreateImpl(const ::rtl::OUString& _rComposedName 464 ,const ::rtl::OUString& _sTableName 465 ,const ::rtl::OUString& _rWinName) 466 { 467 return new OQueryTableWindowData( _rComposedName, _sTableName,_rWinName ); 468 } 469 //------------------------------------------------------------------------------ 470 void OQueryTableView::AddTabWin(const ::rtl::OUString& _rTableName, const ::rtl::OUString& _rAliasName, sal_Bool bNewTable) 471 { 472 DBG_CHKTHIS(OQueryTableView,NULL); 473 // das ist die aus der Basisklasse geerbte Methode, die fuehre ich auf die an meinem Parent zurueck, die mir eventuell einen 474 // Alias dazu bastelt und das an mein anderes AddTabWin weiterreicht 475 476 // leider ist _rTableName voll qualifiziert, das OQueryDesignView erwartet aber einen String, der 477 // nur aus Schema und Tabelle besteht und keinen Katalog enthaelt. 478 Reference< XConnection> xConnection = m_pView->getController().getConnection(); 479 if(!xConnection.is()) 480 return; 481 try 482 { 483 Reference< XDatabaseMetaData > xMetaData = xConnection->getMetaData(); 484 ::rtl::OUString sCatalog, sSchema, sTable; 485 ::dbtools::qualifiedNameComponents(xMetaData, 486 _rTableName, 487 sCatalog, 488 sSchema, 489 sTable, 490 ::dbtools::eInDataManipulation); 491 ::rtl::OUString sRealName(sSchema); 492 if (sRealName.getLength()) 493 sRealName+= ::rtl::OUString('.'); 494 sRealName += sTable; 495 496 AddTabWin(_rTableName, sRealName, _rAliasName, bNewTable); 497 } 498 catch(SQLException&) 499 { 500 OSL_ASSERT(!"qualifiedNameComponents"); 501 } 502 } 503 // ----------------------------------------------------------------------------- 504 // find the table which has a foreign key with this referencedTable name 505 Reference<XPropertySet> getKeyReferencedTo(const Reference<XIndexAccess>& _rxKeys,const ::rtl::OUString& _rReferencedTable) 506 { 507 if(!_rxKeys.is()) 508 return Reference<XPropertySet>(); 509 510 if ( !_rxKeys.is() ) 511 return Reference<XPropertySet>(); 512 // search the one and only primary key 513 const sal_Int32 nCount = _rxKeys->getCount(); 514 for(sal_Int32 i=0;i<nCount ;++i) 515 { 516 Reference<XPropertySet> xKey(_rxKeys->getByIndex(i),UNO_QUERY); 517 if(xKey.is()) 518 { 519 sal_Int32 nKeyType = 0; 520 xKey->getPropertyValue(PROPERTY_TYPE) >>= nKeyType; 521 if(KeyType::FOREIGN == nKeyType) 522 { 523 ::rtl::OUString sReferencedTable; 524 xKey->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= sReferencedTable; 525 // TODO check case 526 if(sReferencedTable == _rReferencedTable) 527 return xKey; 528 } 529 } 530 } 531 return Reference<XPropertySet>(); 532 } 533 //------------------------------------------------------------------------------ 534 void OQueryTableView::AddTabWin(const ::rtl::OUString& _rComposedName, const ::rtl::OUString& _rTableName, const ::rtl::OUString& strAlias, sal_Bool bNewTable) 535 { 536 DBG_CHKTHIS(OQueryTableView,NULL); 537 DBG_ASSERT(_rTableName.getLength() || strAlias.getLength(), "OQueryTableView::AddTabWin : kein Tabellen- und kein Aliasname !"); 538 // wenn der Tabellenname nicht gesetzt ist, steht das fuer ein Dummy-Fenster, das braucht aber wenigstens einen Alias-Namen 539 540 // neue Datenstruktur erzeugen 541 // first check if this already hav it's data 542 sal_Bool bAppend = bNewTable; 543 TTableWindowData::value_type pNewTabWinData; 544 TTableWindowData* pWindowData = getDesignView()->getController().getTableWindowData(); 545 TTableWindowData::iterator aWinIter = pWindowData->begin(); 546 TTableWindowData::iterator aWinEnd = pWindowData->end(); 547 for(;aWinIter != aWinEnd;++aWinIter) 548 { 549 pNewTabWinData = *aWinIter; 550 if (pNewTabWinData && pNewTabWinData->GetWinName() == strAlias && pNewTabWinData->GetComposedName() == _rComposedName && pNewTabWinData->GetTableName() == _rTableName) 551 break; 552 } 553 if ( !bAppend ) 554 bAppend = ( aWinIter == aWinEnd ); 555 if ( bAppend ) 556 pNewTabWinData = createTableWindowData(_rComposedName, _rTableName, strAlias); 557 // die TabWinData brauche ich nicht in die entsprechende Liste der DocShell eintragen, das macht ShowTabWin 558 559 // neues Fenster erzeugen 560 OQueryTableWindow* pNewTabWin = static_cast<OQueryTableWindow*>(createWindow(pNewTabWinData)); 561 // das Init kann ich hier weglassen, da das in ShowTabWin passiert 562 563 // Neue UndoAction 564 OQueryTabWinShowUndoAct* pUndoAction = new OQueryTabWinShowUndoAct(this); 565 pUndoAction->SetTabWin(pNewTabWin); // Fenster 566 sal_Bool bSuccess = ShowTabWin(pNewTabWin, pUndoAction,bAppend); 567 if(!bSuccess) 568 { 569 // reset table window 570 pUndoAction->SetTabWin(NULL); 571 pUndoAction->SetOwnership(sal_False); 572 573 delete pUndoAction; 574 return; 575 } 576 577 // Relationen zwischen den einzelnen Tabellen anzeigen 578 OTableWindowMap* pTabWins = GetTabWinMap(); 579 if(bNewTable && !pTabWins->empty() && _rTableName.getLength()) 580 { 581 modified(); 582 if ( m_pAccessible ) 583 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD, 584 Any(), 585 makeAny(pNewTabWin->GetAccessible()) 586 ); 587 588 do { 589 590 if ( pNewTabWin->GetData()->isQuery() ) 591 break; 592 593 try 594 { 595 ////////////////////////////////////////////////////////////////////// 596 // find relations between the table an the tables already inserted 597 Reference< XIndexAccess> xKeyIndex = pNewTabWin->GetData()->getKeys(); 598 if ( !xKeyIndex.is() ) 599 break; 600 601 Reference<XNameAccess> xFKeyColumns; 602 ::rtl::OUString aReferencedTable; 603 Reference<XColumnsSupplier> xColumnsSupplier; 604 605 const sal_Int32 nKeyCount = xKeyIndex->getCount(); 606 for ( sal_Int32 i=0; i<nKeyCount ; ++i ) 607 { 608 Reference< XPropertySet > xProp( xKeyIndex->getByIndex(i), UNO_QUERY_THROW ); 609 xColumnsSupplier.set( xProp, UNO_QUERY_THROW ); 610 xFKeyColumns.set( xColumnsSupplier->getColumns(), UNO_QUERY_THROW ); 611 612 sal_Int32 nKeyType = 0; 613 xProp->getPropertyValue(PROPERTY_TYPE) >>= nKeyType; 614 615 switch ( nKeyType ) 616 { 617 case KeyType::FOREIGN: 618 { // our new table has a foreign key 619 // so look if the referenced table is already in our list 620 xProp->getPropertyValue(PROPERTY_REFERENCEDTABLE) >>= aReferencedTable; 621 OSL_ENSURE(aReferencedTable.getLength(),"Foreign key without referencedTableName"); 622 623 OTableWindowMap::const_iterator aIter = pTabWins->find(aReferencedTable); 624 OTableWindowMap::const_iterator aEnd = pTabWins->end(); 625 if(aIter == aEnd) 626 { 627 for(aIter = pTabWins->begin();aIter != aEnd;++aIter) 628 { 629 OQueryTableWindow* pTabWinTmp = static_cast<OQueryTableWindow*>(aIter->second); 630 OSL_ENSURE( pTabWinTmp,"TableWindow is null!" ); 631 if ( pTabWinTmp != pNewTabWin && pTabWinTmp->GetComposedName() == aReferencedTable ) 632 break; 633 } 634 } 635 if ( aIter != aEnd && pNewTabWin != aIter->second ) 636 addConnections( this, *pNewTabWin, *static_cast<OQueryTableWindow*>(aIter->second), xFKeyColumns ); 637 } 638 break; 639 640 case KeyType::PRIMARY: 641 { 642 // we have a primary key so look in our list if there exsits a key which this is refered to 643 OTableWindowMap::const_iterator aIter = pTabWins->begin(); 644 OTableWindowMap::const_iterator aEnd = pTabWins->end(); 645 for(;aIter != aEnd;++aIter) 646 { 647 OQueryTableWindow* pTabWinTmp = static_cast<OQueryTableWindow*>(aIter->second); 648 if ( pTabWinTmp == pNewTabWin ) 649 continue; 650 651 if ( pTabWinTmp->GetData()->isQuery() ) 652 continue; 653 654 OSL_ENSURE(pTabWinTmp,"TableWindow is null!"); 655 Reference< XPropertySet > xFKKey = getKeyReferencedTo( pTabWinTmp->GetData()->getKeys(), pNewTabWin->GetComposedName() ); 656 if ( !xFKKey.is() ) 657 continue; 658 659 Reference<XColumnsSupplier> xFKColumnsSupplier( xFKKey, UNO_QUERY_THROW ); 660 Reference< XNameAccess > xTColumns( xFKColumnsSupplier->getColumns(), UNO_QUERY_THROW ); 661 addConnections( this, *pTabWinTmp, *pNewTabWin, xTColumns ); 662 } 663 } 664 break; 665 } 666 } 667 } 668 catch( const Exception& ) 669 { 670 DBG_UNHANDLED_EXCEPTION(); 671 } 672 673 } while ( false ); 674 } 675 676 // mein Parent brauche ich, da es vom Loeschen erfahren soll 677 m_pView->getController().addUndoActionAndInvalidate( pUndoAction ); 678 679 if (bSuccess && m_lnkTabWinsChangeHandler.IsSet()) 680 { 681 TabWinsChangeNotification aHint(TabWinsChangeNotification::AT_ADDED_WIN, pNewTabWin->GetAliasName()); 682 m_lnkTabWinsChangeHandler.Call(&aHint); 683 } 684 } 685 // ----------------------------------------------------------------------------- 686 // ----------------------------------------------------------------------------- 687 void OQueryTableView::AddConnection(const OJoinExchangeData& jxdSource, const OJoinExchangeData& jxdDest) 688 { 689 DBG_CHKTHIS(OQueryTableView,NULL); 690 OQueryTableWindow* pSourceWin = static_cast< OQueryTableWindow*>(jxdSource.pListBox->GetTabWin()); 691 OQueryTableWindow* pDestWin = static_cast< OQueryTableWindow*>(jxdDest.pListBox->GetTabWin()); 692 693 String aSourceFieldName, aDestFieldName; 694 aSourceFieldName = jxdSource.pListBox->GetEntryText(jxdSource.pEntry); 695 aDestFieldName = jxdDest.pListBox->GetEntryText(jxdDest.pEntry); 696 697 OTableConnection* pConn = GetTabConn(pSourceWin,pDestWin,true); 698 if ( !pConn ) 699 { 700 // neues Daten-Objekt 701 OQueryTableConnectionData* pNewConnectionData = new OQueryTableConnectionData(pSourceWin->GetData(), pDestWin->GetData()); 702 TTableConnectionData::value_type aNewConnectionData(pNewConnectionData); 703 704 sal_uInt32 nSourceFieldIndex, nDestFieldIndex; 705 ETableFieldType eSourceFieldType, eDestFieldType; 706 707 // Namen/Position/Typ der beiden betroffenen Felder besorgen ... 708 // Source 709 710 nSourceFieldIndex = jxdSource.pListBox->GetModel()->GetAbsPos(jxdSource.pEntry); 711 eSourceFieldType = static_cast< OTableFieldInfo*>(jxdSource.pEntry->GetUserData())->GetKeyType(); 712 713 // Dest 714 715 nDestFieldIndex = jxdDest.pListBox->GetModel()->GetAbsPos(jxdDest.pEntry); 716 eDestFieldType = static_cast< OTableFieldInfo*>(jxdDest.pEntry->GetUserData())->GetKeyType(); 717 718 // ... und setzen 719 720 pNewConnectionData->SetFieldIndex(JTCS_FROM, nSourceFieldIndex); 721 pNewConnectionData->SetFieldIndex(JTCS_TO, nDestFieldIndex); 722 723 pNewConnectionData->SetFieldType(JTCS_FROM, eSourceFieldType); 724 pNewConnectionData->SetFieldType(JTCS_TO, eDestFieldType); 725 726 pNewConnectionData->AppendConnLine( aSourceFieldName,aDestFieldName ); 727 728 OQueryTableConnection aNewConnection(this, aNewConnectionData); 729 NotifyTabConnection(aNewConnection); 730 // wie immer bei NotifyTabConnection ist das Verwenden lokaler Variablen unkritisch, da sowieso eine Kopie erzeugt wird 731 } 732 else 733 { 734 // the connection could point on the other side 735 if(pConn->GetSourceWin() == pDestWin) 736 { 737 String aTmp(aSourceFieldName); 738 aSourceFieldName = aDestFieldName; 739 aDestFieldName = aTmp; 740 } 741 742 pConn->GetData()->AppendConnLine( aSourceFieldName,aDestFieldName ); 743 744 connectionModified(this,pConn,sal_False); 745 } 746 } 747 // ----------------------------------------------------------------------------- 748 void OQueryTableView::ConnDoubleClicked(OTableConnection* pConnection) 749 { 750 DBG_CHKTHIS(OQueryTableView,NULL); 751 if( openJoinDialog(this,pConnection->GetData(),sal_False) ) 752 { 753 connectionModified(this,pConnection,sal_False); 754 SelectConn( pConnection ); 755 } 756 } 757 // ----------------------------------------------------------------------------- 758 void OQueryTableView::createNewConnection() 759 { 760 TTableConnectionData::value_type pData(new OQueryTableConnectionData()); 761 if( openJoinDialog(this,pData,sal_True) ) 762 { 763 OTableWindowMap* pMap = GetTabWinMap(); 764 OQueryTableWindow* pSourceWin = static_cast< OQueryTableWindow*>((*pMap)[pData->getReferencingTable()->GetWinName()]); 765 OQueryTableWindow* pDestWin = static_cast< OQueryTableWindow*>((*pMap)[pData->getReferencedTable()->GetWinName()]); 766 // first we have to look if the this connection already exists 767 OTableConnection* pConn = GetTabConn(pSourceWin,pDestWin,true); 768 sal_Bool bNew = sal_True; 769 if ( pConn ) 770 { 771 pConn->GetData()->CopyFrom( *pData ); 772 bNew = sal_False; 773 } 774 else 775 { 776 // create a new conenction and append it 777 OQueryTableConnection* pQConn = new OQueryTableConnection(this, pData); 778 GetConnection(pQConn); 779 pConn = pQConn; 780 } 781 connectionModified(this,pConn,bNew); 782 if ( !bNew && pConn == GetSelectedConn() ) // our connection was selected before so we have to reselect it 783 SelectConn( pConn ); 784 } 785 } 786 //------------------------------------------------------------------------------ 787 bool OQueryTableView::RemoveConnection( OTableConnection* _pConnection,sal_Bool /*_bDelete*/ ) 788 { 789 DBG_CHKTHIS(OQueryTableView,NULL); 790 791 // we don't want that our connection will be deleted, we put it in the undo manager 792 bool bRet = OJoinTableView::RemoveConnection( _pConnection,sal_False); 793 794 // add undo action 795 addUndoAction( this, 796 new OQueryDelTabConnUndoAction(this), 797 static_cast< OQueryTableConnection*>(_pConnection), 798 sal_True); 799 return bRet; 800 } 801 802 //------------------------------------------------------------------------------ 803 void OQueryTableView::KeyInput( const KeyEvent& rEvt ) 804 { 805 DBG_CHKTHIS(OQueryTableView,NULL); 806 OJoinTableView::KeyInput( rEvt ); 807 } 808 809 //------------------------------------------------------------------------------ 810 OQueryTableWindow* OQueryTableView::FindTable(const String& rAliasName) 811 { 812 DBG_CHKTHIS(OQueryTableView,NULL); 813 DBG_ASSERT(rAliasName.Len(), "OQueryTableView::FindTable : der AliasName sollte nicht leer sein !"); 814 // (nicht dass es schadet, aber es ist sinnlos und weist vielleicht auf Fehler beim Aufrufer hin) 815 OTableWindowMap::const_iterator aIter = GetTabWinMap()->find(rAliasName); 816 if(aIter != GetTabWinMap()->end()) 817 return static_cast<OQueryTableWindow*>(aIter->second); 818 return NULL; 819 } 820 821 //------------------------------------------------------------------------------ 822 sal_Bool OQueryTableView::FindTableFromField(const String& rFieldName, OTableFieldDescRef& rInfo, sal_uInt16& rCnt) 823 { 824 DBG_CHKTHIS(OQueryTableView,NULL); 825 rCnt = 0; 826 OTableWindowMap::const_iterator aIter = GetTabWinMap()->begin(); 827 OTableWindowMap::const_iterator aEnd = GetTabWinMap()->end(); 828 for(;aIter != aEnd;++aIter) 829 { 830 if(static_cast<OQueryTableWindow*>(aIter->second)->ExistsField(rFieldName, rInfo)) 831 ++rCnt; 832 } 833 834 return rCnt == 1; 835 } 836 837 //------------------------------------------------------------------------------ 838 void OQueryTableView::RemoveTabWin(OTableWindow* pTabWin) 839 { 840 DBG_CHKTHIS(OQueryTableView,NULL); 841 DBG_ASSERT(pTabWin != NULL, "OQueryTableView::RemoveTabWin : Fenster sollte ungleich NULL sein !"); 842 843 // mein Parent brauche ich, da es vom Loeschen erfahren soll 844 OQueryDesignView* pParent = static_cast<OQueryDesignView*>(getDesignView()); 845 846 SfxUndoManager& rUndoMgr = m_pView->getController().GetUndoManager(); 847 rUndoMgr.EnterListAction( String( ModuleRes(STR_QUERY_UNDO_TABWINDELETE) ), String() ); 848 849 // Undo-Action anlegen 850 OQueryTabWinDelUndoAct* pUndoAction = new OQueryTabWinDelUndoAct(this); 851 pUndoAction->SetTabWin(static_cast< OQueryTableWindow*>(pTabWin)); 852 853 // und Fenster verstecken 854 HideTabWin(static_cast< OQueryTableWindow*>(pTabWin), pUndoAction); 855 856 // Undo Actions und Loeschen der Felder in SelectionBrowseBox 857 pParent->TableDeleted( static_cast< OQueryTableWindowData*>(pTabWin->GetData().get())->GetAliasName() ); 858 859 m_pView->getController().addUndoActionAndInvalidate( pUndoAction ); 860 rUndoMgr.LeaveListAction(); 861 862 if (m_lnkTabWinsChangeHandler.IsSet()) 863 { 864 TabWinsChangeNotification aHint(TabWinsChangeNotification::AT_REMOVED_WIN, static_cast< OQueryTableWindow*>(pTabWin)->GetAliasName()); 865 m_lnkTabWinsChangeHandler.Call(&aHint); 866 } 867 868 modified(); 869 if ( m_pAccessible ) 870 m_pAccessible->notifyAccessibleEvent( AccessibleEventId::CHILD, 871 makeAny(pTabWin->GetAccessible()), 872 Any() 873 ); 874 } 875 876 //------------------------------------------------------------------------ 877 void OQueryTableView::EnsureVisible(const OTableWindow* pWin) 878 { 879 DBG_CHKTHIS(OQueryTableView,NULL); 880 881 Invalidate(INVALIDATE_NOCHILDREN); 882 OJoinTableView::EnsureVisible(pWin); 883 } 884 885 //------------------------------------------------------------------------ 886 void OQueryTableView::GetConnection(OQueryTableConnection* pConn) 887 { 888 DBG_CHKTHIS(OQueryTableView,NULL); 889 // bei mir und dem Dokument einfuegen 890 891 addConnection( pConn ); 892 // invalidieren (damit es neu gezeichnet wird) 893 // pConn->Invalidate(); 894 } 895 896 //------------------------------------------------------------------------ 897 void OQueryTableView::DropConnection(OQueryTableConnection* pConn) 898 { 899 DBG_CHKTHIS(OQueryTableView,NULL); 900 // Selektion beachten 901 // bei mir und dem Dokument rausnehmen 902 RemoveConnection( pConn ,sal_False); 903 } 904 905 //------------------------------------------------------------------------ 906 void OQueryTableView::HideTabWin( OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction ) 907 { 908 DBG_CHKTHIS(OQueryTableView,NULL); 909 OTableWindowMap* pTabWins = GetTabWinMap(); 910 DBG_ASSERT(pTabWins != NULL, "OQueryTableView::HideTabWin : habe keine TabWins !"); 911 912 if (pTabWin) 913 { 914 // Fenster 915 // die Position in seinen Daten speichern 916 getDesignView()->SaveTabWinUIConfig(pTabWin); 917 // (ich muss ueber das Parent gehen, da nur das die Position der Scrollbars kennt) 918 // dann aus der Liste der TabWins raus und verstecken 919 OTableWindowMap::iterator aIter = pTabWins->begin(); 920 OTableWindowMap::iterator aEnd = pTabWins->end(); 921 for ( ;aIter != aEnd ; ++aIter ) 922 if ( aIter->second == pTabWin ) 923 { 924 pTabWins->erase( aIter ); 925 break; 926 } 927 928 pTabWin->Hide(); // nicht zerstoeren, steht im Undo!! 929 930 // die Daten zum TabWin muessen auch aus meiner Verantwortung entlassen werden 931 TTableWindowData* pTabWinDataList = m_pView->getController().getTableWindowData(); 932 pTabWinDataList->erase( ::std::remove(pTabWinDataList->begin(),pTabWinDataList->end(),pTabWin->GetData()),pTabWinDataList->end()); 933 // NICHT loeschen, da ja das TabWin selber - das noch lebt - sie auch noch braucht 934 // Entweder geht es irgendwann wieder in meine Verantwortung ueber, (ueber ShowTabWin), dann fuege ich 935 // auch die Daten wieder ein, oder die Undo-Action, die im Augenblick die alleinige Verantwortung fuer das Fenster 936 // und dessen Daten hat, wird zestoert, dann loescht es beides 937 938 if (m_pLastFocusTabWin == pTabWin) 939 m_pLastFocusTabWin = NULL; 940 941 // Verbindungen, die zum Fenster gehoeren, einsammeln und der UndoAction uebergeben 942 sal_Int16 nCnt = 0; 943 const ::std::vector<OTableConnection*>* pTabConList = getTableConnections(); 944 ::std::vector<OTableConnection*>::const_iterator aIter2 = pTabConList->begin(); 945 for(;aIter2 != pTabConList->end();)// the end may change 946 { 947 OQueryTableConnection* pTmpEntry = static_cast<OQueryTableConnection*>(*aIter2); 948 OSL_ENSURE(pTmpEntry,"OQueryTableConnection is null!"); 949 if( pTmpEntry->GetAliasName(JTCS_FROM) == pTabWin->GetAliasName() || 950 pTmpEntry->GetAliasName(JTCS_TO) == pTabWin->GetAliasName() ) 951 { 952 // add to undo list 953 pUndoAction->InsertConnection(pTmpEntry); 954 955 // call base class because we append an undo action 956 // but this time we are in a undo action list 957 OJoinTableView::RemoveConnection(pTmpEntry,sal_False); 958 aIter2 = pTabConList->begin(); 959 ++nCnt; 960 } 961 else 962 ++aIter2; 963 } 964 965 if (nCnt) 966 InvalidateConnections(); 967 968 m_pView->getController().InvalidateFeature(ID_BROWSER_ADDTABLE); 969 970 // der UndoAction sagen, dass das Fenster (inklusive der Connections) jetzt in seinem Besitzt ist 971 pUndoAction->SetOwnership(sal_True); 972 973 // damit habe ich das Doc natuerlich modifiziert 974 m_pView->getController().setModified( sal_True ); 975 m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY); 976 } 977 } 978 979 //------------------------------------------------------------------------ 980 sal_Bool OQueryTableView::ShowTabWin( OQueryTableWindow* pTabWin, OQueryTabWinUndoAct* pUndoAction,sal_Bool _bAppend ) 981 { 982 DBG_CHKTHIS(OQueryTableView,NULL); 983 984 sal_Bool bSuccess = sal_False; 985 986 if (pTabWin) 987 { 988 if (pTabWin->Init()) 989 { 990 TTableWindowData::value_type pData = pTabWin->GetData(); 991 DBG_ASSERT(pData != NULL, "OQueryTableView::ShowTabWin : TabWin hat keine Daten !"); 992 // Wenn die Daten schon PosSize haben, diese benutzen 993 if (pData->HasPosition() && pData->HasSize()) 994 { 995 Size aSize(CalcZoom(pData->GetSize().Width()),CalcZoom(pData->GetSize().Height())); 996 pTabWin->SetPosSizePixel(pData->GetPosition(), aSize); 997 } 998 else 999 // ansonsten selber eine Default-Position ermitteln 1000 SetDefaultTabWinPosSize(pTabWin); 1001 1002 // Fenster zeigen und in Liste eintragen 1003 ::rtl::OUString sName = static_cast< OQueryTableWindowData*>(pData.get())->GetAliasName(); 1004 OSL_ENSURE(GetTabWinMap()->find(sName) == GetTabWinMap()->end(),"Alias name already in list!"); 1005 GetTabWinMap()->insert(OTableWindowMap::value_type(sName,pTabWin)); 1006 1007 pTabWin->Show(); 1008 1009 pTabWin->Update(); 1010 // Das Update ist notwendig, damit die Connections an dem Fenster richtig gezeichnet werden. Klingt absurd, 1011 // ich weiss. Aber die Listbox haelt sich intern ein Member, was bei ersten Zeichnen (nachdem die Listbox im Init 1012 // gerade neu gefuellt wurde) initialisiert wird, und genau dieses Member wird irgendwann benoetigt fuer 1013 // GetEntryPos, und dieses wiederum von der Connection, wenn sie ihren Ansatzpunkt am Fenster feststellen will. 1014 1015 // die Connections 1016 ::std::vector<OTableConnection*>* pTableCon = pUndoAction->GetTabConnList(); 1017 ::std::vector<OTableConnection*>::iterator aIter = pTableCon->begin(); 1018 ::std::vector<OTableConnection*>::iterator aEnd = pTableCon->end(); 1019 1020 for(;aIter != aEnd;++aIter) 1021 addConnection(*aIter); // add all connections from the undo action 1022 1023 // each connection should invalidated inside addConnection so we don't need this here any longer 1024 // if ( !pOwnList->empty() ) 1025 // InvalidateConnections(); 1026 pTableCon->clear(); 1027 1028 // und die Daten des Fensters ebenfalls in Liste (des Docs) 1029 if(_bAppend) 1030 m_pView->getController().getTableWindowData()->push_back(pTabWin->GetData()); 1031 1032 m_pView->getController().InvalidateFeature(ID_BROWSER_ADDTABLE); 1033 1034 // und der UndoAction sagen, dass das Fenster jetzt meine ist ... 1035 pUndoAction->SetOwnership(sal_False); 1036 1037 bSuccess = sal_True; 1038 } 1039 else 1040 { 1041 ////////////////////////////////////////////////////////////////// 1042 // Initialisierung fehlgeschlagen 1043 // (z.B. wenn Verbindung zur Datenbank in diesem Augenblick unterbrochen worden ist) 1044 pTabWin->clearListBox(); 1045 delete pTabWin; 1046 } 1047 } 1048 1049 // damit habe ich das Doc natuerlich modifiziert 1050 if(!m_pView->getController().isReadOnly()) 1051 m_pView->getController().setModified( sal_True ); 1052 1053 m_pView->getController().InvalidateFeature(SID_BROWSER_CLEAR_QUERY); 1054 1055 return bSuccess; 1056 } 1057 //------------------------------------------------------------------------ 1058 void OQueryTableView::InsertField(const OTableFieldDescRef& rInfo) 1059 { 1060 DBG_CHKTHIS(OQueryTableView,NULL); 1061 DBG_ASSERT(getDesignView() != NULL, "OQueryTableView::InsertField : habe kein Parent !"); 1062 static_cast<OQueryDesignView*>(getDesignView())->InsertField(rInfo); 1063 } 1064 //------------------------------------------------------------------------------ 1065 sal_Bool OQueryTableView::ExistsAVisitedConn(const OQueryTableWindow* pFrom) const 1066 { 1067 DBG_CHKTHIS(OQueryTableView,NULL); 1068 const ::std::vector<OTableConnection*>* pList = getTableConnections(); 1069 if (pList) 1070 { 1071 ::std::vector<OTableConnection*>::const_iterator aIter = pList->begin(); 1072 ::std::vector<OTableConnection*>::const_iterator aEnd = pList->end(); 1073 for(;aIter != aEnd;++aIter) 1074 { 1075 OQueryTableConnection* pTemp = static_cast<OQueryTableConnection*>(*aIter); 1076 if (pTemp->IsVisited() && 1077 (pFrom == static_cast< OQueryTableWindow*>(pTemp->GetSourceWin()) || pFrom == static_cast< OQueryTableWindow*>(pTemp->GetDestWin()))) 1078 return pTemp != NULL; 1079 } 1080 } 1081 1082 return sal_False; 1083 } 1084 // ----------------------------------------------------------------------------- 1085 void OQueryTableView::onNoColumns_throw() 1086 { 1087 String sError( ModuleRes( STR_STATEMENT_WITHOUT_RESULT_SET ) ); 1088 ::dbtools::throwSQLException( sError, ::dbtools::SQL_GENERAL_ERROR, NULL ); 1089 } 1090 //------------------------------------------------------------------------------ 1091 bool OQueryTableView::supressCrossNaturalJoin(const TTableConnectionData::value_type& _pData) const 1092 { 1093 OQueryTableConnectionData* pQueryData = static_cast<OQueryTableConnectionData*>(_pData.get()); 1094 return pQueryData && (pQueryData->GetJoinType() == CROSS_JOIN); 1095 } 1096 // ----------------------------------------------------------------------------- 1097