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