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