| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sw.hxx" |
| |
| // INCLUDE --------------------------------------------------------------- |
| |
| |
| #include <sot/formats.hxx> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/sdbc/XDataSource.hpp> |
| #include <com/sun/star/sdbcx/XTablesSupplier.hpp> |
| #include <com/sun/star/sdbcx/XColumnsSupplier.hpp> |
| #include <com/sun/star/sdb/XQueriesSupplier.hpp> |
| #include <com/sun/star/sdb/XDatabaseAccess.hpp> |
| #include <com/sun/star/sdb/CommandType.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <comphelper/processfactory.hxx> |
| #include <com/sun/star/sdb/XCompletedConnection.hpp> |
| #include <com/sun/star/container/XContainerListener.hpp> |
| #include <com/sun/star/container/XContainer.hpp> |
| #include <cppuhelper/implbase1.hxx> |
| #include <svx/dbaexchange.hxx> |
| |
| #ifndef _DBMGR_HXX |
| #include <dbmgr.hxx> |
| #endif |
| #include <swmodule.hxx> |
| #ifndef _VIEW_HXX |
| #include <view.hxx> |
| #endif |
| #include <wrtsh.hxx> |
| #include <dbtree.hxx> |
| #include <vos/mutex.hxx> |
| #include <vcl/svapp.hxx> |
| |
| #ifndef _HELPID_H |
| #include <helpid.h> |
| #endif |
| #ifndef _UTLUI_HRC |
| #include <utlui.hrc> |
| #endif |
| |
| #include <unomid.h> |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::sdb; |
| using namespace ::com::sun::star::sdbc; |
| using namespace ::com::sun::star::sdbcx; |
| using namespace ::com::sun::star::task; |
| using namespace ::com::sun::star::beans; |
| |
| /* -----------------------------17.07.01 13:10-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| struct SwConnectionData |
| { |
| ::rtl::OUString sSourceName; |
| Reference<XConnection> xConnection; |
| }; |
| |
| typedef SwConnectionData* SwConnectionDataPtr; |
| SV_DECL_PTRARR_DEL( SwConnectionArr, SwConnectionDataPtr, 32, 32 ) |
| SV_IMPL_PTRARR( SwConnectionArr, SwConnectionDataPtr ) |
| /* -----------------------------17.07.01 13:24-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| class SwDBTreeList_Impl : public cppu::WeakImplHelper1 < XContainerListener > |
| { |
| Reference< XNameAccess > xDBContext; |
| SwConnectionArr aConnections; |
| SwWrtShell* pWrtSh; |
| |
| public: |
| SwDBTreeList_Impl(SwWrtShell* pShell) : |
| pWrtSh(pShell) {} |
| ~SwDBTreeList_Impl(); |
| |
| virtual void SAL_CALL elementInserted( const ContainerEvent& Event ) throw (RuntimeException); |
| virtual void SAL_CALL elementRemoved( const ContainerEvent& Event ) throw (RuntimeException); |
| virtual void SAL_CALL elementReplaced( const ContainerEvent& Event ) throw (RuntimeException); |
| virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException); |
| |
| sal_Bool HasContext(); |
| SwWrtShell* GetWrtShell() { return pWrtSh;} |
| void SetWrtShell(SwWrtShell& rSh) { pWrtSh = &rSh;} |
| Reference< XNameAccess > GetContext() {return xDBContext;} |
| Reference<XConnection> GetConnection(const rtl::OUString& rSourceName); |
| }; |
| /* -----------------------------17.07.01 13:24-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| SwDBTreeList_Impl::~SwDBTreeList_Impl() |
| { |
| Reference<XContainer> xContainer(xDBContext, UNO_QUERY); |
| if(xContainer.is()) |
| { |
| m_refCount++; |
| //block necessary due to solaris' compiler behaviour to |
| //remove temporaries at the block's end |
| { |
| xContainer->removeContainerListener( this ); |
| } |
| m_refCount--; |
| } |
| } |
| /* -----------------------------17.07.01 13:24-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| void SwDBTreeList_Impl::elementInserted( const ContainerEvent& ) throw (RuntimeException) |
| { |
| // information not needed |
| } |
| /* -----------------------------17.07.01 13:24-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| void SwDBTreeList_Impl::elementRemoved( const ContainerEvent& rEvent ) throw (RuntimeException) |
| { |
| vos::OGuard aGuard(Application::GetSolarMutex()); |
| ::rtl::OUString sSource; |
| rEvent.Accessor >>= sSource; |
| for(sal_uInt16 i = 0; i < aConnections.Count(); i++) |
| { |
| SwConnectionDataPtr pPtr = aConnections[i]; |
| if(pPtr->sSourceName == sSource) |
| { |
| // SwConnectionDataPtr pPtr = aConnections[i]; |
| // Reference<XComponent> xComp(pPtr->xConnection, UNO_QUERY); |
| // if(xComp.is()) |
| // xComp->dispose(); |
| aConnections.DeleteAndDestroy(i); |
| break; |
| } |
| } |
| } |
| /* -----------------------------17.07.01 13:24-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| void SwDBTreeList_Impl::disposing( const EventObject& ) throw (RuntimeException) |
| { |
| xDBContext = 0; |
| } |
| /* -----------------------------17.07.01 13:24-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| void SwDBTreeList_Impl::elementReplaced( const ContainerEvent& rEvent ) throw (RuntimeException) |
| { |
| elementRemoved(rEvent); |
| } |
| /* -----------------------------17.07.01 13:24-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| sal_Bool SwDBTreeList_Impl::HasContext() |
| { |
| if(!xDBContext.is()) |
| { |
| Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() ); |
| if( xMgr.is() ) |
| { |
| Reference<XInterface> xInstance = xMgr->createInstance( |
| C2U( "com.sun.star.sdb.DatabaseContext" )); |
| xDBContext = Reference<XNameAccess>(xInstance, UNO_QUERY) ; |
| Reference<XContainer> xContainer(xDBContext, UNO_QUERY); |
| if(xContainer.is()) |
| xContainer->addContainerListener( this ); |
| } |
| DBG_ASSERT(xDBContext.is(), "com.sun.star.sdb.DataBaseContext: service not available"); |
| } |
| return xDBContext.is(); |
| } |
| /* -----------------------------17.07.01 13:24-------------------------------- |
| |
| ---------------------------------------------------------------------------*/ |
| Reference<XConnection> SwDBTreeList_Impl::GetConnection(const rtl::OUString& rSourceName) |
| { |
| Reference<XConnection> xRet; |
| for(sal_uInt16 i = 0; i < aConnections.Count(); i++) |
| { |
| SwConnectionDataPtr pPtr = aConnections[i]; |
| if(pPtr->sSourceName == rSourceName) |
| { |
| xRet = pPtr->xConnection; |
| break; |
| } |
| } |
| if(!xRet.is() && xDBContext.is() && pWrtSh) |
| { |
| SwConnectionDataPtr pPtr = new SwConnectionData(); |
| pPtr->sSourceName = rSourceName; |
| xRet = pWrtSh->GetNewDBMgr()->RegisterConnection(pPtr->sSourceName); |
| aConnections.Insert(pPtr, aConnections.Count()); |
| } |
| return xRet; |
| } |
| /*------------------------------------------------------------------------ |
| Beschreibung: |
| ------------------------------------------------------------------------*/ |
| SwDBTreeList::SwDBTreeList(Window *pParent, const ResId& rResId, |
| SwWrtShell* pSh, |
| const String& rDefDBName, const sal_Bool bShowCol): |
| |
| SvTreeListBox (pParent, rResId), |
| aImageList (SW_RES(ILIST_DB_DLG )), |
| aImageListHC (SW_RES(ILIST_DB_DLG_HC )), |
| sDefDBName (rDefDBName), |
| bInitialized (sal_False), |
| bShowColumns (bShowCol), |
| pImpl(new SwDBTreeList_Impl(pSh)) |
| { |
| SetHelpId(HID_DB_SELECTION_TLB); |
| |
| if (IsVisible()) |
| InitTreeList(); |
| } |
| |
| /*------------------------------------------------------------------------ |
| Beschreibung: |
| ------------------------------------------------------------------------*/ |
| SwDBTreeList::~SwDBTreeList() |
| { |
| delete pImpl; |
| } |
| |
| /*------------------------------------------------------------------------ |
| Beschreibung: |
| ------------------------------------------------------------------------*/ |
| |
| |
| void SwDBTreeList::InitTreeList() |
| { |
| if(!pImpl->HasContext() && pImpl->GetWrtShell()) |
| return; |
| SetSelectionMode(SINGLE_SELECTION); |
| SetStyle(GetStyle()|WB_HASLINES|WB_CLIPCHILDREN|WB_SORT|WB_HASBUTTONS|WB_HASBUTTONSATROOT|WB_HSCROLL); |
| // Font nicht setzen, damit der Font des Controls uebernommen wird! |
| SetSpaceBetweenEntries(0); |
| SetNodeBitmaps( aImageList.GetImage(IMG_COLLAPSE), |
| aImageList.GetImage(IMG_EXPAND ), BMP_COLOR_NORMAL ); |
| SetNodeBitmaps( aImageListHC.GetImage(IMG_COLLAPSE), |
| aImageListHC.GetImage(IMG_EXPAND ), BMP_COLOR_HIGHCONTRAST ); |
| |
| SetDragDropMode(SV_DRAGDROP_APP_COPY); |
| |
| GetModel()->SetCompareHdl(LINK(this, SwDBTreeList, DBCompare)); |
| |
| Sequence< ::rtl::OUString > aDBNames = pImpl->GetContext()->getElementNames(); |
| const ::rtl::OUString* pDBNames = aDBNames.getConstArray(); |
| long nCount = aDBNames.getLength(); |
| |
| Image aImg = aImageList.GetImage(IMG_DB); |
| Image aHCImg = aImageListHC.GetImage(IMG_DB); |
| for(long i = 0; i < nCount; i++) |
| { |
| String sDBName(pDBNames[i]); |
| SvLBoxEntry* pEntry = InsertEntry(sDBName, aImg, aImg, NULL, sal_True); |
| SetExpandedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST); |
| SetCollapsedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST); |
| } |
| String sDBName(sDefDBName.GetToken(0, DB_DELIM)); |
| String sTableName(sDefDBName.GetToken(1, DB_DELIM)); |
| String sColumnName(sDefDBName.GetToken(2, DB_DELIM)); |
| Select(sDBName, sTableName, sColumnName); |
| |
| |
| bInitialized = sal_True; |
| } |
| /*-- 27.05.2004 09:19:09--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| void SwDBTreeList::AddDataSource(const String& rSource) |
| { |
| Image aImg = aImageList.GetImage(IMG_DB); |
| Image aHCImg = aImageListHC.GetImage(IMG_DB); |
| SvLBoxEntry* pEntry = InsertEntry(rSource, aImg, aImg, NULL, sal_True); |
| SetExpandedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST); |
| SetCollapsedEntryBmp(pEntry, aHCImg, BMP_COLOR_HIGHCONTRAST); |
| SvTreeListBox::Select(pEntry); |
| } |
| /*------------------------------------------------------------------------ |
| Beschreibung: |
| ------------------------------------------------------------------------*/ |
| |
| void SwDBTreeList::ShowColumns(sal_Bool bShowCol) |
| { |
| if (bShowCol != bShowColumns) |
| { |
| bShowColumns = bShowCol; |
| String sTableName, sColumnName; |
| String sDBName(GetDBName(sTableName, sColumnName)); |
| |
| SetUpdateMode(sal_False); |
| |
| SvLBoxEntry* pEntry = First(); |
| |
| while (pEntry) |
| { |
| pEntry = (SvLBoxEntry*)GetRootLevelParent( pEntry ); |
| Collapse(pEntry); // zuklappen |
| |
| SvLBoxEntry* pChild; |
| while ((pChild = FirstChild(pEntry)) != 0L) |
| GetModel()->Remove(pChild); |
| |
| pEntry = Next(pEntry); |
| } |
| |
| if (sDBName.Len()) |
| { |
| Select(sDBName, sTableName, sColumnName); // force RequestingChilds |
| } |
| SetUpdateMode(sal_True); |
| } |
| } |
| |
| /*------------------------------------------------------------------------ |
| Beschreibung: |
| ------------------------------------------------------------------------*/ |
| |
| void SwDBTreeList::RequestingChilds(SvLBoxEntry* pParent) |
| { |
| if (!pParent->HasChilds()) |
| { |
| if (GetParent(pParent)) // column names |
| { |
| try |
| { |
| |
| String sSourceName = GetEntryText(GetParent(pParent)); |
| String sTableName = GetEntryText(pParent); |
| |
| if(!pImpl->GetContext()->hasByName(sSourceName)) |
| return; |
| Reference<XConnection> xConnection = pImpl->GetConnection(sSourceName); |
| sal_Bool bTable = pParent->GetUserData() == 0; |
| Reference<XColumnsSupplier> xColsSupplier; |
| if(bTable) |
| { |
| Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY); |
| if(xTSupplier.is()) |
| { |
| Reference<XNameAccess> xTbls = xTSupplier->getTables(); |
| DBG_ASSERT(xTbls->hasByName(sTableName), "table not available anymore?"); |
| try |
| { |
| Any aTable = xTbls->getByName(sTableName); |
| Reference<XPropertySet> xPropSet; |
| aTable >>= xPropSet; |
| xColsSupplier = Reference<XColumnsSupplier>(xPropSet, UNO_QUERY); |
| } |
| catch(Exception&) |
| {} |
| } |
| } |
| else |
| { |
| Reference<XQueriesSupplier> xQSupplier = Reference<XQueriesSupplier>(xConnection, UNO_QUERY); |
| if(xQSupplier.is()) |
| { |
| Reference<XNameAccess> xQueries = xQSupplier->getQueries(); |
| DBG_ASSERT(xQueries->hasByName(sTableName), "table not available anymore?"); |
| try |
| { |
| Any aQuery = xQueries->getByName(sTableName); |
| Reference<XPropertySet> xPropSet; |
| aQuery >>= xPropSet; |
| xColsSupplier = Reference<XColumnsSupplier>(xPropSet, UNO_QUERY); |
| } |
| catch(Exception&) |
| {} |
| } |
| } |
| |
| if(xColsSupplier.is()) |
| { |
| Reference <XNameAccess> xCols = xColsSupplier->getColumns(); |
| Sequence< ::rtl::OUString> aColNames = xCols->getElementNames(); |
| const ::rtl::OUString* pColNames = aColNames.getConstArray(); |
| long nCount = aColNames.getLength(); |
| for (long i = 0; i < nCount; i++) |
| { |
| String sName = pColNames[i]; |
| if(bTable) |
| InsertEntry(sName, pParent); |
| else |
| InsertEntry(sName, pParent); |
| } |
| } |
| } |
| catch(const Exception&) |
| { |
| } |
| } |
| else // Tabellennamen |
| { |
| try |
| { |
| String sSourceName = GetEntryText(pParent); |
| if(!pImpl->GetContext()->hasByName(sSourceName)) |
| return; |
| Reference<XConnection> xConnection = pImpl->GetConnection(sSourceName); |
| if (xConnection.is()) |
| { |
| Reference<XTablesSupplier> xTSupplier = Reference<XTablesSupplier>(xConnection, UNO_QUERY); |
| if(xTSupplier.is()) |
| { |
| Reference<XNameAccess> xTbls = xTSupplier->getTables(); |
| Sequence< ::rtl::OUString> aTblNames = xTbls->getElementNames(); |
| String sTableName; |
| long nCount = aTblNames.getLength(); |
| const ::rtl::OUString* pTblNames = aTblNames.getConstArray(); |
| Image aImg = aImageList.GetImage(IMG_DBTABLE); |
| Image aHCImg = aImageListHC.GetImage(IMG_DBTABLE); |
| for (long i = 0; i < nCount; i++) |
| { |
| sTableName = pTblNames[i]; |
| SvLBoxEntry* pTableEntry = InsertEntry(sTableName, aImg, aImg, pParent, bShowColumns); |
| //to discriminate between queries and tables the user data of table entries is set |
| pTableEntry->SetUserData((void*)0); |
| SetExpandedEntryBmp(pTableEntry, aHCImg, BMP_COLOR_HIGHCONTRAST); |
| SetCollapsedEntryBmp(pTableEntry, aHCImg, BMP_COLOR_HIGHCONTRAST); |
| } |
| } |
| |
| Reference<XQueriesSupplier> xQSupplier = Reference<XQueriesSupplier>(xConnection, UNO_QUERY); |
| if(xQSupplier.is()) |
| { |
| Reference<XNameAccess> xQueries = xQSupplier->getQueries(); |
| Sequence< ::rtl::OUString> aQueryNames = xQueries->getElementNames(); |
| String sQueryName; |
| long nCount = aQueryNames.getLength(); |
| const ::rtl::OUString* pQueryNames = aQueryNames.getConstArray(); |
| Image aImg = aImageList.GetImage(IMG_DBQUERY); |
| Image aHCImg = aImageListHC.GetImage(IMG_DBQUERY); |
| for (long i = 0; i < nCount; i++) |
| { |
| sQueryName = pQueryNames[i]; |
| SvLBoxEntry* pQueryEntry = InsertEntry(sQueryName, aImg, aImg, pParent, bShowColumns); |
| pQueryEntry->SetUserData((void*)1); |
| SetExpandedEntryBmp(pQueryEntry, aHCImg, BMP_COLOR_HIGHCONTRAST); |
| SetCollapsedEntryBmp( pQueryEntry, aHCImg, BMP_COLOR_HIGHCONTRAST); |
| } |
| } |
| } |
| } |
| catch(const Exception&) |
| { |
| } |
| } |
| } |
| } |
| |
| /*------------------------------------------------------------------------ |
| Beschreibung: |
| ------------------------------------------------------------------------*/ |
| |
| IMPL_LINK( SwDBTreeList, DBCompare, SvSortData*, pData ) |
| { |
| SvLBoxEntry* pRight = (SvLBoxEntry*)(pData->pRight ); |
| |
| if (GetParent(pRight) && GetParent(GetParent(pRight))) |
| return COMPARE_GREATER; // Spaltennamen nicht sortieren |
| |
| return DefaultCompare(pData); // Sonst Basisklasse rufen |
| } |
| |
| /*------------------------------------------------------------------------ |
| Beschreibung: |
| ------------------------------------------------------------------------*/ |
| |
| String SwDBTreeList::GetDBName(String& rTableName, String& rColumnName, sal_Bool* pbIsTable) |
| { |
| String sDBName; |
| SvLBoxEntry* pEntry = FirstSelected(); |
| |
| if (pEntry && GetParent(pEntry)) |
| { |
| if (GetParent(GetParent(pEntry))) |
| { |
| rColumnName = GetEntryText(pEntry); |
| pEntry = GetParent(pEntry); // Spaltenname war selektiert |
| } |
| sDBName = GetEntryText(GetParent(pEntry)); |
| if(pbIsTable) |
| { |
| *pbIsTable = pEntry->GetUserData() == 0; |
| } |
| rTableName = GetEntryText(pEntry); |
| } |
| return sDBName; |
| } |
| |
| /*------------------------------------------------------------------------ |
| Beschreibung: Format: Datenbank.Tabelle |
| ------------------------------------------------------------------------*/ |
| |
| |
| void SwDBTreeList::Select(const String& rDBName, const String& rTableName, const String& rColumnName) |
| { |
| SvLBoxEntry* pParent; |
| SvLBoxEntry* pChild; |
| sal_uInt16 nParent = 0; |
| sal_uInt16 nChild = 0; |
| |
| while ((pParent = GetEntry(nParent++)) != NULL) |
| { |
| if (rDBName == GetEntryText(pParent)) |
| { |
| if (!pParent->HasChilds()) |
| RequestingChilds(pParent); |
| while ((pChild = GetEntry(pParent, nChild++)) != NULL) |
| { |
| if (rTableName == GetEntryText(pChild)) |
| { |
| pParent = pChild; |
| |
| if (bShowColumns && rColumnName.Len()) |
| { |
| nChild = 0; |
| |
| if (!pParent->HasChilds()) |
| RequestingChilds(pParent); |
| |
| while ((pChild = GetEntry(pParent, nChild++)) != NULL) |
| if (rColumnName == GetEntryText(pChild)) |
| break; |
| } |
| if (!pChild) |
| pChild = pParent; |
| |
| MakeVisible(pChild); |
| SvTreeListBox::Select(pChild); |
| return; |
| } |
| } |
| } |
| } |
| } |
| |
| /*------------------------------------------------------------------------ |
| Beschreibung: |
| ------------------------------------------------------------------------*/ |
| |
| void SwDBTreeList::StartDrag( sal_Int8 /*nAction*/, const Point& /*rPosPixel*/ ) |
| { |
| String sTableName, sColumnName; |
| String sDBName( GetDBName( sTableName, sColumnName )); |
| if( sDBName.Len() ) |
| { |
| TransferDataContainer* pContainer = new TransferDataContainer; |
| STAR_REFERENCE( datatransfer::XTransferable ) xRef( pContainer ); |
| if( sColumnName.Len() ) |
| { |
| // Datenbankfeld draggen |
| svx::OColumnTransferable aColTransfer( |
| sDBName |
| ,::rtl::OUString() |
| , sdb::CommandType::TABLE |
| ,sTableName |
| , sColumnName |
| ,(CTF_FIELD_DESCRIPTOR |CTF_COLUMN_DESCRIPTOR )); |
| aColTransfer.addDataToContainer( pContainer ); |
| } |
| |
| sDBName += '.'; |
| sDBName += sTableName; |
| if( sColumnName.Len() ) |
| { |
| sDBName += '.'; |
| sDBName += sColumnName; |
| } |
| |
| pContainer->CopyString( FORMAT_STRING, sDBName ); |
| pContainer->StartDrag( this, DND_ACTION_COPY | DND_ACTION_LINK, |
| Link() ); |
| } |
| } |
| |
| /*------------------------------------------------------------------------ |
| Beschreibung: |
| ------------------------------------------------------------------------*/ |
| sal_Int8 SwDBTreeList::AcceptDrop( const AcceptDropEvent& /*rEvt*/ ) |
| { |
| return DND_ACTION_NONE; |
| } |
| /*-- 07.10.2003 13:28:22--------------------------------------------------- |
| |
| -----------------------------------------------------------------------*/ |
| void SwDBTreeList::SetWrtShell(SwWrtShell& rSh) |
| { |
| pImpl->SetWrtShell(rSh); |
| if (IsVisible() && !bInitialized) |
| InitTreeList(); |
| } |