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_TABLETREE_HXX_ 28 #include "tabletree.hxx" 29 #endif 30 #ifndef _DBAUI_TABLETREE_HRC_ 31 #include "tabletree.hrc" 32 #endif 33 #ifndef DBACCESS_IMAGEPROVIDER_HXX 34 #include "imageprovider.hxx" 35 #endif 36 #ifndef _DBAUI_MODULE_DBU_HXX_ 37 #include "moduledbu.hxx" 38 #endif 39 #ifndef _DBU_CONTROL_HRC_ 40 #include "dbu_control.hrc" 41 #endif 42 #ifndef _SV_MENU_HXX 43 #include <vcl/menu.hxx> 44 #endif 45 #ifndef _CONNECTIVITY_DBTOOLS_HXX_ 46 #include <connectivity/dbtools.hxx> 47 #endif 48 #ifndef _COMPHELPER_TYPES_HXX_ 49 #include <comphelper/types.hxx> 50 #endif 51 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC 52 #include "dbustrings.hrc" 53 #endif 54 #ifndef _COM_SUN_STAR_SDB_APPLICATION_DATABASEOBJECT_HPP_ 55 #include <com/sun/star/sdb/application/DatabaseObject.hpp> 56 #endif 57 #ifndef _COM_SUN_STAR_SDB_APPLICATION_DATABASEOBJECTFOLDER_HPP_ 58 #include <com/sun/star/sdb/application/DatabaseObjectContainer.hpp> 59 #endif 60 #ifndef _COM_SUN_STAR_SDBC_XDRIVERACCESS_HPP_ 61 #include <com/sun/star/sdbc/XDriverAccess.hpp> 62 #endif 63 #ifndef _COM_SUN_STAR_SDBCX_XDATADEFINITIONSUPPLIER_HPP_ 64 #include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp> 65 #endif 66 #ifndef _COM_SUN_STAR_SDBCX_XVIEWSSUPPLIER_HPP_ 67 #include <com/sun/star/sdbcx/XViewsSupplier.hpp> 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_SDB_SQLCONTEXT_HPP_ 73 #include <com/sun/star/sdb/SQLContext.hpp> 74 #endif 75 #ifndef _COM_SUN_STAR_SDBC_XROW_HPP_ 76 #include <com/sun/star/sdbc/XRow.hpp> 77 #endif 78 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_ 79 #include <com/sun/star/beans/XPropertySet.hpp> 80 #endif 81 #ifndef _DBAUI_COMMON_TYPES_HXX_ 82 #include "commontypes.hxx" 83 #endif 84 #ifndef _DBAUI_LISTVIEWITEMS_HXX_ 85 #include "listviewitems.hxx" 86 #endif 87 #ifndef TOOLS_DIAGNOSE_EX_H 88 #include <tools/diagnose_ex.h> 89 #endif 90 #ifndef _RTL_USTRBUF_HXX_ 91 #include <rtl/ustrbuf.hxx> 92 #endif 93 #include <connectivity/dbmetadata.hxx> 94 95 #include <algorithm> 96 97 //......................................................................... 98 namespace dbaui 99 { 100 //......................................................................... 101 102 using namespace ::com::sun::star::uno; 103 using namespace ::com::sun::star::sdb; 104 using namespace ::com::sun::star::lang; 105 using namespace ::com::sun::star::sdbc; 106 using namespace ::com::sun::star::sdbcx; 107 using namespace ::com::sun::star::beans; 108 using namespace ::com::sun::star::container; 109 using namespace ::com::sun::star::sdb::application; 110 111 using namespace ::dbtools; 112 using namespace ::comphelper; 113 114 namespace DatabaseObject = ::com::sun::star::sdb::application::DatabaseObject; 115 namespace DatabaseObjectContainer = ::com::sun::star::sdb::application::DatabaseObjectContainer; 116 117 //======================================================================== 118 //= OTableTreeListBox 119 //======================================================================== 120 OTableTreeListBox::OTableTreeListBox( Window* pParent, const Reference< XMultiServiceFactory >& _rxORB, WinBits nWinStyle,sal_Bool _bVirtualRoot ) 121 :OMarkableTreeListBox(pParent,_rxORB,nWinStyle) 122 ,m_pImageProvider( new ImageProvider ) 123 ,m_bVirtualRoot(_bVirtualRoot) 124 ,m_bNoEmptyFolders( false ) 125 { 126 implSetDefaultImages(); 127 } 128 //------------------------------------------------------------------------ 129 OTableTreeListBox::OTableTreeListBox( Window* pParent, const Reference< XMultiServiceFactory >& _rxORB, const ResId& rResId ,sal_Bool _bVirtualRoot) 130 :OMarkableTreeListBox(pParent,_rxORB,rResId) 131 ,m_pImageProvider( new ImageProvider ) 132 ,m_bVirtualRoot(_bVirtualRoot) 133 ,m_bNoEmptyFolders( false ) 134 { 135 implSetDefaultImages(); 136 } 137 138 // ----------------------------------------------------------------------------- 139 OTableTreeListBox::~OTableTreeListBox() 140 { 141 } 142 143 // ----------------------------------------------------------------------------- 144 void OTableTreeListBox::implSetDefaultImages() 145 { 146 ImageProvider aImageProvider; 147 SetDefaultExpandedEntryBmp( aImageProvider.getFolderImage( DatabaseObject::TABLE, false ), BMP_COLOR_NORMAL ); 148 SetDefaultExpandedEntryBmp( aImageProvider.getFolderImage( DatabaseObject::TABLE, true ), BMP_COLOR_HIGHCONTRAST ); 149 SetDefaultCollapsedEntryBmp( aImageProvider.getFolderImage( DatabaseObject::TABLE, false ), BMP_COLOR_NORMAL ); 150 SetDefaultCollapsedEntryBmp( aImageProvider.getFolderImage( DatabaseObject::TABLE, true ), BMP_COLOR_HIGHCONTRAST ); 151 } 152 153 // ----------------------------------------------------------------------------- 154 bool OTableTreeListBox::isFolderEntry( const SvLBoxEntry* _pEntry ) const 155 { 156 sal_Int32 nEntryType = reinterpret_cast< sal_IntPtr >( _pEntry->GetUserData() ); 157 if ( ( nEntryType == DatabaseObjectContainer::TABLES ) 158 || ( nEntryType == DatabaseObjectContainer::CATALOG ) 159 || ( nEntryType == DatabaseObjectContainer::SCHEMA ) 160 ) 161 return true; 162 return false; 163 } 164 165 // ----------------------------------------------------------------------------- 166 void OTableTreeListBox::notifyHiContrastChanged() 167 { 168 implSetDefaultImages(); 169 170 SvLBoxEntry* pEntryLoop = First(); 171 while (pEntryLoop) 172 { 173 sal_uInt16 nCount = pEntryLoop->ItemCount(); 174 for (sal_uInt16 i=0;i<nCount;++i) 175 { 176 SvLBoxItem* pItem = pEntryLoop->GetItem(i); 177 if ( pItem && pItem->IsA() == SV_ITEM_ID_LBOXCONTEXTBMP) 178 { 179 SvLBoxContextBmp* pContextBitmapItem = static_cast< SvLBoxContextBmp* >( pItem ); 180 181 Image aImage, aImageHC; 182 if ( isFolderEntry( pEntryLoop ) ) 183 { 184 aImage = m_pImageProvider->getFolderImage( DatabaseObject::TABLE, false ); 185 aImageHC = m_pImageProvider->getFolderImage( DatabaseObject::TABLE, true ); 186 } 187 else 188 { 189 String sCompleteName( getQualifiedTableName( pEntryLoop ) ); 190 m_pImageProvider->getImages( sCompleteName, DatabaseObject::TABLE, aImage, aImageHC ); 191 } 192 193 pContextBitmapItem->SetBitmap1( aImage, BMP_COLOR_NORMAL ); 194 pContextBitmapItem->SetBitmap2( aImage, BMP_COLOR_NORMAL ); 195 pContextBitmapItem->SetBitmap1( aImageHC, BMP_COLOR_HIGHCONTRAST ); 196 pContextBitmapItem->SetBitmap2( aImageHC, BMP_COLOR_HIGHCONTRAST ); 197 // TODO: Now that we give both images to the entry item, it is not necessary anymore 198 // to do this anytime HC changes - the tree control will do this itself now. 199 // We would only need to properly initialize newly inserted entries. 200 break; 201 } 202 } 203 pEntryLoop = Next(pEntryLoop); 204 } 205 } 206 207 //------------------------------------------------------------------------ 208 void OTableTreeListBox::implOnNewConnection( const Reference< XConnection >& _rxConnection ) 209 { 210 m_xConnection = _rxConnection; 211 m_pImageProvider.reset( new ImageProvider( m_xConnection ) ); 212 } 213 214 //------------------------------------------------------------------------ 215 void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConnection ) throw(SQLException) 216 { 217 Sequence< ::rtl::OUString > sTables, sViews; 218 219 String sCurrentActionError; 220 try 221 { 222 Reference< XTablesSupplier > xTableSupp( _rxConnection, UNO_QUERY_THROW ); 223 sCurrentActionError = String(ModuleRes(STR_NOTABLEINFO)); 224 225 Reference< XNameAccess > xTables,xViews; 226 227 Reference< XViewsSupplier > xViewSupp( _rxConnection, UNO_QUERY ); 228 if ( xViewSupp.is() ) 229 { 230 xViews = xViewSupp->getViews(); 231 if (xViews.is()) 232 sViews = xViews->getElementNames(); 233 } 234 235 xTables = xTableSupp->getTables(); 236 if (xTables.is()) 237 sTables = xTables->getElementNames(); 238 } 239 catch(RuntimeException&) 240 { 241 DBG_ERROR("OTableTreeListBox::UpdateTableList : caught an RuntimeException!"); 242 } 243 catch ( const SQLException& ) 244 { 245 throw; 246 } 247 catch(Exception&) 248 { 249 // a non-SQLException exception occurred ... simply throw an SQLException 250 SQLException aInfo; 251 aInfo.Message = sCurrentActionError; 252 throw aInfo; 253 } 254 255 UpdateTableList( _rxConnection, sTables, sViews ); 256 } 257 // ----------------------------------------------------------------------------- 258 namespace 259 { 260 struct OViewSetter : public ::std::unary_function< OTableTreeListBox::TNames::value_type, bool> 261 { 262 const Sequence< ::rtl::OUString> m_aViews; 263 ::comphelper::TStringMixEqualFunctor m_aEqualFunctor; 264 265 OViewSetter(const Sequence< ::rtl::OUString>& _rViews,sal_Bool _bCase) : m_aViews(_rViews),m_aEqualFunctor(_bCase){} 266 OTableTreeListBox::TNames::value_type operator() (const ::rtl::OUString& lhs) 267 { 268 OTableTreeListBox::TNames::value_type aRet; 269 aRet.first = lhs; 270 const ::rtl::OUString* pIter = m_aViews.getConstArray(); 271 const ::rtl::OUString* pEnd = m_aViews.getConstArray() + m_aViews.getLength(); 272 aRet.second = (::std::find_if(pIter,pEnd,::std::bind2nd(m_aEqualFunctor,lhs)) != pEnd); 273 274 return aRet; 275 } 276 }; 277 278 } 279 // ----------------------------------------------------------------------------- 280 void OTableTreeListBox::UpdateTableList( 281 const Reference< XConnection >& _rxConnection, 282 const Sequence< ::rtl::OUString>& _rTables, 283 const Sequence< ::rtl::OUString>& _rViews 284 ) 285 { 286 TNames aTables; 287 aTables.resize(_rTables.getLength()); 288 const ::rtl::OUString* pIter = _rTables.getConstArray(); 289 const ::rtl::OUString* pEnd = _rTables.getConstArray() + _rTables.getLength(); 290 try 291 { 292 Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData(), UNO_QUERY_THROW ); 293 ::std::transform( pIter, pEnd, 294 aTables.begin(), OViewSetter( _rViews, xMeta->supportsMixedCaseQuotedIdentifiers() ) ); 295 } 296 catch(Exception&) 297 { 298 DBG_UNHANDLED_EXCEPTION(); 299 } 300 UpdateTableList( _rxConnection, aTables ); 301 } 302 303 //------------------------------------------------------------------------ 304 namespace 305 { 306 ::std::vector< ::rtl::OUString > lcl_getMetaDataStrings_throw( const Reference< XResultSet >& _rxMetaDataResult, sal_Int32 _nColumnIndex ) 307 { 308 ::std::vector< ::rtl::OUString > aStrings; 309 Reference< XRow > xRow( _rxMetaDataResult, UNO_QUERY_THROW ); 310 while ( _rxMetaDataResult->next() ) 311 aStrings.push_back( xRow->getString( _nColumnIndex ) ); 312 return aStrings; 313 } 314 315 bool lcl_shouldDisplayEmptySchemasAndCatalogs( const Reference< XConnection >& _rxConnection ) 316 { 317 ::dbtools::DatabaseMetaData aMetaData( _rxConnection ); 318 return aMetaData.displayEmptyTableFolders(); 319 } 320 } 321 322 //------------------------------------------------------------------------ 323 void OTableTreeListBox::UpdateTableList( const Reference< XConnection >& _rxConnection, const TNames& _rTables ) 324 { 325 implOnNewConnection( _rxConnection ); 326 327 // throw away all the old stuff 328 Clear(); 329 330 try 331 { 332 // the root entry saying "all objects" 333 SvLBoxEntry* pAllObjects = NULL; 334 if (haveVirtualRoot()) 335 { 336 String sRootEntryText; 337 TNames::const_iterator aViews = ::std::find_if(_rTables.begin(),_rTables.end(), 338 ::std::compose1(::std::bind2nd(::std::equal_to<sal_Bool>(),sal_False),::std::select2nd<TNames::value_type>())); 339 TNames::const_iterator aTables = ::std::find_if(_rTables.begin(),_rTables.end(), 340 ::std::compose1(::std::bind2nd(::std::equal_to<sal_Bool>(),sal_True),::std::select2nd<TNames::value_type>())); 341 342 if ( aViews == _rTables.end() ) 343 sRootEntryText = String(ModuleRes(STR_ALL_TABLES)); 344 else if ( aTables == _rTables.end() ) 345 sRootEntryText = String(ModuleRes(STR_ALL_VIEWS)); 346 else 347 sRootEntryText = String(ModuleRes(STR_ALL_TABLES_AND_VIEWS)); 348 pAllObjects = InsertEntry( sRootEntryText, NULL, sal_False, LIST_APPEND, reinterpret_cast< void* >( DatabaseObjectContainer::TABLES ) ); 349 } 350 351 if ( _rTables.empty() ) 352 // nothing to do (besides inserting the root entry) 353 return; 354 355 // get the table/view names 356 TNames::const_iterator aIter = _rTables.begin(); 357 TNames::const_iterator aEnd = _rTables.end(); 358 359 Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData(), UNO_QUERY_THROW ); 360 for ( ; aIter != aEnd; ++aIter ) 361 { 362 // add the entry 363 implAddEntry( 364 xMeta, 365 aIter->first, 366 sal_False 367 ); 368 } 369 370 if ( !m_bNoEmptyFolders && lcl_shouldDisplayEmptySchemasAndCatalogs( _rxConnection ) ) 371 { 372 sal_Bool bSupportsCatalogs = xMeta->supportsCatalogsInDataManipulation(); 373 sal_Bool bSupportsSchemas = xMeta->supportsSchemasInDataManipulation(); 374 375 if ( bSupportsCatalogs || bSupportsSchemas ) 376 { 377 // we display empty catalogs if the DB supports catalogs, and they're noted at the beginning of a 378 // composed name. Otherwise, we display empty schematas. (also see the tree structure explained in 379 // implAddEntry) 380 bool bCatalogs = bSupportsCatalogs && xMeta->isCatalogAtStart(); 381 382 ::std::vector< ::rtl::OUString > aFolderNames( lcl_getMetaDataStrings_throw( 383 bCatalogs ? xMeta->getCatalogs() : xMeta->getSchemas(), 1 ) ); 384 sal_Int32 nFolderType = bCatalogs ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA; 385 386 SvLBoxEntry* pRootEntry = getAllObjectsEntry(); 387 for ( ::std::vector< ::rtl::OUString >::const_iterator folder = aFolderNames.begin(); 388 folder != aFolderNames.end(); 389 ++folder 390 ) 391 { 392 SvLBoxEntry* pFolder = GetEntryPosByName( *folder, pRootEntry ); 393 if ( !pFolder ) 394 pFolder = InsertEntry( *folder, pRootEntry, sal_False, LIST_APPEND, reinterpret_cast< void* >( nFolderType ) ); 395 } 396 } 397 } 398 } 399 catch ( const Exception& ) 400 { 401 DBG_UNHANDLED_EXCEPTION(); 402 } 403 } 404 //------------------------------------------------------------------------ 405 sal_Bool OTableTreeListBox::isWildcardChecked(SvLBoxEntry* _pEntry) const 406 { 407 if (_pEntry) 408 { 409 OBoldListboxString* pTextItem = static_cast<OBoldListboxString*>(_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING)); 410 if (pTextItem) 411 return pTextItem->isEmphasized(); 412 } 413 return sal_False; 414 } 415 416 //------------------------------------------------------------------------ 417 void OTableTreeListBox::checkWildcard(SvLBoxEntry* _pEntry) 418 { 419 SetCheckButtonState(_pEntry, SV_BUTTON_CHECKED); 420 checkedButton_noBroadcast(_pEntry); 421 } 422 423 //------------------------------------------------------------------------ 424 SvLBoxEntry* OTableTreeListBox::getAllObjectsEntry() const 425 { 426 return haveVirtualRoot() ? First() : NULL; 427 } 428 429 //------------------------------------------------------------------------ 430 void OTableTreeListBox::checkedButton_noBroadcast(SvLBoxEntry* _pEntry) 431 { 432 OMarkableTreeListBox::checkedButton_noBroadcast(_pEntry); 433 434 // if an entry has children, it makes a difference if the entry is checked because alls children are checked 435 // or if the user checked it explicitly. 436 // So we track explicit (un)checking 437 438 SvButtonState eState = GetCheckButtonState(_pEntry); 439 DBG_ASSERT(SV_BUTTON_TRISTATE != eState, "OTableTreeListBox::CheckButtonHdl: user action which lead to TRISTATE?"); 440 implEmphasize(_pEntry, SV_BUTTON_CHECKED == eState); 441 } 442 443 //------------------------------------------------------------------------ 444 void OTableTreeListBox::implEmphasize(SvLBoxEntry* _pEntry, sal_Bool _bChecked, sal_Bool _bUpdateDescendants, sal_Bool _bUpdateAncestors) 445 { 446 DBG_ASSERT(_pEntry, "OTableTreeListBox::implEmphasize: invalid entry (NULL)!"); 447 448 // special emphasizing handling for the "all objects" entry 449 // 89709 - 16.07.2001 - frank.schoenheit@sun.com 450 sal_Bool bAllObjectsEntryAffected = haveVirtualRoot() && (getAllObjectsEntry() == _pEntry); 451 if ( GetModel()->HasChilds(_pEntry) // the entry has children 452 || bAllObjectsEntryAffected // or it is the "all objects" entry 453 ) 454 { 455 OBoldListboxString* pTextItem = static_cast<OBoldListboxString*>(_pEntry->GetFirstItem(SV_ITEM_ID_BOLDLBSTRING)); 456 if (pTextItem) 457 pTextItem->emphasize(_bChecked); 458 459 if (bAllObjectsEntryAffected) 460 InvalidateEntry(_pEntry); 461 } 462 463 if (_bUpdateDescendants) 464 { 465 // remove the mark for all children of the checked entry 466 SvLBoxEntry* pChildLoop = FirstChild(_pEntry); 467 while (pChildLoop) 468 { 469 if (GetModel()->HasChilds(pChildLoop)) 470 implEmphasize(pChildLoop, sal_False, sal_True, sal_False); 471 pChildLoop = NextSibling(pChildLoop); 472 } 473 } 474 475 if (_bUpdateAncestors) 476 { 477 // remove the mark for all ancestors of the entry 478 if (GetModel()->HasParent(_pEntry)) 479 implEmphasize(GetParent(_pEntry), sal_False, sal_False, sal_True); 480 } 481 } 482 483 //------------------------------------------------------------------------ 484 void OTableTreeListBox::InitEntry(SvLBoxEntry* _pEntry, const XubString& _rString, const Image& _rCollapsedBitmap, const Image& _rExpandedBitmap, SvLBoxButtonKind _eButtonKind) 485 { 486 OMarkableTreeListBox::InitEntry(_pEntry, _rString, _rCollapsedBitmap, _rExpandedBitmap, _eButtonKind); 487 488 // replace the text item with our own one 489 SvLBoxItem* pTextItem = _pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING); 490 DBG_ASSERT(pTextItem, "OTableTreeListBox::InitEntry: no text item!?"); 491 sal_uInt16 nTextPos = _pEntry->GetPos(pTextItem); 492 DBG_ASSERT(((sal_uInt16)-1) != nTextPos, "OTableTreeListBox::InitEntry: no text item pos!"); 493 494 _pEntry->ReplaceItem(new OBoldListboxString(_pEntry, 0, _rString), nTextPos); 495 } 496 497 //------------------------------------------------------------------------ 498 SvLBoxEntry* OTableTreeListBox::implAddEntry( 499 const Reference< XDatabaseMetaData >& _rxMeta, 500 const ::rtl::OUString& _rTableName, 501 sal_Bool _bCheckName 502 ) 503 { 504 OSL_PRECOND( _rxMeta.is(), "OTableTreeListBox::implAddEntry: invalid meta data!" ); 505 if ( !_rxMeta.is() ) 506 return NULL; 507 508 // split the complete name into it's components 509 ::rtl::OUString sCatalog, sSchema, sName; 510 qualifiedNameComponents( _rxMeta, _rTableName, sCatalog, sSchema, sName, ::dbtools::eInDataManipulation ); 511 512 SvLBoxEntry* pParentEntry = getAllObjectsEntry(); 513 514 // if the DB uses catalog at the start of identifiers, then our hierarchy is 515 // catalog 516 // +- schema 517 // +- table 518 // else it is 519 // schema 520 // +- catalog 521 // +- table 522 sal_Bool bCatalogAtStart = _rxMeta->isCatalogAtStart(); 523 const ::rtl::OUString& rFirstName = bCatalogAtStart ? sCatalog : sSchema; 524 const sal_Int32 nFirstFolderType = bCatalogAtStart ? DatabaseObjectContainer::CATALOG : DatabaseObjectContainer::SCHEMA; 525 const ::rtl::OUString& rSecondName = bCatalogAtStart ? sSchema : sCatalog; 526 const sal_Int32 nSecondFolderType = bCatalogAtStart ? DatabaseObjectContainer::SCHEMA : DatabaseObjectContainer::CATALOG; 527 528 if ( rFirstName.getLength() ) 529 { 530 SvLBoxEntry* pFolder = GetEntryPosByName( rFirstName, pParentEntry ); 531 if ( !pFolder ) 532 pFolder = InsertEntry( rFirstName, pParentEntry, sal_False, LIST_APPEND, reinterpret_cast< void* >( nFirstFolderType ) ); 533 pParentEntry = pFolder; 534 } 535 536 if ( rSecondName.getLength() ) 537 { 538 SvLBoxEntry* pFolder = GetEntryPosByName( rSecondName, pParentEntry ); 539 if ( !pFolder ) 540 pFolder = InsertEntry( rSecondName, pParentEntry, sal_False, LIST_APPEND, reinterpret_cast< void* >( nSecondFolderType ) ); 541 pParentEntry = pFolder; 542 } 543 544 SvLBoxEntry* pRet = NULL; 545 if ( !_bCheckName || !GetEntryPosByName( sName, pParentEntry ) ) 546 { 547 pRet = InsertEntry( sName, pParentEntry, sal_False, LIST_APPEND ); 548 549 Image aImage, aImageHC; 550 m_pImageProvider->getImages( _rTableName, DatabaseObject::TABLE, aImage, aImageHC ); 551 552 SetExpandedEntryBmp( pRet, aImage, BMP_COLOR_NORMAL ); 553 SetCollapsedEntryBmp( pRet, aImage, BMP_COLOR_NORMAL ); 554 SetExpandedEntryBmp( pRet, aImageHC, BMP_COLOR_HIGHCONTRAST ); 555 SetCollapsedEntryBmp( pRet, aImageHC, BMP_COLOR_HIGHCONTRAST ); 556 } 557 return pRet; 558 } 559 560 //------------------------------------------------------------------------ 561 NamedDatabaseObject OTableTreeListBox::describeObject( SvLBoxEntry* _pEntry ) 562 { 563 NamedDatabaseObject aObject; 564 565 sal_Int32 nEntryType = reinterpret_cast< sal_IntPtr >( _pEntry->GetUserData() ); 566 567 if ( nEntryType == DatabaseObjectContainer::TABLES ) 568 { 569 aObject.Type = DatabaseObjectContainer::TABLES; 570 } 571 else if ( ( nEntryType == DatabaseObjectContainer::CATALOG ) 572 || ( nEntryType == DatabaseObjectContainer::SCHEMA ) 573 ) 574 { 575 SvLBoxEntry* pParent = GetParent( _pEntry ); 576 sal_Int32 nParentEntryType = pParent ? reinterpret_cast< sal_IntPtr >( pParent->GetUserData() ) : -1; 577 578 ::rtl::OUStringBuffer buffer; 579 if ( nEntryType == DatabaseObjectContainer::CATALOG ) 580 { 581 if ( nParentEntryType == DatabaseObjectContainer::SCHEMA ) 582 { 583 buffer.append( GetEntryText( pParent ) ); 584 buffer.append( sal_Unicode( '.' ) ); 585 } 586 buffer.append( GetEntryText( _pEntry ) ); 587 } 588 else if ( nEntryType == DatabaseObjectContainer::SCHEMA ) 589 { 590 if ( nParentEntryType == DatabaseObjectContainer::CATALOG ) 591 { 592 buffer.append( GetEntryText( pParent ) ); 593 buffer.append( sal_Unicode( '.' ) ); 594 } 595 buffer.append( GetEntryText( _pEntry ) ); 596 } 597 } 598 else 599 { 600 aObject.Type = DatabaseObject::TABLE; 601 aObject.Name = getQualifiedTableName( _pEntry ); 602 } 603 604 return aObject; 605 } 606 607 //------------------------------------------------------------------------ 608 SvLBoxEntry* OTableTreeListBox::addedTable( const ::rtl::OUString& _rName ) 609 { 610 try 611 { 612 Reference< XDatabaseMetaData > xMeta; 613 if ( impl_getAndAssertMetaData( xMeta ) ) 614 return implAddEntry( xMeta, _rName ); 615 } 616 catch( const Exception& ) 617 { 618 DBG_UNHANDLED_EXCEPTION(); 619 } 620 return NULL; 621 } 622 623 //------------------------------------------------------------------------ 624 bool OTableTreeListBox::impl_getAndAssertMetaData( Reference< XDatabaseMetaData >& _out_rMetaData ) const 625 { 626 if ( m_xConnection.is() ) 627 _out_rMetaData = m_xConnection->getMetaData(); 628 OSL_PRECOND( _out_rMetaData.is(), "OTableTreeListBox::impl_getAndAssertMetaData: invalid current connection!" ); 629 return _out_rMetaData.is(); 630 } 631 632 //------------------------------------------------------------------------ 633 String OTableTreeListBox::getQualifiedTableName( SvLBoxEntry* _pEntry ) const 634 { 635 OSL_PRECOND( !isFolderEntry( _pEntry ), "OTableTreeListBox::getQualifiedTableName: folder entries not allowed here!" ); 636 637 try 638 { 639 Reference< XDatabaseMetaData > xMeta; 640 if ( !impl_getAndAssertMetaData( xMeta ) ) 641 return String(); 642 643 ::rtl::OUString sCatalog; 644 ::rtl::OUString sSchema; 645 ::rtl::OUString sTable; 646 647 SvLBoxEntry* pSchema = GetParent( _pEntry ); 648 if ( pSchema ) 649 { 650 SvLBoxEntry* pCatalog = GetParent( pSchema ); 651 if ( pCatalog 652 || ( xMeta->supportsCatalogsInDataManipulation() 653 && !xMeta->supportsSchemasInDataManipulation() 654 ) // here we support catalog but no schema 655 ) 656 { 657 if ( pCatalog == NULL ) 658 { 659 pCatalog = pSchema; 660 pSchema = NULL; 661 } 662 sCatalog = GetEntryText( pCatalog ); 663 } 664 if ( pSchema ) 665 sSchema = GetEntryText(pSchema); 666 } 667 sTable = GetEntryText( _pEntry ); 668 669 return ::dbtools::composeTableName( xMeta, sCatalog, sSchema, sTable, sal_False, ::dbtools::eInDataManipulation ); 670 } 671 catch( const Exception& ) 672 { 673 DBG_UNHANDLED_EXCEPTION(); 674 } 675 return String(); 676 } 677 678 //------------------------------------------------------------------------ 679 SvLBoxEntry* OTableTreeListBox::getEntryByQualifiedName( const ::rtl::OUString& _rName ) 680 { 681 try 682 { 683 Reference< XDatabaseMetaData > xMeta; 684 if ( !impl_getAndAssertMetaData( xMeta ) ) 685 return NULL; 686 687 // split the complete name into it's components 688 ::rtl::OUString sCatalog, sSchema, sName; 689 qualifiedNameComponents(xMeta, _rName, sCatalog, sSchema, sName,::dbtools::eInDataManipulation); 690 691 SvLBoxEntry* pParent = getAllObjectsEntry(); 692 SvLBoxEntry* pCat = NULL; 693 SvLBoxEntry* pSchema = NULL; 694 if ( sCatalog.getLength() ) 695 { 696 pCat = GetEntryPosByName(sCatalog, pParent); 697 if ( pCat ) 698 pParent = pCat; 699 } 700 701 if ( sSchema.getLength() ) 702 { 703 pSchema = GetEntryPosByName(sSchema, pParent); 704 if ( pSchema ) 705 pParent = pSchema; 706 } 707 708 return GetEntryPosByName(sName, pParent); 709 } 710 catch( const Exception& ) 711 { 712 DBG_UNHANDLED_EXCEPTION(); 713 } 714 return NULL; 715 } 716 //------------------------------------------------------------------------ 717 void OTableTreeListBox::removedTable( const ::rtl::OUString& _rName ) 718 { 719 try 720 { 721 SvLBoxEntry* pEntry = getEntryByQualifiedName( _rName ); 722 if ( pEntry ) 723 GetModel()->Remove( pEntry ); 724 } 725 catch( const Exception& ) 726 { 727 DBG_UNHANDLED_EXCEPTION(); 728 } 729 } 730 731 //......................................................................... 732 } // namespace dbaui 733 //......................................................................... 734 735