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 $
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>
57 #include <swmodule.hxx>
63 #include <vos/mutex.hxx>
64 #include <vcl/svapp.hxx>
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
;
107 SwDBTreeList_Impl(SwWrtShell
* 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
);
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
);
131 //block necessary due to solaris' compiler behaviour to
132 //remove temporaries at the block's end
134 xContainer
->removeContainerListener( this );
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);
163 aConnections
.DeleteAndDestroy(i
);
168 /* -----------------------------17.07.01 13:24--------------------------------
170 ---------------------------------------------------------------------------*/
171 void SwDBTreeList_Impl::disposing( const EventObject
& ) throw (RuntimeException
)
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()
189 Reference
< XMultiServiceFactory
> xMgr( ::comphelper::getProcessServiceFactory() );
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
);
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
;
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());
227 /*------------------------------------------------------------------------
229 ------------------------------------------------------------------------*/
230 SwDBTreeList::SwDBTreeList(Window
*pParent
, const ResId
& rResId
,
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
);
248 /*------------------------------------------------------------------------
250 ------------------------------------------------------------------------*/
251 SwDBTreeList::~SwDBTreeList()
256 /*------------------------------------------------------------------------
258 ------------------------------------------------------------------------*/
261 void SwDBTreeList::InitTreeList()
263 if(!pImpl
->HasContext() && pImpl
->GetWrtShell())
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
);
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 /*------------------------------------------------------------------------
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();
329 pEntry
= (SvLBoxEntry
*)GetRootLevelParent( pEntry
);
330 Collapse(pEntry
); // zuklappen
333 while ((pChild
= FirstChild(pEntry
)) != 0L)
334 GetModel()->Remove(pChild
);
336 pEntry
= Next(pEntry
);
341 Select(sDBName
, sTableName
, sColumnName
); // force RequestingChilds
347 /*------------------------------------------------------------------------
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
))
365 Reference
<XConnection
> xConnection
= pImpl
->GetConnection(sSourceName
);
366 BOOL bTable
= pParent
->GetUserData() == 0;
367 Reference
<XColumnsSupplier
> xColsSupplier
;
370 Reference
<XTablesSupplier
> xTSupplier
= Reference
<XTablesSupplier
>(xConnection
, UNO_QUERY
);
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
;
380 xColsSupplier
= Reference
<XColumnsSupplier
>(xPropSet
, UNO_QUERY
);
388 Reference
<XQueriesSupplier
> xQSupplier
= Reference
<XQueriesSupplier
>(xConnection
, UNO_QUERY
);
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
;
398 xColsSupplier
= Reference
<XColumnsSupplier
>(xPropSet
, UNO_QUERY
);
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
];
415 InsertEntry(sName
, pParent
);
417 InsertEntry(sName
, pParent
);
421 catch(const Exception
&)
425 else // Tabellennamen
429 String sSourceName
= GetEntryText(pParent
);
430 if(!pImpl
->GetContext()->hasByName(sSourceName
))
432 Reference
<XConnection
> xConnection
= pImpl
->GetConnection(sSourceName
);
433 if (xConnection
.is())
435 Reference
<XTablesSupplier
> xTSupplier
= Reference
<XTablesSupplier
>(xConnection
, UNO_QUERY
);
438 Reference
<XNameAccess
> xTbls
= xTSupplier
->getTables();
439 Sequence
< ::rtl::OUString
> aTblNames
= xTbls
->getElementNames();
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
);
459 Reference
<XNameAccess
> xQueries
= xQSupplier
->getQueries();
460 Sequence
< ::rtl::OUString
> aQueryNames
= xQueries
->getElementNames();
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 /*------------------------------------------------------------------------
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 /*------------------------------------------------------------------------
500 ------------------------------------------------------------------------*/
502 String
SwDBTreeList::GetDBName(String
& rTableName
, String
& rColumnName
, BOOL
* pbIsTable
)
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
));
517 *pbIsTable
= pEntry
->GetUserData() == 0;
519 rTableName
= GetEntryText(pEntry
);
524 /*------------------------------------------------------------------------
525 Beschreibung: Format: Datenbank.Tabelle
526 ------------------------------------------------------------------------*/
529 void SwDBTreeList::Select(const String
& rDBName
, const String
& rTableName
, const String
& rColumnName
)
531 SvLBoxEntry
* pParent
;
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
))
548 if (bShowColumns
&& rColumnName
.Len())
552 if (!pParent
->HasChilds())
553 RequestingChilds(pParent
);
555 while ((pChild
= GetEntry(pParent
, nChild
++)) != NULL
)
556 if (rColumnName
== GetEntryText(pChild
))
563 SvTreeListBox::Select(pChild
);
571 /*------------------------------------------------------------------------
573 ------------------------------------------------------------------------*/
575 void SwDBTreeList::StartDrag( sal_Int8
/*nAction*/, const Point
& /*rPosPixel*/ )
577 String sTableName
, sColumnName
;
578 String
sDBName( GetDBName( sTableName
, sColumnName
));
581 TransferDataContainer
* pContainer
= new TransferDataContainer
;
582 STAR_REFERENCE( datatransfer::XTransferable
) xRef( pContainer
);
583 if( sColumnName
.Len() )
585 // Datenbankfeld draggen
586 svx::OColumnTransferable
aColTransfer(
589 , sdb::CommandType::TABLE
592 ,(CTF_FIELD_DESCRIPTOR
|CTF_COLUMN_DESCRIPTOR
));
593 aColTransfer
.addDataToContainer( pContainer
);
597 sDBName
+= sTableName
;
598 if( sColumnName
.Len() )
601 sDBName
+= sColumnName
;
604 pContainer
->CopyString( FORMAT_STRING
, sDBName
);
605 pContainer
->StartDrag( this, DND_ACTION_COPY
| DND_ACTION_LINK
,
610 /*------------------------------------------------------------------------
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
)