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