Update ooo320-m1
[ooovba.git] / sw / source / ui / dbui / dbtree.cxx
blob5502941cb97354a178996d73f8d985ad43192aa4
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dbtree.cxx,v $
10 * $Revision: 1.26 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
34 // INCLUDE ---------------------------------------------------------------
37 #include <sot/formats.hxx>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/container/XNameAccess.hpp>
40 #include <com/sun/star/sdbc/XDataSource.hpp>
41 #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
42 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
43 #include <com/sun/star/sdb/XQueriesSupplier.hpp>
44 #include <com/sun/star/sdb/XDatabaseAccess.hpp>
45 #include <com/sun/star/sdb/CommandType.hpp>
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 #include <comphelper/processfactory.hxx>
48 #include <com/sun/star/sdb/XCompletedConnection.hpp>
49 #include <com/sun/star/container/XContainerListener.hpp>
50 #include <com/sun/star/container/XContainer.hpp>
51 #include <cppuhelper/implbase1.hxx>
52 #include <svx/dbaexchange.hxx>
54 #ifndef _DBMGR_HXX
55 #include <dbmgr.hxx>
56 #endif
57 #include <swmodule.hxx>
58 #ifndef _VIEW_HXX
59 #include <view.hxx>
60 #endif
61 #include <wrtsh.hxx>
62 #include <dbtree.hxx>
63 #include <vos/mutex.hxx>
64 #include <vcl/svapp.hxx>
66 #ifndef _HELPID_H
67 #include <helpid.h>
68 #endif
69 #ifndef _UTLUI_HRC
70 #include <utlui.hrc>
71 #endif
73 #include <unomid.h>
75 using namespace ::com::sun::star;
76 using namespace ::com::sun::star::uno;
77 using namespace ::com::sun::star::container;
78 using namespace ::com::sun::star::lang;
79 using namespace ::com::sun::star::sdb;
80 using namespace ::com::sun::star::sdbc;
81 using namespace ::com::sun::star::sdbcx;
82 using namespace ::com::sun::star::task;
83 using namespace ::com::sun::star::beans;
85 /* -----------------------------17.07.01 13:10--------------------------------
87 ---------------------------------------------------------------------------*/
88 struct SwConnectionData
90 ::rtl::OUString sSourceName;
91 Reference<XConnection> xConnection;
94 typedef SwConnectionData* SwConnectionDataPtr;
95 SV_DECL_PTRARR_DEL( SwConnectionArr, SwConnectionDataPtr, 32, 32 )
96 SV_IMPL_PTRARR( SwConnectionArr, SwConnectionDataPtr )
97 /* -----------------------------17.07.01 13:24--------------------------------
99 ---------------------------------------------------------------------------*/
100 class SwDBTreeList_Impl : public cppu::WeakImplHelper1 < XContainerListener >
102 Reference< XNameAccess > xDBContext;
103 SwConnectionArr aConnections;
104 SwWrtShell* pWrtSh;
106 public:
107 SwDBTreeList_Impl(SwWrtShell* pShell) :
108 pWrtSh(pShell) {}
109 ~SwDBTreeList_Impl();
111 virtual void SAL_CALL elementInserted( const ContainerEvent& Event ) throw (RuntimeException);
112 virtual void SAL_CALL elementRemoved( const ContainerEvent& Event ) throw (RuntimeException);
113 virtual void SAL_CALL elementReplaced( const ContainerEvent& Event ) throw (RuntimeException);
114 virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);
116 BOOL HasContext();
117 SwWrtShell* GetWrtShell() { return pWrtSh;}
118 void SetWrtShell(SwWrtShell& rSh) { pWrtSh = &rSh;}
119 Reference< XNameAccess > GetContext() {return xDBContext;}
120 Reference<XConnection> GetConnection(const rtl::OUString& rSourceName);
122 /* -----------------------------17.07.01 13:24--------------------------------
124 ---------------------------------------------------------------------------*/
125 SwDBTreeList_Impl::~SwDBTreeList_Impl()
127 Reference<XContainer> xContainer(xDBContext, UNO_QUERY);
128 if(xContainer.is())
130 m_refCount++;
131 //block necessary due to solaris' compiler behaviour to
132 //remove temporaries at the block's end
134 xContainer->removeContainerListener( this );
136 m_refCount--;
139 /* -----------------------------17.07.01 13:24--------------------------------
141 ---------------------------------------------------------------------------*/
142 void SwDBTreeList_Impl::elementInserted( const ContainerEvent& ) throw (RuntimeException)
144 // information not needed
146 /* -----------------------------17.07.01 13:24--------------------------------
148 ---------------------------------------------------------------------------*/
149 void SwDBTreeList_Impl::elementRemoved( const ContainerEvent& rEvent ) throw (RuntimeException)
151 vos::OGuard aGuard(Application::GetSolarMutex());
152 ::rtl::OUString sSource;
153 rEvent.Accessor >>= sSource;
154 for(USHORT i = 0; i < aConnections.Count(); i++)
156 SwConnectionDataPtr pPtr = aConnections[i];
157 if(pPtr->sSourceName == sSource)
159 // SwConnectionDataPtr pPtr = aConnections[i];
160 // Reference<XComponent> xComp(pPtr->xConnection, UNO_QUERY);
161 // if(xComp.is())
162 // xComp->dispose();
163 aConnections.DeleteAndDestroy(i);
164 break;
168 /* -----------------------------17.07.01 13:24--------------------------------
170 ---------------------------------------------------------------------------*/
171 void SwDBTreeList_Impl::disposing( const EventObject& ) throw (RuntimeException)
173 xDBContext = 0;
175 /* -----------------------------17.07.01 13:24--------------------------------
177 ---------------------------------------------------------------------------*/
178 void SwDBTreeList_Impl::elementReplaced( const ContainerEvent& rEvent ) throw (RuntimeException)
180 elementRemoved(rEvent);
182 /* -----------------------------17.07.01 13:24--------------------------------
184 ---------------------------------------------------------------------------*/
185 BOOL SwDBTreeList_Impl::HasContext()
187 if(!xDBContext.is())
189 Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
190 if( xMgr.is() )
192 Reference<XInterface> xInstance = xMgr->createInstance(
193 C2U( "com.sun.star.sdb.DatabaseContext" ));
194 xDBContext = Reference<XNameAccess>(xInstance, UNO_QUERY) ;
195 Reference<XContainer> xContainer(xDBContext, UNO_QUERY);
196 if(xContainer.is())
197 xContainer->addContainerListener( this );
199 DBG_ASSERT(xDBContext.is(), "com.sun.star.sdb.DataBaseContext: service not available");
201 return xDBContext.is();
203 /* -----------------------------17.07.01 13:24--------------------------------
205 ---------------------------------------------------------------------------*/
206 Reference<XConnection> SwDBTreeList_Impl::GetConnection(const rtl::OUString& rSourceName)
208 Reference<XConnection> xRet;
209 for(USHORT i = 0; i < aConnections.Count(); i++)
211 SwConnectionDataPtr pPtr = aConnections[i];
212 if(pPtr->sSourceName == rSourceName)
214 xRet = pPtr->xConnection;
215 break;
218 if(!xRet.is() && xDBContext.is() && pWrtSh)
220 SwConnectionDataPtr pPtr = new SwConnectionData();
221 pPtr->sSourceName = rSourceName;
222 xRet = pWrtSh->GetNewDBMgr()->RegisterConnection(pPtr->sSourceName);
223 aConnections.Insert(pPtr, aConnections.Count());
225 return xRet;
227 /*------------------------------------------------------------------------
228 Beschreibung:
229 ------------------------------------------------------------------------*/
230 SwDBTreeList::SwDBTreeList(Window *pParent, const ResId& rResId,
231 SwWrtShell* pSh,
232 const String& rDefDBName, const BOOL bShowCol):
234 SvTreeListBox (pParent, rResId),
235 aImageList (SW_RES(ILIST_DB_DLG )),
236 aImageListHC (SW_RES(ILIST_DB_DLG_HC )),
237 sDefDBName (rDefDBName),
238 bInitialized (FALSE),
239 bShowColumns (bShowCol),
240 pImpl(new SwDBTreeList_Impl(pSh))
242 SetHelpId(HID_DB_SELECTION_TLB);
244 if (IsVisible())
245 InitTreeList();
248 /*------------------------------------------------------------------------
249 Beschreibung:
250 ------------------------------------------------------------------------*/
251 SwDBTreeList::~SwDBTreeList()
253 delete pImpl;
256 /*------------------------------------------------------------------------
257 Beschreibung:
258 ------------------------------------------------------------------------*/
261 void SwDBTreeList::InitTreeList()
263 if(!pImpl->HasContext() && pImpl->GetWrtShell())
264 return;
265 SetSelectionMode(SINGLE_SELECTION);
266 SetWindowBits(WB_HASLINES|WB_CLIPCHILDREN|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL);
267 // Font nicht setzen, damit der Font des Controls uebernommen wird!
268 SetSpaceBetweenEntries(0);
269 SetNodeBitmaps( aImageList.GetImage(IMG_COLLAPSE),
270 aImageList.GetImage(IMG_EXPAND ), BMP_COLOR_NORMAL );
271 SetNodeBitmaps( aImageListHC.GetImage(IMG_COLLAPSE),
272 aImageListHC.GetImage(IMG_EXPAND ), BMP_COLOR_HIGHCONTRAST );
274 SetDragDropMode(SV_DRAGDROP_APP_COPY);
276 GetModel()->SetCompareHdl(LINK(this, SwDBTreeList, DBCompare));
278 Sequence< ::rtl::OUString > aDBNames = pImpl->GetContext()->getElementNames();
279 const ::rtl::OUString* pDBNames = aDBNames.getConstArray();
280 long nCount = aDBNames.getLength();
282 Image aImg = aImageList.GetImage(IMG_DB);
283 Image aHCImg = aImageListHC.GetImage(IMG_DB);
284 for(long i = 0; i < nCount; i++)
286 String sDBName(pDBNames[i]);
287 SvLBoxEntry* pEntry = InsertEntry(sDBName, aImg, aImg, NULL, TRUE);
288 SetExpandedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
289 SetCollapsedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
291 String sDBName(sDefDBName.GetToken(0, DB_DELIM));
292 String sTableName(sDefDBName.GetToken(1, DB_DELIM));
293 String sColumnName(sDefDBName.GetToken(2, DB_DELIM));
294 Select(sDBName, sTableName, sColumnName);
297 bInitialized = TRUE;
299 /*-- 27.05.2004 09:19:09---------------------------------------------------
301 -----------------------------------------------------------------------*/
302 void SwDBTreeList::AddDataSource(const String& rSource)
304 Image aImg = aImageList.GetImage(IMG_DB);
305 Image aHCImg = aImageListHC.GetImage(IMG_DB);
306 SvLBoxEntry* pEntry = InsertEntry(rSource, aImg, aImg, NULL, TRUE);
307 SetExpandedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
308 SetCollapsedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
309 SvTreeListBox::Select(pEntry);
311 /*------------------------------------------------------------------------
312 Beschreibung:
313 ------------------------------------------------------------------------*/
315 void SwDBTreeList::ShowColumns(BOOL bShowCol)
317 if (bShowCol != bShowColumns)
319 bShowColumns = bShowCol;
320 String sTableName, sColumnName;
321 String sDBName(GetDBName(sTableName, sColumnName));
323 SetUpdateMode(FALSE);
325 SvLBoxEntry* pEntry = First();
327 while (pEntry)
329 pEntry = (SvLBoxEntry*)GetRootLevelParent( pEntry );
330 Collapse(pEntry); // zuklappen
332 SvLBoxEntry* pChild;
333 while ((pChild = FirstChild(pEntry)) != 0L)
334 GetModel()->Remove(pChild);
336 pEntry = Next(pEntry);
339 if (sDBName.Len())
341 Select(sDBName, sTableName, sColumnName); // force RequestingChilds
343 SetUpdateMode(TRUE);
347 /*------------------------------------------------------------------------
348 Beschreibung:
349 ------------------------------------------------------------------------*/
351 void SwDBTreeList::RequestingChilds(SvLBoxEntry* pParent)
353 if (!pParent->HasChilds())
355 if (GetParent(pParent)) // column names
360 String sSourceName = GetEntryText(GetParent(pParent));
361 String sTableName = GetEntryText(pParent);
363 if(!pImpl->GetContext()->hasByName(sSourceName))
364 return;
365 Reference<XConnection> xConnection = pImpl->GetConnection(sSourceName);
366 BOOL bTable = pParent->GetUserData() == 0;
367 Reference<XColumnsSupplier> xColsSupplier;
368 if(bTable)
370 Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY);
371 if(xTSupplier.is())
373 Reference<XNameAccess> xTbls = xTSupplier->getTables();
374 DBG_ASSERT(xTbls->hasByName(sTableName), "table not available anymore?");
377 Any aTable = xTbls->getByName(sTableName);
378 Reference<XPropertySet> xPropSet;
379 aTable >>= xPropSet;
380 xColsSupplier = Reference<XColumnsSupplier>(xPropSet, UNO_QUERY);
382 catch(Exception&)
386 else
388 Reference<XQueriesSupplier> xQSupplier = Reference<XQueriesSupplier>(xConnection, UNO_QUERY);
389 if(xQSupplier.is())
391 Reference<XNameAccess> xQueries = xQSupplier->getQueries();
392 DBG_ASSERT(xQueries->hasByName(sTableName), "table not available anymore?");
395 Any aQuery = xQueries->getByName(sTableName);
396 Reference<XPropertySet> xPropSet;
397 aQuery >>= xPropSet;
398 xColsSupplier = Reference<XColumnsSupplier>(xPropSet, UNO_QUERY);
400 catch(Exception&)
405 if(xColsSupplier.is())
407 Reference <XNameAccess> xCols = xColsSupplier->getColumns();
408 Sequence< ::rtl::OUString> aColNames = xCols->getElementNames();
409 const ::rtl::OUString* pColNames = aColNames.getConstArray();
410 long nCount = aColNames.getLength();
411 for (long i = 0; i < nCount; i++)
413 String sName = pColNames[i];
414 if(bTable)
415 InsertEntry(sName, pParent);
416 else
417 InsertEntry(sName, pParent);
421 catch(const Exception&)
425 else // Tabellennamen
429 String sSourceName = GetEntryText(pParent);
430 if(!pImpl->GetContext()->hasByName(sSourceName))
431 return;
432 Reference<XConnection> xConnection = pImpl->GetConnection(sSourceName);
433 if (xConnection.is())
435 Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY);
436 if(xTSupplier.is())
438 Reference<XNameAccess> xTbls = xTSupplier->getTables();
439 Sequence< ::rtl::OUString> aTblNames = xTbls->getElementNames();
440 String sTableName;
441 long nCount = aTblNames.getLength();
442 const ::rtl::OUString* pTblNames = aTblNames.getConstArray();
443 Image aImg = aImageList.GetImage(IMG_DBTABLE);
444 Image aHCImg = aImageListHC.GetImage(IMG_DBTABLE);
445 for (long i = 0; i < nCount; i++)
447 sTableName = pTblNames[i];
448 SvLBoxEntry* pTableEntry = InsertEntry(sTableName, aImg, aImg, pParent, bShowColumns);
449 //to discriminate between queries and tables the user data of table entries is set
450 pTableEntry->SetUserData((void*)0);
451 SetExpandedEntryBmp(pTableEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
452 SetCollapsedEntryBmp(pTableEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
456 Reference<XQueriesSupplier> xQSupplier = Reference<XQueriesSupplier>(xConnection, UNO_QUERY);
457 if(xQSupplier.is())
459 Reference<XNameAccess> xQueries = xQSupplier->getQueries();
460 Sequence< ::rtl::OUString> aQueryNames = xQueries->getElementNames();
461 String sQueryName;
462 long nCount = aQueryNames.getLength();
463 const ::rtl::OUString* pQueryNames = aQueryNames.getConstArray();
464 Image aImg = aImageList.GetImage(IMG_DBQUERY);
465 Image aHCImg = aImageListHC.GetImage(IMG_DBQUERY);
466 for (long i = 0; i < nCount; i++)
468 sQueryName = pQueryNames[i];
469 SvLBoxEntry* pQueryEntry = InsertEntry(sQueryName, aImg, aImg, pParent, bShowColumns);
470 pQueryEntry->SetUserData((void*)1);
471 SetExpandedEntryBmp(pQueryEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
472 SetCollapsedEntryBmp( pQueryEntry, aHCImg, BMP_COLOR_HIGHCONTRAST);
477 catch(const Exception&)
484 /*------------------------------------------------------------------------
485 Beschreibung:
486 ------------------------------------------------------------------------*/
488 IMPL_LINK( SwDBTreeList, DBCompare, SvSortData*, pData )
490 SvLBoxEntry* pRight = (SvLBoxEntry*)(pData->pRight );
492 if (GetParent(pRight) && GetParent(GetParent(pRight)))
493 return COMPARE_GREATER; // Spaltennamen nicht sortieren
495 return DefaultCompare(pData); // Sonst Basisklasse rufen
498 /*------------------------------------------------------------------------
499 Beschreibung:
500 ------------------------------------------------------------------------*/
502 String SwDBTreeList::GetDBName(String& rTableName, String& rColumnName, BOOL* pbIsTable)
504 String sDBName;
505 SvLBoxEntry* pEntry = FirstSelected();
507 if (pEntry && GetParent(pEntry))
509 if (GetParent(GetParent(pEntry)))
511 rColumnName = GetEntryText(pEntry);
512 pEntry = GetParent(pEntry); // Spaltenname war selektiert
514 sDBName = GetEntryText(GetParent(pEntry));
515 if(pbIsTable)
517 *pbIsTable = pEntry->GetUserData() == 0;
519 rTableName = GetEntryText(pEntry);
521 return sDBName;
524 /*------------------------------------------------------------------------
525 Beschreibung: Format: Datenbank.Tabelle
526 ------------------------------------------------------------------------*/
529 void SwDBTreeList::Select(const String& rDBName, const String& rTableName, const String& rColumnName)
531 SvLBoxEntry* pParent;
532 SvLBoxEntry* pChild;
533 USHORT nParent = 0;
534 USHORT nChild = 0;
536 while ((pParent = GetEntry(nParent++)) != NULL)
538 if (rDBName == GetEntryText(pParent))
540 if (!pParent->HasChilds())
541 RequestingChilds(pParent);
542 while ((pChild = GetEntry(pParent, nChild++)) != NULL)
544 if (rTableName == GetEntryText(pChild))
546 pParent = pChild;
548 if (bShowColumns && rColumnName.Len())
550 nChild = 0;
552 if (!pParent->HasChilds())
553 RequestingChilds(pParent);
555 while ((pChild = GetEntry(pParent, nChild++)) != NULL)
556 if (rColumnName == GetEntryText(pChild))
557 break;
559 if (!pChild)
560 pChild = pParent;
562 MakeVisible(pChild);
563 SvTreeListBox::Select(pChild);
564 return;
571 /*------------------------------------------------------------------------
572 Beschreibung:
573 ------------------------------------------------------------------------*/
575 void SwDBTreeList::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ )
577 String sTableName, sColumnName;
578 String sDBName( GetDBName( sTableName, sColumnName ));
579 if( sDBName.Len() )
581 TransferDataContainer* pContainer = new TransferDataContainer;
582 STAR_REFERENCE( datatransfer::XTransferable ) xRef( pContainer );
583 if( sColumnName.Len() )
585 // Datenbankfeld draggen
586 svx::OColumnTransferable aColTransfer(
587 sDBName
588 ,::rtl::OUString()
589 , sdb::CommandType::TABLE
590 ,sTableName
591 , sColumnName
592 ,(CTF_FIELD_DESCRIPTOR |CTF_COLUMN_DESCRIPTOR ));
593 aColTransfer.addDataToContainer( pContainer );
596 sDBName += '.';
597 sDBName += sTableName;
598 if( sColumnName.Len() )
600 sDBName += '.';
601 sDBName += sColumnName;
604 pContainer->CopyString( FORMAT_STRING, sDBName );
605 pContainer->StartDrag( this, DND_ACTION_COPY | DND_ACTION_LINK,
606 Link() );
610 /*------------------------------------------------------------------------
611 Beschreibung:
612 ------------------------------------------------------------------------*/
613 sal_Int8 SwDBTreeList::AcceptDrop( const AcceptDropEvent& /*rEvt*/ )
615 return DND_ACTION_NONE;
617 /*-- 07.10.2003 13:28:22---------------------------------------------------
619 -----------------------------------------------------------------------*/
620 void SwDBTreeList::SetWrtShell(SwWrtShell& rSh)
622 pImpl->SetWrtShell(rSh);
623 if (IsVisible() && !bInitialized)
624 InitTreeList();