LCOV - code coverage report
Current view: top level - svtools/source/contnr - treelistbox.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 909 2140 42.5 %
Date: 2014-11-03 Functions: 121 281 43.1 %
Legend: Lines: hit not hit

          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             :     TODO:
      22             :         - delete anchor in SelectionEngine when selecting manually
      23             :         - SelectAll( false ) => only repaint the delselected entries
      24             : */
      25             : 
      26             : #include <svtools/treelistbox.hxx>
      27             : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      28             : #include <vcl/svapp.hxx>
      29             : #include <vcl/accel.hxx>
      30             : #include <vcl/i18nhelp.hxx>
      31             : #include <vcl/builder.hxx>
      32             : #include <vcl/settings.hxx>
      33             : #include <sot/formats.hxx>
      34             : #include <unotools/accessiblestatesethelper.hxx>
      35             : #include <rtl/instance.hxx>
      36             : #include <comphelper/string.hxx>
      37             : 
      38             : #include <svtools/svmedit.hxx>
      39             : #include <svtools/svlbitm.hxx>
      40             : #include <svtools/treelistentry.hxx>
      41             : #include <svtools/viewdataentry.hxx>
      42             : #include "svimpbox.hxx"
      43             : 
      44             : #include <set>
      45             : #include <string.h>
      46             : #include <vector>
      47             : 
      48             : using namespace ::com::sun::star::accessibility;
      49             : 
      50             : // Drag&Drop
      51             : static SvTreeListBox* pDDSource = NULL;
      52             : static SvTreeListBox* pDDTarget = NULL;
      53             : 
      54             : 
      55             : #define SVLBOX_ACC_RETURN 1
      56             : #define SVLBOX_ACC_ESCAPE 2
      57             : 
      58             : // ***************************************************************
      59             : 
      60           0 : class MyEdit_Impl : public Edit
      61             : {
      62             :     SvInplaceEdit2* pOwner;
      63             : public:
      64             :                  MyEdit_Impl( vcl::Window* pParent, SvInplaceEdit2* pOwner );
      65             :     virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
      66             :     virtual void LoseFocus() SAL_OVERRIDE;
      67             : };
      68             : 
      69           0 : class MyMultiEdit_Impl : public MultiLineEdit
      70             : {
      71             :     SvInplaceEdit2* pOwner;
      72             : public:
      73             :                  MyMultiEdit_Impl( vcl::Window* pParent, SvInplaceEdit2* pOwner );
      74             :     virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
      75             :     virtual void LoseFocus() SAL_OVERRIDE;
      76             : };
      77             : 
      78           0 : MyEdit_Impl::MyEdit_Impl( vcl::Window* pParent, SvInplaceEdit2* _pOwner ) :
      79             : 
      80             :     Edit( pParent, WB_LEFT ),
      81             : 
      82           0 :     pOwner( _pOwner )
      83             : 
      84             : {
      85           0 : }
      86             : 
      87           0 : void MyEdit_Impl::KeyInput( const KeyEvent& rKEvt )
      88             : {
      89           0 :     if( !pOwner->KeyInput( rKEvt ))
      90           0 :         Edit::KeyInput( rKEvt );
      91           0 : }
      92             : 
      93           0 : void MyEdit_Impl::LoseFocus()
      94             : {
      95           0 :     pOwner->LoseFocus();
      96           0 : }
      97             : 
      98           0 : MyMultiEdit_Impl::MyMultiEdit_Impl( vcl::Window* pParent, SvInplaceEdit2* _pOwner )
      99             :     : MultiLineEdit( pParent,
     100             :     WB_CENTER
     101           0 :     ), pOwner(_pOwner)
     102             : {
     103           0 : }
     104             : 
     105           0 : void MyMultiEdit_Impl::KeyInput( const KeyEvent& rKEvt )
     106             : {
     107           0 :     if( !pOwner->KeyInput( rKEvt ))
     108           0 :         MultiLineEdit::KeyInput( rKEvt );
     109           0 : }
     110             : 
     111           0 : void MyMultiEdit_Impl::LoseFocus()
     112             : {
     113           0 :     pOwner->LoseFocus();
     114           0 : }
     115             : 
     116             : 
     117           0 : SvInplaceEdit2::SvInplaceEdit2
     118             : (
     119             :     vcl::Window* pParent, const Point& rPos,
     120             :     const Size& rSize,
     121             :     const OUString& rData,
     122             :     const Link& rNotifyEditEnd,
     123             :     const Selection& rSelection,
     124             :     bool bMulti
     125             : ) :
     126             : 
     127             :      aCallBackHdl       ( rNotifyEditEnd ),
     128             :     bCanceled           ( false ),
     129           0 :     bAlreadyInCallBack  ( false )
     130             : 
     131             : {
     132             : 
     133           0 :     if( bMulti )
     134           0 :         pEdit = new MyMultiEdit_Impl( pParent, this );
     135             :     else
     136           0 :         pEdit = new MyEdit_Impl( pParent, this );
     137             : 
     138           0 :     vcl::Font aFont( pParent->GetFont() );
     139           0 :     aFont.SetTransparent( false );
     140           0 :     Color aColor( pParent->GetBackground().GetColor() );
     141           0 :     aFont.SetFillColor(aColor );
     142           0 :     pEdit->SetFont( aFont );
     143           0 :     pEdit->SetBackground( pParent->GetBackground() );
     144           0 :     pEdit->SetPosPixel( rPos );
     145           0 :     pEdit->SetSizePixel( rSize );
     146           0 :     pEdit->SetText( rData );
     147           0 :     pEdit->SetSelection( rSelection );
     148           0 :     pEdit->SaveValue();
     149             : 
     150           0 :     aAccReturn.InsertItem( SVLBOX_ACC_RETURN, vcl::KeyCode(KEY_RETURN) );
     151           0 :     aAccEscape.InsertItem( SVLBOX_ACC_ESCAPE, vcl::KeyCode(KEY_ESCAPE) );
     152             : 
     153           0 :     aAccReturn.SetActivateHdl( LINK( this, SvInplaceEdit2, ReturnHdl_Impl) );
     154           0 :     aAccEscape.SetActivateHdl( LINK( this, SvInplaceEdit2, EscapeHdl_Impl) );
     155           0 :     Application::InsertAccel( &aAccReturn );
     156           0 :     Application::InsertAccel( &aAccEscape );
     157             : 
     158           0 :     pEdit->Show();
     159           0 :     pEdit->GrabFocus();
     160           0 : }
     161             : 
     162           0 : SvInplaceEdit2::~SvInplaceEdit2()
     163             : {
     164           0 :     if( !bAlreadyInCallBack )
     165             :     {
     166           0 :         Application::RemoveAccel( &aAccReturn );
     167           0 :         Application::RemoveAccel( &aAccEscape );
     168             :     }
     169           0 :     delete pEdit;
     170           0 : }
     171             : 
     172           0 : OUString SvInplaceEdit2::GetSavedValue() const
     173             : {
     174           0 :     return pEdit->GetSavedValue();
     175             : }
     176             : 
     177           0 : void SvInplaceEdit2::Hide()
     178             : {
     179           0 :     pEdit->Hide();
     180           0 : }
     181             : 
     182             : 
     183           0 : IMPL_LINK_NOARG_INLINE_START(SvInplaceEdit2, ReturnHdl_Impl)
     184             : {
     185           0 :     bCanceled = false;
     186           0 :     CallCallBackHdl_Impl();
     187           0 :     return 1;
     188             : }
     189           0 : IMPL_LINK_NOARG_INLINE_END(SvInplaceEdit2, ReturnHdl_Impl)
     190             : 
     191           0 : IMPL_LINK_NOARG_INLINE_START(SvInplaceEdit2, EscapeHdl_Impl)
     192             : {
     193           0 :     bCanceled = true;
     194           0 :     CallCallBackHdl_Impl();
     195           0 :     return 1;
     196             : }
     197           0 : IMPL_LINK_NOARG_INLINE_END(SvInplaceEdit2, EscapeHdl_Impl)
     198             : 
     199             : 
     200           0 : bool SvInplaceEdit2::KeyInput( const KeyEvent& rKEvt )
     201             : {
     202           0 :     vcl::KeyCode aCode = rKEvt.GetKeyCode();
     203           0 :     sal_uInt16 nCode = aCode.GetCode();
     204             : 
     205           0 :     switch ( nCode )
     206             :     {
     207             :         case KEY_ESCAPE:
     208           0 :             bCanceled = true;
     209           0 :             CallCallBackHdl_Impl();
     210           0 :             return true;
     211             : 
     212             :         case KEY_RETURN:
     213           0 :             bCanceled = false;
     214           0 :             CallCallBackHdl_Impl();
     215           0 :             return true;
     216             :     }
     217           0 :     return false;
     218             : }
     219             : 
     220           0 : void SvInplaceEdit2::StopEditing( bool bCancel )
     221             : {
     222           0 :     if ( !bAlreadyInCallBack )
     223             :     {
     224           0 :         bCanceled = bCancel;
     225           0 :         CallCallBackHdl_Impl();
     226             :     }
     227           0 : }
     228             : 
     229           0 : void SvInplaceEdit2::LoseFocus()
     230             : {
     231           0 :     if ( !bAlreadyInCallBack
     232           0 :     && ((!Application::GetFocusWindow()) || !pEdit->IsChild( Application::GetFocusWindow()) )
     233             :     )
     234             :     {
     235           0 :         bCanceled = false;
     236           0 :         aTimer.SetTimeout(10);
     237           0 :         aTimer.SetTimeoutHdl(LINK(this,SvInplaceEdit2,Timeout_Impl));
     238           0 :         aTimer.Start();
     239             :     }
     240           0 : }
     241             : 
     242           0 : IMPL_LINK_NOARG_INLINE_START(SvInplaceEdit2, Timeout_Impl)
     243             : {
     244           0 :     CallCallBackHdl_Impl();
     245           0 :     return 0;
     246             : }
     247           0 : IMPL_LINK_NOARG_INLINE_END(SvInplaceEdit2, Timeout_Impl)
     248             : 
     249           0 : void SvInplaceEdit2::CallCallBackHdl_Impl()
     250             : {
     251           0 :     aTimer.Stop();
     252           0 :     if ( !bAlreadyInCallBack )
     253             :     {
     254           0 :         bAlreadyInCallBack = true;
     255           0 :         Application::RemoveAccel( &aAccReturn );
     256           0 :         Application::RemoveAccel( &aAccEscape );
     257           0 :         pEdit->Hide();
     258           0 :         aCallBackHdl.Call( this );
     259             :     }
     260           0 : }
     261             : 
     262           0 : OUString SvInplaceEdit2::GetText() const
     263             : {
     264           0 :     return pEdit->GetText();
     265             : }
     266             : 
     267             : // ***************************************************************
     268             : // class SvLBoxTab
     269             : // ***************************************************************
     270             : 
     271             : 
     272           0 : SvLBoxTab::SvLBoxTab()
     273             : {
     274           0 :     nPos = 0;
     275           0 :     pUserData = 0;
     276           0 :     nFlags = 0;
     277           0 : }
     278             : 
     279        3664 : SvLBoxTab::SvLBoxTab( long nPosition, sal_uInt16 nTabFlags )
     280             : {
     281        3664 :     nPos = nPosition;
     282        3664 :     pUserData = 0;
     283        3664 :     nFlags = nTabFlags;
     284        3664 : }
     285             : 
     286           0 : SvLBoxTab::SvLBoxTab( const SvLBoxTab& rTab )
     287             : {
     288           0 :     nPos = rTab.nPos;
     289           0 :     pUserData = rTab.pUserData;
     290           0 :     nFlags = rTab.nFlags;
     291           0 : }
     292             : 
     293        3656 : SvLBoxTab::~SvLBoxTab()
     294             : {
     295        3656 : }
     296             : 
     297             : 
     298        5969 : long SvLBoxTab::CalcOffset( long nItemWidth, long nTabWidth )
     299             : {
     300        5969 :     long nOffset = 0;
     301        5969 :     if ( nFlags & SV_LBOXTAB_ADJUST_RIGHT )
     302             :     {
     303           0 :         nOffset = nTabWidth - nItemWidth;
     304           0 :         if( nOffset < 0 )
     305           0 :             nOffset = 0;
     306             :     }
     307        5969 :     else if ( nFlags & SV_LBOXTAB_ADJUST_CENTER )
     308             :     {
     309        1783 :         if( nFlags & SV_LBOXTAB_FORCE )
     310             :         {
     311             :             // correct implementation of centering
     312           0 :             nOffset = ( nTabWidth - nItemWidth ) / 2;
     313           0 :             if( nOffset < 0 )
     314           0 :                 nOffset = 0;
     315             :         }
     316             :         else
     317             :         {
     318             :             // historically grown, wrong calculation of tabs which is needed by
     319             :             // Abo-Tabbox, Tools/Options/Customize etc.
     320        1783 :             nItemWidth++;
     321        1783 :             nOffset = -( nItemWidth / 2 );
     322             :         }
     323             :     }
     324        5969 :     return nOffset;
     325             : }
     326             : 
     327             : // ***************************************************************
     328             : // class SvLBoxItem
     329             : // ***************************************************************
     330             : 
     331             : 
     332        4350 : SvLBoxItem::SvLBoxItem( SvTreeListEntry*, sal_uInt16 )
     333             : {
     334        4350 : }
     335             : 
     336           0 : SvLBoxItem::SvLBoxItem()
     337             : {
     338           0 : }
     339             : 
     340        4350 : SvLBoxItem::~SvLBoxItem()
     341             : {
     342        4350 : }
     343             : 
     344        4170 : const Size& SvLBoxItem::GetSize(const SvTreeListBox* pView, const SvTreeListEntry* pEntry) const
     345             : {
     346        4170 :     const SvViewDataItem* pViewData = pView->GetViewDataItem( pEntry, this );
     347        4170 :     return pViewData->maSize;
     348             : }
     349             : 
     350        6474 : const Size& SvLBoxItem::GetSize(const SvViewDataEntry* pData, sal_uInt16 nItemPos) const
     351             : {
     352        6474 :     const SvViewDataItem* pIData = pData->GetItem(nItemPos);
     353        6474 :     return pIData->maSize;
     354             : }
     355             : 
     356         262 : struct SvTreeListBoxImpl
     357             : {
     358             :     bool m_bIsEmptyTextAllowed:1;
     359             :     bool m_bEntryMnemonicsEnabled:1;
     360             :     bool m_bDoingQuickSelection:1;
     361             : 
     362             :     Link* m_pLink;
     363             : 
     364             :     vcl::MnemonicEngine m_aMnemonicEngine;
     365             :     vcl::QuickSelectionEngine m_aQuickSelectionEngine;
     366             : 
     367         266 :     SvTreeListBoxImpl(SvTreeListBox& _rBox) :
     368             :         m_bIsEmptyTextAllowed(true),
     369             :         m_bEntryMnemonicsEnabled(false),
     370             :         m_bDoingQuickSelection(false),
     371             :         m_pLink(NULL),
     372             :         m_aMnemonicEngine(_rBox),
     373         266 :         m_aQuickSelectionEngine(_rBox) {}
     374             : };
     375             : 
     376             : 
     377          24 : SvTreeListBox::SvTreeListBox(vcl::Window* pParent, WinBits nWinStyle) :
     378             :     Control(pParent, nWinStyle | WB_CLIPCHILDREN),
     379             :     DropTargetHelper(this),
     380             :     DragSourceHelper(this),
     381          24 :     mpImpl(new SvTreeListBoxImpl(*this)),
     382             :     mbContextBmpExpanded(false),
     383             :     mbAlternatingRowColors(false),
     384             :     eSelMode(NO_SELECTION),
     385          48 :     nMinWidthInChars(0)
     386             : {
     387          24 :     nDragOptions =  DND_ACTION_COPYMOVE | DND_ACTION_LINK;
     388          24 :     nImpFlags = 0;
     389          24 :     pTargetEntry = 0;
     390          24 :     nDragDropMode = 0;
     391          24 :     SvTreeList* pTempModel = new SvTreeList;
     392          24 :     pTempModel->SetRefCount( 0 );
     393          24 :     SetBaseModel(pTempModel);
     394          24 :     pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
     395          24 :     pModel->InsertView( this );
     396          24 :     pHdlEntry = 0;
     397          24 :     pEdCtrl = 0;
     398          24 :     eSelMode = SINGLE_SELECTION;
     399          24 :     nDragDropMode = SV_DRAGDROP_NONE;
     400          24 :     SetType(WINDOW_TREELISTBOX);
     401             : 
     402          24 :     InitTreeView();
     403             : 
     404          24 :     SetSublistOpenWithLeftRight();
     405          24 : }
     406             : 
     407         242 : SvTreeListBox::SvTreeListBox(vcl::Window* pParent, const ResId& rResId) :
     408             :     Control(pParent, rResId),
     409             :     DropTargetHelper(this),
     410             :     DragSourceHelper(this),
     411         242 :     mpImpl(new SvTreeListBoxImpl(*this)),
     412             :     mbContextBmpExpanded(false),
     413             :     mbAlternatingRowColors(false),
     414             :     eSelMode(NO_SELECTION),
     415         484 :     nMinWidthInChars(0)
     416             : {
     417         242 :     pTargetEntry = 0;
     418         242 :     nImpFlags = 0;
     419         242 :     nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK;
     420         242 :     nDragDropMode = 0;
     421         242 :     SvTreeList* pTempModel = new SvTreeList;
     422         242 :     pTempModel->SetRefCount( 0 );
     423         242 :     SetBaseModel(pTempModel);
     424         242 :     pModel->InsertView( this );
     425         242 :     pHdlEntry = 0;
     426         242 :     pEdCtrl = 0;
     427         242 :     pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
     428         242 :     SetType(WINDOW_TREELISTBOX);
     429             : 
     430         242 :     InitTreeView();
     431         242 :     Resize();
     432             : 
     433         242 :     SetSublistOpenWithLeftRight();
     434         242 : }
     435             : 
     436           0 : extern "C" SAL_DLLPUBLIC_EXPORT vcl::Window* SAL_CALL makeSvTreeListBox(vcl::Window *pParent, VclBuilder::stringmap &rMap)
     437             : {
     438           0 :     WinBits nWinStyle = WB_TABSTOP;
     439           0 :     OString sBorder = VclBuilder::extractCustomProperty(rMap);
     440           0 :     if (!sBorder.isEmpty())
     441           0 :         nWinStyle |= WB_BORDER;
     442           0 :     return new SvTreeListBox(pParent, nWinStyle);
     443             : }
     444             : 
     445         618 : void SvTreeListBox::Clear()
     446             : {
     447         618 :     pModel->Clear();  // Model calls SvTreeListBox::ModelHasCleared()
     448         618 : }
     449             : 
     450          16 : void SvTreeListBox::EnableEntryMnemonics( bool _bEnable )
     451             : {
     452          16 :     if ( _bEnable == IsEntryMnemonicsEnabled() )
     453          16 :         return;
     454             : 
     455          16 :     mpImpl->m_bEntryMnemonicsEnabled = _bEnable;
     456          16 :     Invalidate();
     457             : }
     458             : 
     459        1783 : bool SvTreeListBox::IsEntryMnemonicsEnabled() const
     460             : {
     461        1783 :     return mpImpl->m_bEntryMnemonicsEnabled;
     462             : }
     463             : 
     464           0 : IMPL_LINK_INLINE_START( SvTreeListBox, CloneHdl_Impl, SvTreeListEntry*, pEntry )
     465             : {
     466           0 :     return reinterpret_cast<sal_IntPtr>(CloneEntry((SvTreeListEntry*)pEntry));
     467             : }
     468           0 : IMPL_LINK_INLINE_END( SvTreeListBox, CloneHdl_Impl, SvTreeListEntry*, pEntry )
     469             : 
     470           6 : sal_uLong SvTreeListBox::Insert( SvTreeListEntry* pEntry, SvTreeListEntry* pParent, sal_uLong nPos )
     471             : {
     472           6 :     sal_uLong nInsPos = pModel->Insert( pEntry, pParent, nPos );
     473           6 :     if(mbAlternatingRowColors)
     474             :     {
     475           0 :         if(nPos == TREELIST_APPEND)
     476           0 :             pEntry->SetBackColor( Prev(pEntry) && Prev(pEntry)->GetBackColor() == GetSettings().GetStyleSettings().GetRowColor() ?
     477           0 :                                     GetSettings().GetStyleSettings().GetAlternatingRowColor() :
     478           0 :                                     GetSettings().GetStyleSettings().GetRowColor() );
     479             :         else
     480           0 :             SetAlternatingRowColors( true );
     481             :     }
     482           6 :     return nInsPos;
     483             : }
     484             : 
     485        1444 : sal_uLong SvTreeListBox::Insert( SvTreeListEntry* pEntry,sal_uLong nRootPos )
     486             : {
     487        1444 :     sal_uLong nInsPos = pModel->Insert( pEntry, nRootPos );
     488        1444 :     if(mbAlternatingRowColors)
     489             :     {
     490           0 :         if(nRootPos == TREELIST_APPEND)
     491           0 :             pEntry->SetBackColor( Prev(pEntry) && Prev(pEntry)->GetBackColor() == GetSettings().GetStyleSettings().GetRowColor() ?
     492           0 :                                     GetSettings().GetStyleSettings().GetAlternatingRowColor() :
     493           0 :                                     GetSettings().GetStyleSettings().GetRowColor() );
     494             :         else
     495           0 :             SetAlternatingRowColors( true );
     496             :     }
     497        1444 :     return nInsPos;
     498             : }
     499             : 
     500           4 : bool SvTreeListBox::ExpandingHdl()
     501             : {
     502           4 :     return !aExpandingHdl.IsSet() || aExpandingHdl.Call( this );
     503             : }
     504             : 
     505           4 : void SvTreeListBox::ExpandedHdl()
     506             : {
     507           4 :     aExpandedHdl.Call( this );
     508           4 : }
     509             : 
     510         125 : void SvTreeListBox::SelectHdl()
     511             : {
     512         125 :     aSelectHdl.Call( this );
     513         125 : }
     514             : 
     515           2 : void SvTreeListBox::DeselectHdl()
     516             : {
     517           2 :     aDeselectHdl.Call( this );
     518           2 : }
     519             : 
     520           0 : bool SvTreeListBox::DoubleClickHdl()
     521             : {
     522           0 :     aDoubleClickHdl.Call( this );
     523           0 :     return true;
     524             : }
     525             : 
     526             : 
     527           0 : bool SvTreeListBox::CheckDragAndDropMode( SvTreeListBox* pSource, sal_Int8 nAction )
     528             : {
     529           0 :     if ( pSource == this )
     530             :     {
     531           0 :         if ( !(nDragDropMode & (SV_DRAGDROP_CTRL_MOVE | SV_DRAGDROP_CTRL_COPY) ) )
     532           0 :             return false; // D&D locked within list
     533           0 :         if( DND_ACTION_MOVE == nAction )
     534             :         {
     535           0 :             if ( !(nDragDropMode & SV_DRAGDROP_CTRL_MOVE) )
     536           0 :                  return false; // no local move
     537             :         }
     538             :         else
     539             :         {
     540           0 :             if ( !(nDragDropMode & SV_DRAGDROP_CTRL_COPY))
     541           0 :                 return false; // no local copy
     542             :         }
     543             :     }
     544             :     else
     545             :     {
     546           0 :         if ( !(nDragDropMode & SV_DRAGDROP_APP_DROP ) )
     547           0 :             return false; // no drop
     548           0 :         if ( DND_ACTION_MOVE == nAction )
     549             :         {
     550           0 :             if ( !(nDragDropMode & SV_DRAGDROP_APP_MOVE) )
     551           0 :                 return false; // no global move
     552             :         }
     553             :         else
     554             :         {
     555           0 :             if ( !(nDragDropMode & SV_DRAGDROP_APP_COPY))
     556           0 :                 return false; // no global copy
     557             :         }
     558             :     }
     559           0 :     return true;
     560             : }
     561             : 
     562             : 
     563             : 
     564             : 
     565           0 : void SvTreeListBox::NotifyRemoving( SvTreeListEntry* )
     566             : {
     567           0 : }
     568             : 
     569             : /*
     570             :     NotifyMoving/Copying
     571             :     ====================
     572             : 
     573             :     default behavior:
     574             : 
     575             :     1. target doesn't have children
     576             :         - entry becomes sibling of target. entry comes after target
     577             :           (->Window: below the target)
     578             :     2. target is an expanded parent
     579             :         - entry inserted at the beginning of the target childlist
     580             :     3. target is a collapsed parent
     581             :         - entry is inserted at the end of the target childlist
     582             : */
     583             : #ifdef DBG_UTIL
     584             : TriState SvTreeListBox::NotifyMoving(
     585             :     SvTreeListEntry*  pTarget,       // D&D dropping position in this->GetModel()
     586             :     SvTreeListEntry*  pEntry,        // entry that we want to move, from
     587             :                                  // GetSourceListBox()->GetModel()
     588             :     SvTreeListEntry*& rpNewParent,   // new target parent
     589             :     sal_uLong&        rNewChildPos)  // position in childlist of target parent
     590             : #else
     591           0 : TriState SvTreeListBox::NotifyMoving(
     592             :     SvTreeListEntry*  pTarget,       // D&D dropping position in this->GetModel()
     593             :     SvTreeListEntry*,                // entry that we want to move, from
     594             :                                  // GetSourceListBox()->GetModel()
     595             :     SvTreeListEntry*& rpNewParent,   // new target parent
     596             :     sal_uLong&        rNewChildPos)  // position in childlist of target parent
     597             : #endif
     598             : {
     599             :     DBG_ASSERT(pEntry,"NotifyMoving:SoureEntry?");
     600           0 :     if( !pTarget )
     601             :     {
     602           0 :         rpNewParent = 0;
     603           0 :         rNewChildPos = 0;
     604           0 :         return TRISTATE_TRUE;
     605             :     }
     606           0 :     if ( !pTarget->HasChildren() && !pTarget->HasChildrenOnDemand() )
     607             :     {
     608             :         // case 1
     609           0 :         rpNewParent = GetParent( pTarget );
     610           0 :         rNewChildPos = pModel->GetRelPos( pTarget ) + 1;
     611           0 :         rNewChildPos += nCurEntrySelPos;
     612           0 :         nCurEntrySelPos++;
     613             :     }
     614             :     else
     615             :     {
     616             :         // cases 2 & 3
     617           0 :         rpNewParent = pTarget;
     618           0 :         if( IsExpanded(pTarget))
     619           0 :             rNewChildPos = 0;
     620             :         else
     621           0 :             rNewChildPos = TREELIST_APPEND;
     622             :     }
     623           0 :     return TRISTATE_TRUE;
     624             : }
     625             : 
     626           0 : TriState SvTreeListBox::NotifyCopying(
     627             :     SvTreeListEntry*  pTarget,       // D&D dropping position in this->GetModel()
     628             :     SvTreeListEntry*  pEntry,        // entry that we want to move, from
     629             :                                  // GetSourceListBox()->GetModel()
     630             :     SvTreeListEntry*& rpNewParent,   // new target parent
     631             :     sal_uLong&        rNewChildPos)  // position in childlist of target parent
     632             : {
     633           0 :     return NotifyMoving(pTarget,pEntry,rpNewParent,rNewChildPos);
     634             : }
     635             : 
     636         302 : SvTreeListEntry* SvTreeListBox::FirstChild( SvTreeListEntry* pParent ) const
     637             : {
     638         302 :     return pModel->FirstChild(pParent);
     639             : }
     640             : 
     641          62 : SvTreeListEntry* SvTreeListBox::NextSibling( SvTreeListEntry* pEntry ) const
     642             : {
     643          62 :     return pModel->NextSibling(pEntry);
     644             : }
     645             : 
     646           0 : SvTreeListEntry* SvTreeListBox::PrevSibling( SvTreeListEntry* pEntry ) const
     647             : {
     648           0 :     return pModel->PrevSibling(pEntry);
     649             : }
     650             : 
     651             : // return: all entries copied
     652           0 : bool SvTreeListBox::CopySelection( SvTreeListBox* pSource, SvTreeListEntry* pTarget )
     653             : {
     654           0 :     nCurEntrySelPos = 0; // selection counter for NotifyMoving/Copying
     655           0 :     bool bSuccess = true;
     656           0 :     std::vector<SvTreeListEntry*> aList;
     657           0 :     bool bClone = ( pSource->GetModel() != GetModel() );
     658           0 :     Link aCloneLink( pModel->GetCloneLink() );
     659           0 :     pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
     660             : 
     661             :     // cache selection to simplify iterating over the selection when doing a D&D
     662             :     // exchange within the same listbox
     663           0 :     SvTreeListEntry* pSourceEntry = pSource->FirstSelected();
     664           0 :     while ( pSourceEntry )
     665             :     {
     666             :         // children are copied automatically
     667           0 :         pSource->SelectChildren( pSourceEntry, false );
     668           0 :         aList.push_back( pSourceEntry );
     669           0 :         pSourceEntry = pSource->NextSelected( pSourceEntry );
     670             :     }
     671             : 
     672           0 :     std::vector<SvTreeListEntry*>::const_iterator it = aList.begin(), itEnd = aList.end();
     673           0 :     for (; it != itEnd; ++it)
     674             :     {
     675           0 :         pSourceEntry = *it;
     676           0 :         SvTreeListEntry* pNewParent = 0;
     677           0 :         sal_uLong nInsertionPos = TREELIST_APPEND;
     678           0 :         TriState nOk = NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos);
     679           0 :         if ( nOk )
     680             :         {
     681           0 :             if ( bClone )
     682             :             {
     683           0 :                 sal_uLong nCloneCount = 0;
     684           0 :                 pSourceEntry = pModel->Clone(pSourceEntry, nCloneCount);
     685           0 :                 pModel->InsertTree(pSourceEntry, pNewParent, nInsertionPos);
     686             :             }
     687             :             else
     688             :             {
     689           0 :                 sal_uLong nListPos = pModel->Copy(pSourceEntry, pNewParent, nInsertionPos);
     690           0 :                 pSourceEntry = GetEntry( pNewParent, nListPos );
     691             :             }
     692             :         }
     693             :         else
     694           0 :             bSuccess = false;
     695             : 
     696           0 :         if (nOk == TRISTATE_INDET)  // HACK: make visible moved entry
     697           0 :             MakeVisible( pSourceEntry );
     698             :     }
     699           0 :     pModel->SetCloneLink( aCloneLink );
     700           0 :     return bSuccess;
     701             : }
     702             : 
     703             : // return: all entries were moved
     704           0 : bool SvTreeListBox::MoveSelection( SvTreeListBox* pSource, SvTreeListEntry* pTarget )
     705             : {
     706           0 :     return MoveSelectionCopyFallbackPossible( pSource, pTarget, false );
     707             : }
     708             : 
     709           0 : bool SvTreeListBox::MoveSelectionCopyFallbackPossible( SvTreeListBox* pSource, SvTreeListEntry* pTarget, bool bAllowCopyFallback )
     710             : {
     711           0 :     nCurEntrySelPos = 0; // selection counter for NotifyMoving/Copying
     712           0 :     bool bSuccess = true;
     713           0 :     std::vector<SvTreeListEntry*> aList;
     714           0 :     bool bClone = ( pSource->GetModel() != GetModel() );
     715           0 :     Link aCloneLink( pModel->GetCloneLink() );
     716           0 :     if ( bClone )
     717           0 :         pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
     718             : 
     719           0 :     SvTreeListEntry* pSourceEntry = pSource->FirstSelected();
     720           0 :     while ( pSourceEntry )
     721             :     {
     722             :         // children are automatically moved
     723           0 :         pSource->SelectChildren( pSourceEntry, false );
     724           0 :         aList.push_back( pSourceEntry );
     725           0 :         pSourceEntry = pSource->NextSelected( pSourceEntry );
     726             :     }
     727             : 
     728           0 :     std::vector<SvTreeListEntry*>::const_iterator it = aList.begin(), itEnd = aList.end();
     729           0 :     for (; it != itEnd; ++it)
     730             :     {
     731           0 :         pSourceEntry = *it;
     732             : 
     733           0 :         SvTreeListEntry* pNewParent = 0;
     734           0 :         sal_uLong nInsertionPos = TREELIST_APPEND;
     735           0 :         TriState nOk = NotifyMoving(pTarget,pSourceEntry,pNewParent,nInsertionPos);
     736           0 :         TriState nCopyOk = nOk;
     737           0 :         if ( !nOk && bAllowCopyFallback )
     738             :         {
     739           0 :             nInsertionPos = TREELIST_APPEND;
     740           0 :             nCopyOk = NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos);
     741             :         }
     742             : 
     743           0 :         if ( nOk || nCopyOk )
     744             :         {
     745           0 :             if ( bClone )
     746             :             {
     747           0 :                 sal_uLong nCloneCount = 0;
     748           0 :                 pSourceEntry = pModel->Clone(pSourceEntry, nCloneCount);
     749           0 :                 pModel->InsertTree(pSourceEntry, pNewParent, nInsertionPos);
     750             :             }
     751             :             else
     752             :             {
     753           0 :                 if ( nOk )
     754           0 :                     pModel->Move(pSourceEntry, pNewParent, nInsertionPos);
     755             :                 else
     756           0 :                     pModel->Copy(pSourceEntry, pNewParent, nInsertionPos);
     757           0 :             }
     758             :         }
     759             :         else
     760           0 :             bSuccess = false;
     761             : 
     762           0 :         if (nOk == TRISTATE_INDET)  // HACK: make moved entry visible
     763           0 :             MakeVisible( pSourceEntry );
     764             :     }
     765           0 :     pModel->SetCloneLink( aCloneLink );
     766           0 :     return bSuccess;
     767             : }
     768             : 
     769           0 : void SvTreeListBox::RemoveSelection()
     770             : {
     771           0 :     std::vector<const SvTreeListEntry*> aList;
     772             :     // cache selection, as the implementation deselects everything on the first
     773             :     // remove
     774           0 :     SvTreeListEntry* pEntry = FirstSelected();
     775           0 :     while ( pEntry )
     776             :     {
     777           0 :         aList.push_back( pEntry );
     778           0 :         if ( pEntry->HasChildren() )
     779             :             // remove deletes all children automatically
     780           0 :             SelectChildren(pEntry, false);
     781           0 :         pEntry = NextSelected( pEntry );
     782             :     }
     783             : 
     784           0 :     std::vector<const SvTreeListEntry*>::const_iterator it = aList.begin(), itEnd = aList.end();
     785           0 :     for (; it != itEnd; ++it)
     786           0 :         pModel->Remove(*it);
     787           0 : }
     788             : 
     789           0 : SvTreeListBox* SvTreeListBox::GetSourceView() const
     790             : {
     791           0 :     return pDDSource;
     792             : }
     793             : 
     794         958 : void SvTreeListBox::RecalcViewData()
     795             : {
     796         958 :     SvTreeListEntry* pEntry = First();
     797        1980 :     while( pEntry )
     798             :     {
     799          64 :         sal_uInt16 nCount = pEntry->ItemCount();
     800          64 :         sal_uInt16 nCurPos = 0;
     801         256 :         while ( nCurPos < nCount )
     802             :         {
     803         128 :             SvLBoxItem* pItem = pEntry->GetItem( nCurPos );
     804         128 :             pItem->InitViewData( this, pEntry );
     805         128 :             nCurPos++;
     806             :         }
     807          64 :         ViewDataInitialized( pEntry );
     808          64 :         pEntry = Next( pEntry );
     809             :     }
     810         958 : }
     811             : 
     812          64 : void SvTreeListBox::ViewDataInitialized( SvTreeListEntry* )
     813             : {
     814          64 : }
     815             : 
     816           0 : void SvTreeListBox::ImplShowTargetEmphasis( SvTreeListEntry* pEntry, bool bShow)
     817             : {
     818           0 :     if ( bShow && (nImpFlags & SVLBOX_TARGEMPH_VIS) )
     819           0 :         return;
     820           0 :     if ( !bShow && !(nImpFlags & SVLBOX_TARGEMPH_VIS) )
     821           0 :         return;
     822           0 :     ShowTargetEmphasis( pEntry, bShow );
     823           0 :     if( bShow )
     824           0 :         nImpFlags |= SVLBOX_TARGEMPH_VIS;
     825             :     else
     826           0 :         nImpFlags &= ~SVLBOX_TARGEMPH_VIS;
     827             : }
     828             : 
     829         125 : void SvTreeListBox::OnCurrentEntryChanged()
     830             : {
     831         125 :     if ( !mpImpl->m_bDoingQuickSelection )
     832         125 :         mpImpl->m_aQuickSelectionEngine.Reset();
     833         125 : }
     834             : 
     835         816 : SvTreeListEntry* SvTreeListBox::GetEntry( SvTreeListEntry* pParent, sal_uLong nPos ) const
     836             : {
     837         816 :     return pModel->GetEntry(pParent, nPos);
     838             : }
     839             : 
     840         258 : SvTreeListEntry* SvTreeListBox::GetEntry( sal_uLong nRootPos ) const
     841             : {
     842         258 :     return pModel->GetEntry(nRootPos);
     843             : }
     844             : 
     845         216 : SvTreeListEntry* SvTreeListBox::GetEntryFromPath( const ::std::deque< sal_Int32 >& _rPath ) const
     846             : {
     847             : 
     848         216 :     SvTreeListEntry* pEntry = NULL;
     849         216 :     SvTreeListEntry* pParent = NULL;
     850         432 :     for( ::std::deque< sal_Int32 >::const_iterator pItem = _rPath.begin(); pItem != _rPath.end(); ++pItem )
     851             :     {
     852         216 :         pEntry = GetEntry( pParent, *pItem );
     853         216 :         if ( !pEntry )
     854           0 :             break;
     855         216 :         pParent = pEntry;
     856             :     }
     857             : 
     858         216 :     return pEntry;
     859             : }
     860             : 
     861          72 : void SvTreeListBox::FillEntryPath( SvTreeListEntry* pEntry, ::std::deque< sal_Int32 >& _rPath ) const
     862             : {
     863             : 
     864          72 :     if ( pEntry )
     865             :     {
     866          72 :         SvTreeListEntry* pParentEntry = GetParent( pEntry );
     867             :         while ( true )
     868             :         {
     869          72 :             sal_uLong i, nCount = GetLevelChildCount( pParentEntry );
     870         468 :             for ( i = 0; i < nCount; ++i )
     871             :             {
     872         468 :                 SvTreeListEntry* pTemp = GetEntry( pParentEntry, i );
     873             :                 DBG_ASSERT( pEntry, "invalid entry" );
     874         468 :                 if ( pEntry == pTemp )
     875             :                 {
     876          72 :                     _rPath.push_front( (sal_Int32)i );
     877          72 :                     break;
     878             :                 }
     879             :             }
     880             : 
     881          72 :             if ( pParentEntry )
     882             :             {
     883           0 :                 pEntry = pParentEntry;
     884           0 :                 pParentEntry = GetParent( pParentEntry );
     885             :             }
     886             :             else
     887          72 :                 break;
     888           0 :         }
     889             :     }
     890          72 : }
     891             : 
     892           0 : const SvTreeListEntry* SvTreeListBox::GetParent( const SvTreeListEntry* pEntry ) const
     893             : {
     894           0 :     return pModel->GetParent(pEntry);
     895             : }
     896             : 
     897         659 : SvTreeListEntry* SvTreeListBox::GetParent( SvTreeListEntry* pEntry ) const
     898             : {
     899         659 :     return pModel->GetParent(pEntry);
     900             : }
     901             : 
     902          12 : SvTreeListEntry* SvTreeListBox::GetRootLevelParent( SvTreeListEntry* pEntry ) const
     903             : {
     904          12 :     return pModel->GetRootLevelParent(pEntry);
     905             : }
     906             : 
     907         186 : sal_uLong SvTreeListBox::GetChildCount( SvTreeListEntry* pParent ) const
     908             : {
     909         186 :     return pModel->GetChildCount(pParent);
     910             : }
     911             : 
     912         228 : sal_uLong SvTreeListBox::GetLevelChildCount( SvTreeListEntry* _pParent ) const
     913             : {
     914             : 
     915             :     //if _pParent is 0, then pEntry is the first child of the root.
     916         228 :     SvTreeListEntry* pEntry = FirstChild( _pParent );
     917             : 
     918         228 :     if( !pEntry )//there is only root, root don't have children
     919         144 :         return 0;
     920             : 
     921          84 :     if( !_pParent )//root and children of root
     922          84 :         return pEntry->pParent->maChildren.size();
     923             : 
     924           0 :     return _pParent->maChildren.size();
     925             : }
     926             : 
     927        3438 : SvViewDataEntry* SvTreeListBox::GetViewDataEntry( SvTreeListEntry* pEntry ) const
     928             : {
     929        3438 :     return (SvViewDataEntry*)SvListView::GetViewData(pEntry);
     930             : }
     931             : 
     932         210 : SvViewDataItem* SvTreeListBox::GetViewDataItem(SvTreeListEntry* pEntry, SvLBoxItem* pItem)
     933             : {
     934         210 :     return const_cast<SvViewDataItem*>(static_cast<const SvTreeListBox*>(this)->GetViewDataItem(pEntry, pItem));
     935             : }
     936             : 
     937        4380 : const SvViewDataItem* SvTreeListBox::GetViewDataItem(const SvTreeListEntry* pEntry, const SvLBoxItem* pItem) const
     938             : {
     939        4380 :     const SvViewDataEntry* pEntryData = (const SvViewDataEntry*)SvListView::GetViewData(pEntry);
     940             :     DBG_ASSERT(pEntryData,"Entry not in View");
     941        4380 :     sal_uInt16 nItemPos = pEntry->GetPos(pItem);
     942        4380 :     return pEntryData->GetItem(nItemPos);
     943             : }
     944             : 
     945        1450 : SvViewDataEntry* SvTreeListBox::CreateViewData( SvTreeListEntry* )
     946             : {
     947        1450 :     SvViewDataEntry* pEntryData = new SvViewDataEntry;
     948        1450 :     return (SvViewDataEntry*)pEntryData;
     949             : }
     950             : 
     951        1450 : void SvTreeListBox::InitViewData( SvViewDataEntry* pData, SvTreeListEntry* pEntry )
     952             : {
     953        1450 :     SvTreeListEntry* pInhEntry = (SvTreeListEntry*)pEntry;
     954        1450 :     SvViewDataEntry* pEntryData = (SvViewDataEntry*)pData;
     955             : 
     956        1450 :     pEntryData->Init(pInhEntry->ItemCount());
     957        1450 :     sal_uInt16 nCount = pInhEntry->ItemCount();
     958        1450 :     sal_uInt16 nCurPos = 0;
     959        5800 :     while( nCurPos < nCount )
     960             :     {
     961        2900 :         SvLBoxItem* pItem = pInhEntry->GetItem( nCurPos );
     962        2900 :         SvViewDataItem* pItemData = pEntryData->GetItem(nCurPos);
     963        2900 :         pItem->InitViewData( this, pInhEntry, pItemData );
     964        2900 :         pItemData++;
     965        2900 :         nCurPos++;
     966             :     }
     967        1450 : }
     968             : 
     969             : 
     970             : 
     971           0 : void SvTreeListBox::EnableSelectionAsDropTarget( bool bEnable, bool bWithChildren )
     972             : {
     973             :     sal_uInt16 nRefDepth;
     974             :     SvTreeListEntry* pTemp;
     975             : 
     976           0 :     SvTreeListEntry* pSelEntry = FirstSelected();
     977           0 :     while( pSelEntry )
     978             :     {
     979           0 :         if ( !bEnable )
     980             :         {
     981           0 :             pSelEntry->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP;
     982           0 :             if ( bWithChildren )
     983             :             {
     984           0 :                 nRefDepth = pModel->GetDepth( pSelEntry );
     985           0 :                 pTemp = Next( pSelEntry );
     986           0 :                 while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth )
     987             :                 {
     988           0 :                     pTemp->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP;
     989           0 :                     pTemp = Next( pTemp );
     990             :                 }
     991             :             }
     992             :         }
     993             :         else
     994             :         {
     995           0 :             pSelEntry->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP);
     996           0 :             if ( bWithChildren )
     997             :             {
     998           0 :                 nRefDepth = pModel->GetDepth( pSelEntry );
     999           0 :                 pTemp = Next( pSelEntry );
    1000           0 :                 while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth )
    1001             :                 {
    1002           0 :                     pTemp->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP);
    1003           0 :                     pTemp = Next( pTemp );
    1004             :                 }
    1005             :             }
    1006             :         }
    1007           0 :         pSelEntry = NextSelected( pSelEntry );
    1008             :     }
    1009           0 : }
    1010             : 
    1011             : // ******************************************************************
    1012             : // InplaceEditing
    1013             : // ******************************************************************
    1014             : 
    1015           0 : void SvTreeListBox::EditText( const OUString& rStr, const Rectangle& rRect,
    1016             :     const Selection& rSel )
    1017             : {
    1018           0 :     EditText( rStr, rRect, rSel, false );
    1019           0 : }
    1020             : 
    1021           0 : void SvTreeListBox::EditText( const OUString& rStr, const Rectangle& rRect,
    1022             :     const Selection& rSel, bool bMulti )
    1023             : {
    1024           0 :     if( pEdCtrl )
    1025           0 :         delete pEdCtrl;
    1026           0 :     nImpFlags |= SVLBOX_IN_EDT;
    1027           0 :     nImpFlags &= ~SVLBOX_EDTEND_CALLED;
    1028           0 :     HideFocus();
    1029             :     pEdCtrl = new SvInplaceEdit2(
    1030             :         this, rRect.TopLeft(), rRect.GetSize(), rStr,
    1031             :         LINK( this, SvTreeListBox, TextEditEndedHdl_Impl ),
    1032           0 :         rSel, bMulti );
    1033           0 : }
    1034             : 
    1035           0 : IMPL_LINK_NOARG(SvTreeListBox, TextEditEndedHdl_Impl)
    1036             : {
    1037           0 :     if ( nImpFlags & SVLBOX_EDTEND_CALLED ) // avoid nesting
    1038           0 :         return 0;
    1039           0 :     nImpFlags |= SVLBOX_EDTEND_CALLED;
    1040           0 :     OUString aStr;
    1041           0 :     if ( !pEdCtrl->EditingCanceled() )
    1042           0 :         aStr = pEdCtrl->GetText();
    1043             :     else
    1044           0 :         aStr = pEdCtrl->GetSavedValue();
    1045           0 :     if ( IsEmptyTextAllowed() || !aStr.isEmpty() )
    1046           0 :         EditedText( aStr );
    1047             :     // Hide may only be called after the new text was put into the entry, so
    1048             :     // that we don't call the selection handler in the GetFocus of the listbox
    1049             :     // with the old entry text.
    1050           0 :     pEdCtrl->Hide();
    1051             :     // delete pEdCtrl;
    1052             :     // pEdCtrl = 0;
    1053           0 :     nImpFlags &= (~SVLBOX_IN_EDT);
    1054           0 :     GrabFocus();
    1055           0 :     return 0;
    1056             : }
    1057             : 
    1058         622 : void SvTreeListBox::CancelTextEditing()
    1059             : {
    1060         622 :     if ( pEdCtrl )
    1061           0 :         pEdCtrl->StopEditing( true );
    1062         622 :     nImpFlags &= (~SVLBOX_IN_EDT);
    1063         622 : }
    1064             : 
    1065           0 : void SvTreeListBox::EndEditing( bool bCancel )
    1066             : {
    1067           0 :     if( pEdCtrl )
    1068           0 :         pEdCtrl->StopEditing( bCancel );
    1069           0 :     nImpFlags &= (~SVLBOX_IN_EDT);
    1070           0 : }
    1071             : 
    1072             : 
    1073           0 : bool SvTreeListBox::IsEmptyTextAllowed() const
    1074             : {
    1075           0 :     return mpImpl->m_bIsEmptyTextAllowed;
    1076             : }
    1077             : 
    1078           0 : void SvTreeListBox::ForbidEmptyText()
    1079             : {
    1080           0 :     mpImpl->m_bIsEmptyTextAllowed = false;
    1081           0 : }
    1082             : 
    1083        1450 : SvTreeListEntry* SvTreeListBox::CreateEntry() const
    1084             : {
    1085        1450 :     return new SvTreeListEntry;
    1086             : }
    1087             : 
    1088           0 : const void* SvTreeListBox::FirstSearchEntry( OUString& _rEntryText ) const
    1089             : {
    1090           0 :     SvTreeListEntry* pEntry = GetCurEntry();
    1091           0 :     if ( pEntry )
    1092           0 :         pEntry = const_cast< SvTreeListEntry* >( static_cast< const SvTreeListEntry* >( NextSearchEntry( pEntry, _rEntryText ) ) );
    1093             :     else
    1094             :     {
    1095           0 :         pEntry = FirstSelected();
    1096           0 :         if ( !pEntry )
    1097           0 :             pEntry = First();
    1098             :     }
    1099             : 
    1100           0 :     if ( pEntry )
    1101           0 :         _rEntryText = GetEntryText( pEntry );
    1102             : 
    1103           0 :     return pEntry;
    1104             : }
    1105             : 
    1106           0 : const void* SvTreeListBox::NextSearchEntry( const void* _pCurrentSearchEntry, OUString& _rEntryText ) const
    1107             : {
    1108           0 :     SvTreeListEntry* pEntry = const_cast< SvTreeListEntry* >( static_cast< const SvTreeListEntry* >( _pCurrentSearchEntry ) );
    1109             : 
    1110           0 :     if  (   (   ( GetChildCount( pEntry ) > 0 )
    1111           0 :             ||  ( pEntry->HasChildrenOnDemand() )
    1112             :             )
    1113           0 :         &&  !IsExpanded( pEntry )
    1114             :         )
    1115             :     {
    1116           0 :         pEntry = NextSibling( pEntry );
    1117             :     }
    1118             :     else
    1119             :     {
    1120           0 :         pEntry = Next( pEntry );
    1121             :     }
    1122             : 
    1123           0 :     if ( !pEntry )
    1124           0 :         pEntry = First();
    1125             : 
    1126           0 :     if ( pEntry )
    1127           0 :         _rEntryText = GetEntryText( pEntry );
    1128             : 
    1129           0 :     return pEntry;
    1130             : }
    1131             : 
    1132           0 : void SvTreeListBox::SelectSearchEntry( const void* _pEntry )
    1133             : {
    1134           0 :     SvTreeListEntry* pEntry = const_cast< SvTreeListEntry* >( static_cast< const SvTreeListEntry* >( _pEntry ) );
    1135             :     DBG_ASSERT( pEntry, "SvTreeListBox::SelectSearchEntry: invalid entry!" );
    1136           0 :     if ( !pEntry )
    1137           0 :         return;
    1138             : 
    1139           0 :     SelectAll( false );
    1140           0 :     SetCurEntry( pEntry );
    1141           0 :     Select( pEntry );
    1142             : }
    1143             : 
    1144           0 : void SvTreeListBox::ExecuteSearchEntry( const void* /*_pEntry*/ ) const
    1145             : {
    1146             :     // nothing to do here, we have no "execution"
    1147           0 : }
    1148             : 
    1149           0 : ::vcl::StringEntryIdentifier SvTreeListBox::CurrentEntry( OUString& _out_entryText ) const
    1150             : {
    1151             :     // always accept the current entry if there is one
    1152           0 :     SvTreeListEntry* pCurrentEntry( GetCurEntry() );
    1153           0 :     if ( pCurrentEntry )
    1154             :     {
    1155           0 :         _out_entryText = GetEntryText( pCurrentEntry );
    1156           0 :         return pCurrentEntry;
    1157             :     }
    1158           0 :     return FirstSearchEntry( _out_entryText );
    1159             : }
    1160             : 
    1161           0 : ::vcl::StringEntryIdentifier SvTreeListBox::NextEntry( ::vcl::StringEntryIdentifier _currentEntry, OUString& _out_entryText ) const
    1162             : {
    1163           0 :     return NextSearchEntry( _currentEntry, _out_entryText );
    1164             : }
    1165             : 
    1166           0 : void SvTreeListBox::SelectEntry( ::vcl::StringEntryIdentifier _entry )
    1167             : {
    1168           0 :     SelectSearchEntry( _entry );
    1169           0 : }
    1170             : 
    1171           0 : bool SvTreeListBox::HandleKeyInput( const KeyEvent& _rKEvt )
    1172             : {
    1173           0 :     if  (   IsEntryMnemonicsEnabled()
    1174           0 :         &&  mpImpl->m_aMnemonicEngine.HandleKeyEvent( _rKEvt )
    1175             :         )
    1176           0 :         return true;
    1177             : 
    1178           0 :     if ( ( GetStyle() & WB_QUICK_SEARCH ) != 0 )
    1179             :     {
    1180           0 :         mpImpl->m_bDoingQuickSelection = true;
    1181           0 :         const bool bHandled = mpImpl->m_aQuickSelectionEngine.HandleKeyEvent( _rKEvt );
    1182           0 :         mpImpl->m_bDoingQuickSelection = false;
    1183           0 :         if ( bHandled )
    1184           0 :             return true;
    1185             :     }
    1186             : 
    1187           0 :     return false;
    1188             : }
    1189             : 
    1190           0 : void SvTreeListBox::WriteDragServerInfo( const Point&, SvLBoxDDInfo* )
    1191             : {
    1192           0 : }
    1193             : 
    1194           0 : void SvTreeListBox::ReadDragServerInfo(const Point&, SvLBoxDDInfo* )
    1195             : {
    1196           0 : }
    1197             : 
    1198           0 : bool SvTreeListBox::EditingCanceled() const
    1199             : {
    1200           0 :     if( pEdCtrl && pEdCtrl->EditingCanceled() )
    1201           0 :         return true;
    1202           0 :     return false;
    1203             : }
    1204             : 
    1205             : 
    1206             : //JP 28.3.2001: new Drag & Drop API
    1207           0 : sal_Int8 SvTreeListBox::AcceptDrop( const AcceptDropEvent& rEvt )
    1208             : {
    1209           0 :     sal_Int8 nRet = DND_ACTION_NONE;
    1210             : 
    1211           0 :     if( rEvt.mbLeaving || !CheckDragAndDropMode( pDDSource, rEvt.mnAction ) )
    1212             :     {
    1213           0 :         ImplShowTargetEmphasis( pTargetEntry, false );
    1214             :     }
    1215           0 :     else if( !nDragDropMode )
    1216             :     {
    1217             :         SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no target" );
    1218             :     }
    1219             :     else
    1220             :     {
    1221           0 :         SvTreeListEntry* pEntry = GetDropTarget( rEvt.maPosPixel );
    1222           0 :         if( !IsDropFormatSupported( SOT_FORMATSTR_ID_TREELISTBOX ) )
    1223             :         {
    1224             :             SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no format" );
    1225             :         }
    1226             :         else
    1227             :         {
    1228             :             DBG_ASSERT( pDDSource, "SvTreeListBox::QueryDrop(): SourceBox == 0" );
    1229           0 :             if( !( pEntry && pDDSource->GetModel() == this->GetModel()
    1230           0 :                     && DND_ACTION_MOVE == rEvt.mnAction
    1231           0 :                     && ( pEntry->nEntryFlags & SV_ENTRYFLAG_DISABLE_DROP ) ))
    1232             :             {
    1233           0 :                 if( NotifyAcceptDrop( pEntry ))
    1234           0 :                     nRet = rEvt.mnAction;
    1235             :             }
    1236             :         }
    1237             : 
    1238             :         // **** draw emphasis ****
    1239           0 :         if( DND_ACTION_NONE == nRet )
    1240           0 :                ImplShowTargetEmphasis( pTargetEntry, false );
    1241           0 :         else if( pEntry != pTargetEntry || !(nImpFlags & SVLBOX_TARGEMPH_VIS) )
    1242             :         {
    1243           0 :             ImplShowTargetEmphasis( pTargetEntry, false );
    1244           0 :             pTargetEntry = pEntry;
    1245           0 :             ImplShowTargetEmphasis( pTargetEntry, true );
    1246             :         }
    1247             :     }
    1248           0 :     return nRet;
    1249             : }
    1250             : 
    1251           0 : sal_Int8 SvTreeListBox::ExecuteDrop( const ExecuteDropEvent& rEvt, SvTreeListBox* pSourceView )
    1252             : {
    1253           0 :     sal_Int8 nRet = DND_ACTION_NONE;
    1254             : 
    1255             :     DBG_ASSERT( pSourceView, "SvTreeListBox::ExecuteDrop(): no source view" );
    1256           0 :     pSourceView->EnableSelectionAsDropTarget( true, true );
    1257             : 
    1258           0 :     ImplShowTargetEmphasis( pTargetEntry, false );
    1259           0 :     pDDTarget = this;
    1260             : 
    1261             :     SvLBoxDDInfo aDDInfo;
    1262             : 
    1263           0 :     TransferableDataHelper aData( rEvt.maDropEvent.Transferable );
    1264           0 :     if( aData.HasFormat( SOT_FORMATSTR_ID_TREELISTBOX ))
    1265             :     {
    1266           0 :         css::uno::Sequence<sal_Int8> aSeq = aData.GetSequence(SOT_FORMATSTR_ID_TREELISTBOX, OUString());
    1267           0 :         if (sizeof(SvLBoxDDInfo) == aSeq.getLength())
    1268             :         {
    1269           0 :             memcpy( &aDDInfo, aSeq.getConstArray(), sizeof(SvLBoxDDInfo) );
    1270           0 :             nRet = rEvt.mnAction;
    1271           0 :         }
    1272             :     }
    1273             : 
    1274           0 :     if( DND_ACTION_NONE != nRet )
    1275             :     {
    1276           0 :         nRet = DND_ACTION_NONE;
    1277             : 
    1278           0 :         ReadDragServerInfo( rEvt.maPosPixel, &aDDInfo );
    1279             : 
    1280           0 :         SvTreeListEntry* pTarget = pTargetEntry; // may be 0!
    1281             : 
    1282           0 :         if( DND_ACTION_COPY == rEvt.mnAction )
    1283             :         {
    1284           0 :             if ( CopySelection( aDDInfo.pSource, pTarget ) )
    1285           0 :                 nRet = rEvt.mnAction;
    1286             :         }
    1287           0 :         else if( DND_ACTION_MOVE == rEvt.mnAction )
    1288             :         {
    1289           0 :             if ( MoveSelection( aDDInfo.pSource, pTarget ) )
    1290           0 :                 nRet = rEvt.mnAction;
    1291             :         }
    1292           0 :         else if( DND_ACTION_COPYMOVE == rEvt.mnAction )
    1293             :         {
    1294           0 :             if ( MoveSelectionCopyFallbackPossible( aDDInfo.pSource, pTarget, true ) )
    1295           0 :                 nRet = rEvt.mnAction;
    1296             :         }
    1297             :     }
    1298           0 :     return nRet;
    1299             : }
    1300             : 
    1301           0 : sal_Int8 SvTreeListBox::ExecuteDrop( const ExecuteDropEvent& rEvt )
    1302             : {
    1303           0 :     return ExecuteDrop( rEvt, GetSourceView() );
    1304             : }
    1305             : 
    1306           0 : void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel )
    1307             : {
    1308             : 
    1309           0 :     Point aEventPos( rPosPixel );
    1310           0 :     MouseEvent aMouseEvt( aEventPos, 1, MOUSE_SELECT, MOUSE_LEFT );
    1311           0 :     MouseButtonUp( aMouseEvt );
    1312             : 
    1313           0 :     nOldDragMode = GetDragDropMode();
    1314           0 :     if ( !nOldDragMode )
    1315           0 :         return;
    1316             : 
    1317           0 :     ReleaseMouse();
    1318             : 
    1319           0 :     SvTreeListEntry* pEntry = GetEntry( rPosPixel ); // GetDropTarget( rPos );
    1320           0 :     if( !pEntry )
    1321             :     {
    1322           0 :         DragFinished( DND_ACTION_NONE );
    1323           0 :         return;
    1324             :     }
    1325             : 
    1326           0 :     TransferDataContainer* pContainer = new TransferDataContainer;
    1327             :     ::com::sun::star::uno::Reference<
    1328           0 :         ::com::sun::star::datatransfer::XTransferable > xRef( pContainer );
    1329             : 
    1330           0 :     nDragDropMode = NotifyStartDrag( *pContainer, pEntry );
    1331           0 :     if( !nDragDropMode || 0 == GetSelectionCount() )
    1332             :     {
    1333           0 :         nDragDropMode = nOldDragMode;
    1334           0 :         DragFinished( DND_ACTION_NONE );
    1335           0 :         return;
    1336             :     }
    1337             : 
    1338             :     SvLBoxDDInfo aDDInfo;
    1339           0 :     memset(&aDDInfo,0,sizeof(SvLBoxDDInfo));
    1340           0 :     aDDInfo.pApp = GetpApp();
    1341           0 :     aDDInfo.pSource = this;
    1342           0 :     aDDInfo.pDDStartEntry = pEntry;
    1343             :     // let derived views do their thing
    1344           0 :     WriteDragServerInfo( rPosPixel, &aDDInfo );
    1345             : 
    1346             :     pContainer->CopyAnyData( SOT_FORMATSTR_ID_TREELISTBOX,
    1347           0 :                         (sal_Char*)&aDDInfo, sizeof(SvLBoxDDInfo) );
    1348           0 :     pDDSource = this;
    1349           0 :     pDDTarget = 0;
    1350             : 
    1351           0 :     bool bOldUpdateMode = Control::IsUpdateMode();
    1352           0 :     Control::SetUpdateMode( true );
    1353           0 :     Update();
    1354           0 :     Control::SetUpdateMode( bOldUpdateMode );
    1355             : 
    1356             :     // Disallow using the selection and its children as drop targets.
    1357             :     // Important: If the selection of the SourceListBox is changed in the
    1358             :     // DropHandler, the entries have to be allowed as drop targets again:
    1359             :     // (GetSourceListBox()->EnableSelectionAsDropTarget( true, true );)
    1360           0 :     EnableSelectionAsDropTarget( false, true /* with children */ );
    1361             : 
    1362           0 :     pContainer->StartDrag( this, nDragOptions, GetDragFinishedHdl() );
    1363             : }
    1364             : 
    1365           0 : void SvTreeListBox::DragFinished( sal_Int8
    1366             : #ifndef UNX
    1367             : nAction
    1368             : #endif
    1369             : )
    1370             : {
    1371           0 :     EnableSelectionAsDropTarget( true, true );
    1372             : 
    1373             : #ifndef UNX
    1374             :     if( (nAction == DND_ACTION_MOVE) && ( (pDDTarget &&
    1375             :         ((sal_uLong)(pDDTarget->GetModel())!=(sal_uLong)(this->GetModel()))) ||
    1376             :         !pDDTarget ))
    1377             :     {
    1378             :         RemoveSelection();
    1379             :     }
    1380             : #endif
    1381             : 
    1382           0 :     ImplShowTargetEmphasis( pTargetEntry, false );
    1383           0 :     pDDSource = 0;
    1384           0 :     pDDTarget = 0;
    1385           0 :     pTargetEntry = 0;
    1386           0 :     nDragDropMode = nOldDragMode;
    1387           0 : }
    1388             : 
    1389           0 : DragDropMode SvTreeListBox::NotifyStartDrag( TransferDataContainer&, SvTreeListEntry* )
    1390             : {
    1391           0 :     return (DragDropMode)0xffff;
    1392             : }
    1393             : 
    1394           0 : bool SvTreeListBox::NotifyAcceptDrop( SvTreeListEntry* )
    1395             : {
    1396           0 :     return true;
    1397             : }
    1398             : 
    1399             : // Handler and methods for Drag - finished handler.
    1400             : // The with get GetDragFinishedHdl() get link can set on the
    1401             : // TransferDataContainer. This link is a callback for the DragFinished
    1402             : // call. AddBox method is called from the GetDragFinishedHdl() and the
    1403             : // remove is called in link callback and in the destructor. So it can't
    1404             : // called to a deleted object.
    1405             : 
    1406             : namespace
    1407             : {
    1408             :     struct SortLBoxes : public rtl::Static<std::set<sal_uLong>, SortLBoxes> {};
    1409             : }
    1410             : 
    1411           0 : void SvTreeListBox::AddBoxToDDList_Impl( const SvTreeListBox& rB )
    1412             : {
    1413           0 :     sal_uLong nVal = reinterpret_cast<sal_uLong>(&rB);
    1414           0 :     SortLBoxes::get().insert( nVal );
    1415           0 : }
    1416             : 
    1417         262 : void SvTreeListBox::RemoveBoxFromDDList_Impl( const SvTreeListBox& rB )
    1418             : {
    1419         262 :     sal_uLong nVal = reinterpret_cast<sal_uLong>(&rB);
    1420         262 :     SortLBoxes::get().erase( nVal );
    1421         262 : }
    1422             : 
    1423           0 : IMPL_STATIC_LINK( SvTreeListBox, DragFinishHdl_Impl, sal_Int8*, pAction )
    1424             : {
    1425           0 :     sal_uLong nVal = reinterpret_cast<sal_uLong>(pThis);
    1426           0 :     std::set<sal_uLong> &rSortLBoxes = SortLBoxes::get();
    1427           0 :     std::set<sal_uLong>::const_iterator it = rSortLBoxes.find(nVal);
    1428           0 :     if( it != rSortLBoxes.end() )
    1429             :     {
    1430           0 :         pThis->DragFinished( *pAction );
    1431           0 :         rSortLBoxes.erase( it );
    1432             :     }
    1433           0 :     return 0;
    1434             : }
    1435             : 
    1436           0 : Link SvTreeListBox::GetDragFinishedHdl() const
    1437             : {
    1438           0 :     AddBoxToDDList_Impl( *this );
    1439           0 :     return STATIC_LINK( const_cast<SvTreeListBox*>(this), SvTreeListBox, DragFinishHdl_Impl );
    1440             : }
    1441             : 
    1442             : /*
    1443             :     Bugs/TODO
    1444             : 
    1445             :     - calculate rectangle when editing in-place (bug with some fonts)
    1446             :     - SetSpaceBetweenEntries: offset is not taken into account in SetEntryHeight
    1447             : */
    1448             : 
    1449             : #define TREEFLAG_FIXEDHEIGHT        0x0010
    1450             : 
    1451             : #define SV_LBOX_DEFAULT_INDENT_PIXEL 20
    1452             : 
    1453         266 : void SvTreeListBox::InitTreeView()
    1454             : {
    1455         266 :     pCheckButtonData = NULL;
    1456         266 :     pEdEntry = NULL;
    1457         266 :     pEdItem = NULL;
    1458         266 :     nEntryHeight = 0;
    1459         266 :     pEdCtrl = NULL;
    1460         266 :     nFirstSelTab = 0;
    1461         266 :     nLastSelTab = 0;
    1462         266 :     nFocusWidth = -1;
    1463         266 :     nAllItemAccRoleType = 0;
    1464         266 :     mnCheckboxItemWidth = 0;
    1465             : 
    1466         266 :     Link* pLink = new Link( LINK(this,SvTreeListBox, DefaultCompare) );
    1467         266 :     mpImpl->m_pLink = pLink;
    1468             : 
    1469         266 :     nTreeFlags = TREEFLAG_RECALCTABS;
    1470         266 :     nIndent = SV_LBOX_DEFAULT_INDENT_PIXEL;
    1471         266 :     nEntryHeightOffs = SV_ENTRYHEIGHTOFFS_PIXEL;
    1472         266 :     pImp = new SvImpLBox( this, GetModel(), GetStyle() );
    1473             : 
    1474         266 :     mbContextBmpExpanded = true;
    1475         266 :     nContextBmpWidthMax = 0;
    1476             : 
    1477         266 :     SetFont( GetFont() );
    1478         266 :     AdjustEntryHeightAndRecalc( GetFont() );
    1479             : 
    1480         266 :     SetSpaceBetweenEntries( 0 );
    1481         266 :     SetLineColor();
    1482         266 :     InitSettings( true, true, true );
    1483         266 :     ImplInitStyle();
    1484         266 :     SetTabs();
    1485         266 : }
    1486             : 
    1487           0 : OUString SvTreeListBox::GetEntryAltText( SvTreeListEntry* ) const
    1488             : {
    1489           0 :     return OUString();
    1490             : }
    1491             : 
    1492           0 : OUString SvTreeListBox::GetEntryLongDescription( SvTreeListEntry* ) const
    1493             : {
    1494           0 :     return OUString();
    1495             : }
    1496             : 
    1497           0 : OUString SvTreeListBox::SearchEntryTextWithHeadTitle( SvTreeListEntry* pEntry )
    1498             : {
    1499             :     DBG_ASSERT( pEntry, "SvTreeListBox::SearchEntryText(): no entry" );
    1500           0 :     OUString sRet;
    1501             : 
    1502           0 :     sal_uInt16 nCount = pEntry->ItemCount();
    1503           0 :     sal_uInt16 nCur = 0;
    1504           0 :     sal_uInt16 nHeaderCur = 0;
    1505             :     SvLBoxItem* pItem;
    1506           0 :     while( nCur < nCount )
    1507             :     {
    1508             :         // MT: SV_ITEM_ID_EXTENDRLBOXSTRING / GetExtendText() was in use in IA2 cws, but only used in sc: ScSolverOptionsString. Needed?
    1509           0 :         pItem = pEntry->GetItem( nCur );
    1510           0 :         if ( (pItem->GetType() == SV_ITEM_ID_LBOXSTRING ) &&
    1511           0 :              !static_cast<SvLBoxString*>( pItem )->GetText().isEmpty() )
    1512             :         {
    1513             :             //want the column header
    1514           0 :             if (!headString.isEmpty())
    1515             :             {
    1516           0 :                 sal_Int32 nEnd = headString.indexOf('\t');
    1517           0 :                 if( nEnd == -1 )
    1518             :                 {
    1519           0 :                     if (!sRet.isEmpty())
    1520             :                     {
    1521           0 :                         sRet += ",";
    1522             :                     }
    1523           0 :                     if (!headString.isEmpty())
    1524             :                     {
    1525           0 :                         sRet += headString ;
    1526           0 :                         sRet += ":" ;
    1527             :                     }
    1528             :                 }
    1529             :                 else
    1530             :                 {
    1531           0 :                     OUString  aString=headString.getToken(nHeaderCur, '\t');
    1532           0 :                     if (!sRet.isEmpty())
    1533             :                     {
    1534           0 :                         sRet += ",";
    1535             :                     }
    1536           0 :                     if (!aString.isEmpty())
    1537             :                     {
    1538           0 :                         sRet += aString ;
    1539           0 :                         sRet += ":" ;
    1540             :                     }
    1541           0 :                     nHeaderCur++;
    1542             :                 }
    1543           0 :                 sRet += static_cast<SvLBoxString*>( pItem )->GetText();
    1544             :             }
    1545             :             else
    1546             :             {
    1547           0 :                 sRet += static_cast<SvLBoxString*>( pItem )->GetText();
    1548           0 :                 sRet += ",";
    1549             :             }
    1550             :             //end want to the column header
    1551             :         }
    1552           0 :         nCur++;
    1553             :     }
    1554             : 
    1555           0 :     if (!sRet.isEmpty())
    1556           0 :         sRet = sRet.copy(0, sRet.getLength() - 1);
    1557           0 :     return sRet;
    1558             : }
    1559             : 
    1560         524 : SvTreeListBox::~SvTreeListBox()
    1561             : {
    1562             : 
    1563         262 :     pImp->CallEventListeners( VCLEVENT_OBJECT_DYING );
    1564         262 :     delete pImp;
    1565         262 :     delete mpImpl->m_pLink;
    1566         262 :     ClearTabList();
    1567             : 
    1568         262 :     delete pEdCtrl;
    1569         262 :     pEdCtrl = 0;
    1570         262 :     pModel->RemoveView( this );
    1571         262 :     if ( pModel->GetRefCount() == 0 )
    1572             :     {
    1573         262 :         pModel->Clear();
    1574         262 :         delete pModel;
    1575         262 :         pModel = NULL;
    1576             :     }
    1577             : 
    1578         262 :     SvTreeListBox::RemoveBoxFromDDList_Impl( *this );
    1579             : 
    1580         262 :     if( this == pDDSource )
    1581           0 :         pDDSource = 0;
    1582         262 :     if( this == pDDTarget )
    1583           0 :         pDDTarget = 0;
    1584         262 :     delete mpImpl;
    1585         262 : }
    1586             : 
    1587          16 : void SvTreeListBox::SetExtendedWinBits( ExtendedWinBits _nBits )
    1588             : {
    1589          16 :     pImp->SetExtendedWindowBits( _nBits );
    1590          16 : }
    1591             : 
    1592           2 : void SvTreeListBox::SetModel( SvTreeList* pNewModel )
    1593             : {
    1594           2 :     pImp->SetModel( pNewModel );
    1595           2 :     SetBaseModel(pNewModel);
    1596           2 : }
    1597             : 
    1598         268 : void SvTreeListBox::SetBaseModel( SvTreeList* pNewModel )
    1599             : {
    1600             :     // does the CleanUp
    1601         268 :     SvListView::SetModel( pNewModel );
    1602         268 :     pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
    1603         268 :     SvTreeListEntry* pEntry = First();
    1604         536 :     while( pEntry )
    1605             :     {
    1606           0 :         ModelHasInserted( pEntry );
    1607           0 :         pEntry = Next( pEntry );
    1608             :     }
    1609         268 : }
    1610             : 
    1611           2 : void SvTreeListBox::DisconnectFromModel()
    1612             : {
    1613           2 :     SvTreeList* pNewModel = new SvTreeList;
    1614           2 :     pNewModel->SetRefCount( 0 );    // else this will never be deleted
    1615           2 :     SvListView::SetModel( pNewModel );
    1616             : 
    1617           2 :     pImp->SetModel( GetModel() );
    1618           2 : }
    1619             : 
    1620           0 : void SvTreeListBox::SetSublistOpenWithReturn( bool b )
    1621             : {
    1622           0 :     pImp->bSubLstOpRet = b;
    1623           0 : }
    1624             : 
    1625         266 : void SvTreeListBox::SetSublistOpenWithLeftRight( bool b )
    1626             : {
    1627         266 :     pImp->bSubLstOpLR = b;
    1628         266 : }
    1629             : 
    1630         639 : void SvTreeListBox::Resize()
    1631             : {
    1632         639 :     if( IsEditingActive() )
    1633           0 :         EndEditing( true );
    1634             : 
    1635         639 :     Control::Resize();
    1636             : 
    1637         639 :     pImp->Resize();
    1638         639 :     nFocusWidth = -1;
    1639         639 :     pImp->ShowCursor( false );
    1640         639 :     pImp->ShowCursor( true );
    1641         639 : }
    1642             : 
    1643             : /* Cases:
    1644             : 
    1645             :    A) entries have bitmaps
    1646             :        0. no buttons
    1647             :        1. node buttons (can optionally also be on root items)
    1648             :        2. node buttons (can optionally also be on root items) + CheckButton
    1649             :        3. CheckButton
    1650             :    B) entries don't have bitmaps  (=>via WindowBits because of D&D!)
    1651             :        0. no buttons
    1652             :        1. node buttons (can optionally also be on root items)
    1653             :        2. node buttons (can optionally also be on root items) + CheckButton
    1654             :        3. CheckButton
    1655             : */
    1656             : 
    1657             : #define NO_BUTTONS              0
    1658             : #define NODE_BUTTONS            1
    1659             : #define NODE_AND_CHECK_BUTTONS  2
    1660             : #define CHECK_BUTTONS           3
    1661             : 
    1662             : #define TABFLAGS_TEXT (SV_LBOXTAB_DYNAMIC |        \
    1663             :                        SV_LBOXTAB_ADJUST_LEFT |    \
    1664             :                        SV_LBOXTAB_EDITABLE |       \
    1665             :                        SV_LBOXTAB_SHOW_SELECTION)
    1666             : 
    1667             : #define TABFLAGS_CONTEXTBMP (SV_LBOXTAB_DYNAMIC | SV_LBOXTAB_ADJUST_CENTER)
    1668             : 
    1669             : #define TABFLAGS_CHECKBTN (SV_LBOXTAB_DYNAMIC |        \
    1670             :                            SV_LBOXTAB_ADJUST_CENTER |  \
    1671             :                            SV_LBOXTAB_PUSHABLE)
    1672             : 
    1673             : #define TAB_STARTPOS    2
    1674             : 
    1675             : // take care of GetTextOffset when doing changes
    1676        1832 : void SvTreeListBox::SetTabs()
    1677             : {
    1678        1832 :     if( IsEditingActive() )
    1679           0 :         EndEditing( true );
    1680        1832 :     nTreeFlags &= (~TREEFLAG_RECALCTABS);
    1681        1832 :     nFocusWidth = -1;
    1682        1832 :     const WinBits nStyle( GetStyle() );
    1683        1832 :     bool bHasButtons = (nStyle & WB_HASBUTTONS)!=0;
    1684        1832 :     bool bHasButtonsAtRoot = (nStyle & (WB_HASLINESATROOT |
    1685        1832 :                                               WB_HASBUTTONSATROOT))!=0;
    1686        1832 :     long nStartPos = TAB_STARTPOS;
    1687        1832 :     long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width();
    1688             : 
    1689             :     // pCheckButtonData->Width() knows nothing about the native checkbox width,
    1690             :     // so we have mnCheckboxItemWidth which becomes valid when something is added.
    1691        1832 :     long nCheckWidth = 0;
    1692        1832 :     if( nTreeFlags & TREEFLAG_CHKBTN )
    1693           0 :         nCheckWidth = mnCheckboxItemWidth;
    1694        1832 :     long nCheckWidthDIV2 = nCheckWidth / 2;
    1695             : 
    1696        1832 :     long nContextWidth = nContextBmpWidthMax;
    1697        1832 :     long nContextWidthDIV2 = nContextWidth / 2;
    1698             : 
    1699        1832 :     ClearTabList();
    1700             : 
    1701        1832 :     int nCase = NO_BUTTONS;
    1702        1832 :     if( !(nTreeFlags & TREEFLAG_CHKBTN) )
    1703             :     {
    1704        1832 :         if( bHasButtons )
    1705        1230 :             nCase = NODE_BUTTONS;
    1706             :     }
    1707             :     else
    1708             :     {
    1709           0 :         if( bHasButtons )
    1710           0 :             nCase = NODE_AND_CHECK_BUTTONS;
    1711             :          else
    1712           0 :             nCase = CHECK_BUTTONS;
    1713             :     }
    1714             : 
    1715        1832 :     switch( nCase )
    1716             :     {
    1717             :         case NO_BUTTONS :
    1718         602 :             nStartPos += nContextWidthDIV2;  // because of centering
    1719         602 :             AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
    1720         602 :             nStartPos += nContextWidthDIV2;  // right edge of context bitmap
    1721             :             // only set a distance if there are bitmaps
    1722         602 :             if( nContextBmpWidthMax )
    1723           0 :                 nStartPos += 5; // distance context bitmap to text
    1724         602 :             AddTab( nStartPos, TABFLAGS_TEXT );
    1725         602 :             break;
    1726             : 
    1727             :         case NODE_BUTTONS :
    1728        1230 :             if( bHasButtonsAtRoot )
    1729        1230 :                 nStartPos += ( nIndent + (nNodeWidthPixel/2) );
    1730             :             else
    1731           0 :                 nStartPos += nContextWidthDIV2;
    1732        1230 :             AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
    1733        1230 :             nStartPos += nContextWidthDIV2;  // right edge of context bitmap
    1734             :             // only set a distance if there are bitmaps
    1735        1230 :             if( nContextBmpWidthMax )
    1736         204 :                 nStartPos += 5; // distance context bitmap to text
    1737        1230 :             AddTab( nStartPos, TABFLAGS_TEXT );
    1738        1230 :             break;
    1739             : 
    1740             :         case NODE_AND_CHECK_BUTTONS :
    1741           0 :             if( bHasButtonsAtRoot )
    1742           0 :                 nStartPos += ( nIndent + nNodeWidthPixel );
    1743             :             else
    1744           0 :                 nStartPos += nCheckWidthDIV2;
    1745           0 :             AddTab( nStartPos, TABFLAGS_CHECKBTN );
    1746           0 :             nStartPos += nCheckWidthDIV2;  // right edge of CheckButton
    1747           0 :             nStartPos += 3;  // distance CheckButton to context bitmap
    1748           0 :             nStartPos += nContextWidthDIV2;  // center of context bitmap
    1749           0 :             AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
    1750           0 :             nStartPos += nContextWidthDIV2;  // right edge of context bitmap
    1751             :             // only set a distance if there are bitmaps
    1752           0 :             if( nContextBmpWidthMax )
    1753           0 :                 nStartPos += 5; // distance context bitmap to text
    1754           0 :             AddTab( nStartPos, TABFLAGS_TEXT );
    1755           0 :             break;
    1756             : 
    1757             :         case CHECK_BUTTONS :
    1758           0 :             nStartPos += nCheckWidthDIV2;
    1759           0 :             AddTab( nStartPos, TABFLAGS_CHECKBTN );
    1760           0 :             nStartPos += nCheckWidthDIV2;  // right edge of CheckButton
    1761           0 :             nStartPos += 3;  // distance CheckButton to context bitmap
    1762           0 :             nStartPos += nContextWidthDIV2;  // center of context bitmap
    1763           0 :             AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
    1764           0 :             nStartPos += nContextWidthDIV2;  // right edge of context bitmap
    1765             :             // only set a distance if there are bitmaps
    1766           0 :             if( nContextBmpWidthMax )
    1767           0 :                 nStartPos += 5; // distance context bitmap to text
    1768           0 :             AddTab( nStartPos, TABFLAGS_TEXT );
    1769           0 :             break;
    1770             :     }
    1771        1832 :     pImp->NotifyTabsChanged();
    1772        1832 : }
    1773             : 
    1774        1450 : void SvTreeListBox::InitEntry(SvTreeListEntry* pEntry,
    1775             :     const OUString& aStr, const Image& aCollEntryBmp, const Image& aExpEntryBmp,
    1776             :     SvLBoxButtonKind eButtonKind)
    1777             : {
    1778             :     SvLBoxButton* pButton;
    1779             :     SvLBoxString* pString;
    1780             :     SvLBoxContextBmp* pContextBmp;
    1781             : 
    1782        1450 :     if( nTreeFlags & TREEFLAG_CHKBTN )
    1783             :     {
    1784           0 :         pButton= new SvLBoxButton( pEntry,eButtonKind,0,pCheckButtonData );
    1785           0 :         pEntry->AddItem( pButton );
    1786             :     }
    1787             : 
    1788             :     pContextBmp= new SvLBoxContextBmp(
    1789        1450 :         pEntry,0, aCollEntryBmp,aExpEntryBmp, mbContextBmpExpanded);
    1790        1450 :     pEntry->AddItem( pContextBmp );
    1791             : 
    1792        1450 :     pString = new SvLBoxString( pEntry, 0, aStr );
    1793        1450 :     pEntry->AddItem( pString );
    1794        1450 : }
    1795             : 
    1796          28 : OUString SvTreeListBox::GetEntryText(SvTreeListEntry* pEntry) const
    1797             : {
    1798             :     DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): no entry" );
    1799          28 :     SvLBoxString* pItem = static_cast<SvLBoxString*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
    1800             :     DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): item not found" );
    1801          28 :     return pItem->GetText();
    1802             : }
    1803             : 
    1804        1450 : const Image& SvTreeListBox::GetExpandedEntryBmp(const SvTreeListEntry* pEntry) const
    1805             : {
    1806             :     DBG_ASSERT(pEntry,"Entry?");
    1807        1450 :     const SvLBoxContextBmp* pItem = static_cast<const SvLBoxContextBmp*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
    1808             :     DBG_ASSERT(pItem,"GetContextBmp:Item not found");
    1809        1450 :     return pItem->GetBitmap2( );
    1810             : }
    1811             : 
    1812        1450 : const Image& SvTreeListBox::GetCollapsedEntryBmp( const SvTreeListEntry* pEntry ) const
    1813             : {
    1814             :     DBG_ASSERT(pEntry,"Entry?");
    1815        1450 :     const SvLBoxContextBmp* pItem = static_cast<const SvLBoxContextBmp*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
    1816             :     DBG_ASSERT(pItem,"GetContextBmp:Item not found");
    1817        1450 :     return pItem->GetBitmap1( );
    1818             : }
    1819             : 
    1820           0 : IMPL_LINK_INLINE_START( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )
    1821             : {
    1822           0 :     pHdlEntry = pData->GetActEntry();
    1823           0 :     CheckButtonHdl();
    1824           0 :     return 0;
    1825             : }
    1826           0 : IMPL_LINK_INLINE_END( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )
    1827             : 
    1828           2 : SvTreeListEntry* SvTreeListBox::InsertEntry(
    1829             :     const OUString& rText,
    1830             :     SvTreeListEntry* pParent,
    1831             :     bool bChildrenOnDemand, sal_uLong nPos,
    1832             :     void* pUser,
    1833             :     SvLBoxButtonKind eButtonKind
    1834             : )
    1835             : {
    1836           2 :     nTreeFlags |= TREEFLAG_MANINS;
    1837             : 
    1838           2 :     const Image& rDefExpBmp = pImp->GetDefaultEntryExpBmp( );
    1839           2 :     const Image& rDefColBmp = pImp->GetDefaultEntryColBmp( );
    1840             : 
    1841           2 :     aCurInsertedExpBmp = rDefExpBmp;
    1842           2 :     aCurInsertedColBmp = rDefColBmp;
    1843             : 
    1844           2 :     SvTreeListEntry* pEntry = CreateEntry();
    1845           2 :     pEntry->SetUserData( pUser );
    1846           2 :     InitEntry( pEntry, rText, rDefColBmp, rDefExpBmp, eButtonKind );
    1847           2 :     pEntry->EnableChildrenOnDemand( bChildrenOnDemand );
    1848             : 
    1849           2 :     if( !pParent )
    1850           0 :         Insert( pEntry, nPos );
    1851             :     else
    1852           2 :         Insert( pEntry, pParent, nPos );
    1853             : 
    1854           2 :     aPrevInsertedExpBmp = rDefExpBmp;
    1855           2 :     aPrevInsertedColBmp = rDefColBmp;
    1856             : 
    1857           2 :     nTreeFlags &= (~TREEFLAG_MANINS);
    1858             : 
    1859           2 :     return pEntry;
    1860             : }
    1861             : 
    1862        1448 : SvTreeListEntry* SvTreeListBox::InsertEntry( const OUString& rText,
    1863             :     const Image& aExpEntryBmp, const Image& aCollEntryBmp,
    1864             :     SvTreeListEntry* pParent, bool bChildrenOnDemand, sal_uLong nPos, void* pUser,
    1865             :     SvLBoxButtonKind eButtonKind )
    1866             : {
    1867        1448 :     nTreeFlags |= TREEFLAG_MANINS;
    1868             : 
    1869        1448 :     aCurInsertedExpBmp = aExpEntryBmp;
    1870        1448 :     aCurInsertedColBmp = aCollEntryBmp;
    1871             : 
    1872        1448 :     SvTreeListEntry* pEntry = CreateEntry();
    1873        1448 :     pEntry->SetUserData( pUser );
    1874        1448 :     InitEntry( pEntry, rText, aCollEntryBmp, aExpEntryBmp, eButtonKind );
    1875             : 
    1876        1448 :     pEntry->EnableChildrenOnDemand( bChildrenOnDemand );
    1877             : 
    1878        1448 :     if( !pParent )
    1879        1444 :         Insert( pEntry, nPos );
    1880             :     else
    1881           4 :         Insert( pEntry, pParent, nPos );
    1882             : 
    1883        1448 :     aPrevInsertedExpBmp = aExpEntryBmp;
    1884        1448 :     aPrevInsertedColBmp = aCollEntryBmp;
    1885             : 
    1886        1448 :     nTreeFlags &= (~TREEFLAG_MANINS);
    1887             : 
    1888        1448 :     return pEntry;
    1889             : }
    1890             : 
    1891           0 : void SvTreeListBox::SetEntryText(SvTreeListEntry* pEntry, const OUString& rStr)
    1892             : {
    1893           0 :     SvLBoxString* pItem = static_cast<SvLBoxString*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
    1894             :     DBG_ASSERT(pItem,"SetText:Item not found");
    1895           0 :     pItem->SetText(rStr);
    1896           0 :     pItem->InitViewData( this, pEntry, 0 );
    1897           0 :     GetModel()->InvalidateEntry( pEntry );
    1898           0 : }
    1899             : 
    1900           2 : void SvTreeListBox::SetExpandedEntryBmp( SvTreeListEntry* pEntry, const Image& aBmp )
    1901             : {
    1902           2 :     SvLBoxContextBmp* pItem = static_cast<SvLBoxContextBmp*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
    1903             : 
    1904             :     DBG_ASSERT(pItem,"SetExpBmp:Item not found");
    1905           2 :     pItem->SetBitmap2( aBmp );
    1906             : 
    1907           2 :     GetModel()->InvalidateEntry( pEntry );
    1908           2 :     SetEntryHeight( pEntry );
    1909           2 :     Size aSize = aBmp.GetSizePixel();
    1910           2 :     short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
    1911           2 :     if( nWidth > nContextBmpWidthMax )
    1912             :     {
    1913           0 :         nContextBmpWidthMax = nWidth;
    1914           0 :         SetTabs();
    1915             :     }
    1916           2 : }
    1917             : 
    1918           2 : void SvTreeListBox::SetCollapsedEntryBmp(SvTreeListEntry* pEntry,const Image& aBmp )
    1919             : {
    1920           2 :     SvLBoxContextBmp* pItem = static_cast<SvLBoxContextBmp*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
    1921             : 
    1922             :     DBG_ASSERT(pItem,"SetExpBmp:Item not found");
    1923           2 :     pItem->SetBitmap1( aBmp );
    1924             : 
    1925           2 :     GetModel()->InvalidateEntry( pEntry );
    1926           2 :     SetEntryHeight( pEntry );
    1927           2 :     Size aSize = aBmp.GetSizePixel();
    1928           2 :     short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
    1929           2 :     if( nWidth > nContextBmpWidthMax )
    1930             :     {
    1931           0 :         nContextBmpWidthMax = nWidth;
    1932           0 :         SetTabs();
    1933             :     }
    1934           2 : }
    1935             : 
    1936        1450 : void SvTreeListBox::ImpEntryInserted( SvTreeListEntry* pEntry )
    1937             : {
    1938             : 
    1939        1450 :     SvTreeListEntry* pParent = (SvTreeListEntry*)pModel->GetParent( pEntry );
    1940        1450 :     if( pParent )
    1941             :     {
    1942           6 :         sal_uInt16 nFlags = pParent->GetFlags();
    1943           6 :         nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
    1944           6 :         pParent->SetFlags( nFlags );
    1945             :     }
    1946             : 
    1947        4350 :     if(!((nTreeFlags & TREEFLAG_MANINS) &&
    1948        1450 :          (aPrevInsertedExpBmp == aCurInsertedExpBmp)  &&
    1949        1450 :          (aPrevInsertedColBmp == aCurInsertedColBmp) ))
    1950             :     {
    1951        1450 :         Size aSize = GetCollapsedEntryBmp( pEntry ).GetSizePixel();
    1952        1450 :         if( aSize.Width() > nContextBmpWidthMax )
    1953             :         {
    1954         124 :             nContextBmpWidthMax = (short)aSize.Width();
    1955         124 :             nTreeFlags |= TREEFLAG_RECALCTABS;
    1956             :         }
    1957        1450 :         aSize = GetExpandedEntryBmp( pEntry ).GetSizePixel();
    1958        1450 :         if( aSize.Width() > nContextBmpWidthMax )
    1959             :         {
    1960           0 :             nContextBmpWidthMax = (short)aSize.Width();
    1961           0 :             nTreeFlags |= TREEFLAG_RECALCTABS;
    1962             :         }
    1963             :     }
    1964        1450 :     SetEntryHeight( (SvTreeListEntry*)pEntry );
    1965             : 
    1966        1450 :     if( nTreeFlags & TREEFLAG_CHKBTN )
    1967             :     {
    1968           0 :         SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
    1969           0 :         if( pItem )
    1970             :         {
    1971           0 :             long nWidth = pItem->GetSize(this, pEntry).Width();
    1972           0 :             if( mnCheckboxItemWidth < nWidth )
    1973             :             {
    1974           0 :                 mnCheckboxItemWidth = nWidth;
    1975           0 :                 nTreeFlags |= TREEFLAG_RECALCTABS;
    1976             :             }
    1977             :         }
    1978             :     }
    1979        1450 : }
    1980             : 
    1981             : 
    1982             : 
    1983           0 : void SvTreeListBox::SetCheckButtonState( SvTreeListEntry* pEntry, SvButtonState eState)
    1984             : {
    1985           0 :     if( nTreeFlags & TREEFLAG_CHKBTN )
    1986             :     {
    1987           0 :         SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
    1988           0 :         if(!(pItem && pItem->CheckModification()))
    1989           0 :             return ;
    1990           0 :         switch( eState )
    1991             :         {
    1992             :             case SV_BUTTON_CHECKED:
    1993           0 :                 pItem->SetStateChecked();
    1994           0 :                 break;
    1995             : 
    1996             :             case SV_BUTTON_UNCHECKED:
    1997           0 :                 pItem->SetStateUnchecked();
    1998           0 :                 break;
    1999             : 
    2000             :             case SV_BUTTON_TRISTATE:
    2001           0 :                 pItem->SetStateTristate();
    2002           0 :                 break;
    2003             :         }
    2004           0 :         InvalidateEntry( pEntry );
    2005             :     }
    2006             : }
    2007             : 
    2008           0 : void SvTreeListBox::SetCheckButtonInvisible( SvTreeListEntry* pEntry)
    2009             : {
    2010           0 :     if( nTreeFlags & TREEFLAG_CHKBTN )
    2011             :     {
    2012           0 :         SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
    2013           0 :         pItem->SetStateInvisible();
    2014           0 :         InvalidateEntry( pEntry );
    2015             :     }
    2016           0 : }
    2017             : 
    2018          72 : SvButtonState SvTreeListBox::GetCheckButtonState( SvTreeListEntry* pEntry ) const
    2019             : {
    2020          72 :     SvButtonState eState = SV_BUTTON_UNCHECKED;
    2021          72 :     if( nTreeFlags & TREEFLAG_CHKBTN )
    2022             :     {
    2023           0 :         SvLBoxButton* pItem = static_cast<SvLBoxButton*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
    2024           0 :         if(!pItem)
    2025           0 :             return SV_BUTTON_TRISTATE;
    2026           0 :         sal_uInt16 nButtonFlags = pItem->GetButtonFlags();
    2027           0 :         eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
    2028             :     }
    2029          72 :     return eState;
    2030             : }
    2031             : 
    2032           0 : void SvTreeListBox::CheckButtonHdl()
    2033             : {
    2034           0 :     aCheckButtonHdl.Call( this );
    2035           0 :     if ( pCheckButtonData )
    2036           0 :         pImp->CallEventListeners( VCLEVENT_CHECKBOX_TOGGLE, (void*)pCheckButtonData->GetActEntry() );
    2037           0 : }
    2038             : 
    2039             : 
    2040             : // TODO: Currently all data is cloned so that they conform to the default tree
    2041             : // view format. Actually, the model should be used as a reference here. This
    2042             : // leads to us _not_ calling SvTreeListEntry::Clone, but only its base class
    2043             : // SvTreeListEntry.
    2044             : 
    2045             : 
    2046           0 : SvTreeListEntry* SvTreeListBox::CloneEntry( SvTreeListEntry* pSource )
    2047             : {
    2048           0 :     OUString aStr;
    2049           0 :     Image aCollEntryBmp;
    2050           0 :     Image aExpEntryBmp;
    2051           0 :     SvLBoxButtonKind eButtonKind = SvLBoxButtonKind_enabledCheckbox;
    2052             : 
    2053           0 :     SvLBoxString* pStringItem = static_cast<SvLBoxString*>(pSource->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
    2054           0 :     if( pStringItem )
    2055           0 :         aStr = pStringItem->GetText();
    2056           0 :     SvLBoxContextBmp* pBmpItem = static_cast<SvLBoxContextBmp*>(pSource->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
    2057           0 :     if( pBmpItem )
    2058             :     {
    2059           0 :         aCollEntryBmp = pBmpItem->GetBitmap1( );
    2060           0 :         aExpEntryBmp  = pBmpItem->GetBitmap2( );
    2061             :     }
    2062           0 :     SvLBoxButton* pButtonItem = static_cast<SvLBoxButton*>(pSource->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
    2063           0 :     if( pButtonItem )
    2064           0 :         eButtonKind = pButtonItem->GetKind();
    2065           0 :     SvTreeListEntry* pClone = CreateEntry();
    2066           0 :     InitEntry( pClone, aStr, aCollEntryBmp, aExpEntryBmp, eButtonKind );
    2067           0 :     pClone->SvTreeListEntry::Clone( pSource );
    2068           0 :     pClone->EnableChildrenOnDemand( pSource->HasChildrenOnDemand() );
    2069           0 :     pClone->SetUserData( pSource->GetUserData() );
    2070             : 
    2071           0 :     return pClone;
    2072             : }
    2073             : 
    2074           0 : void SvTreeListBox::SetIndent( short nNewIndent )
    2075             : {
    2076           0 :     nIndent = nNewIndent;
    2077           0 :     SetTabs();
    2078           0 :     if( IsUpdateMode() )
    2079           0 :         Invalidate();
    2080           0 : }
    2081             : 
    2082        1244 : const Image& SvTreeListBox::GetDefaultExpandedEntryBmp( ) const
    2083             : {
    2084        1244 :     return pImp->GetDefaultEntryExpBmp( );
    2085             : }
    2086             : 
    2087        1244 : const Image& SvTreeListBox::GetDefaultCollapsedEntryBmp( ) const
    2088             : {
    2089        1244 :     return pImp->GetDefaultEntryColBmp( );
    2090             : }
    2091             : 
    2092         644 : void SvTreeListBox::SetDefaultExpandedEntryBmp( const Image& aBmp )
    2093             : {
    2094         644 :     Size aSize = aBmp.GetSizePixel();
    2095         644 :     if( aSize.Width() > nContextBmpWidthMax )
    2096          18 :         nContextBmpWidthMax = (short)aSize.Width();
    2097         644 :     SetTabs();
    2098             : 
    2099         644 :     pImp->SetDefaultEntryExpBmp( aBmp );
    2100         644 : }
    2101             : 
    2102         644 : void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image& aBmp )
    2103             : {
    2104         644 :     Size aSize = aBmp.GetSizePixel();
    2105         644 :     if( aSize.Width() > nContextBmpWidthMax )
    2106          22 :         nContextBmpWidthMax = (short)aSize.Width();
    2107         644 :     SetTabs();
    2108             : 
    2109         644 :     pImp->SetDefaultEntryColBmp( aBmp );
    2110         644 : }
    2111             : 
    2112           8 : void SvTreeListBox::EnableCheckButton( SvLBoxButtonData* pData )
    2113             : {
    2114             :     DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0");
    2115           8 :     if( !pData )
    2116           8 :         nTreeFlags &= (~TREEFLAG_CHKBTN);
    2117             :     else
    2118             :     {
    2119           0 :         SetCheckButtonData( pData );
    2120           0 :         nTreeFlags |= TREEFLAG_CHKBTN;
    2121           0 :         pData->SetLink( LINK(this, SvTreeListBox, CheckButtonClick));
    2122             :     }
    2123             : 
    2124           8 :     SetTabs();
    2125           8 :     if( IsUpdateMode() )
    2126           8 :         Invalidate();
    2127           8 : }
    2128             : 
    2129           0 : void SvTreeListBox::SetCheckButtonData( SvLBoxButtonData* pData )
    2130             : {
    2131           0 :     if ( pData )
    2132           0 :         pCheckButtonData = pData;
    2133           0 : }
    2134             : 
    2135         144 : const Image& SvTreeListBox::GetDefaultExpandedNodeImage( )
    2136             : {
    2137         144 :     return SvImpLBox::GetDefaultExpandedNodeImage( );
    2138             : }
    2139             : 
    2140         144 : const Image& SvTreeListBox::GetDefaultCollapsedNodeImage( )
    2141             : {
    2142         144 :     return SvImpLBox::GetDefaultCollapsedNodeImage( );
    2143             : }
    2144             : 
    2145         146 : void SvTreeListBox::SetNodeBitmaps( const Image& rCollapsedNodeBmp, const Image& rExpandedNodeBmp )
    2146             : {
    2147         146 :     SetExpandedNodeBmp( rExpandedNodeBmp );
    2148         146 :     SetCollapsedNodeBmp( rCollapsedNodeBmp );
    2149         146 :     SetTabs();
    2150         146 : }
    2151             : 
    2152           0 : bool SvTreeListBox::EditingEntry( SvTreeListEntry*, Selection& )
    2153             : {
    2154           0 :     return true;
    2155             : }
    2156             : 
    2157           0 : bool SvTreeListBox::EditedEntry( SvTreeListEntry* /*pEntry*/,const OUString& /*rNewText*/)
    2158             : {
    2159           0 :     return true;
    2160             : }
    2161             : 
    2162           2 : void SvTreeListBox::EnableInplaceEditing( bool bOn )
    2163             : {
    2164           2 :     if (bOn)
    2165           2 :         nImpFlags |= SVLBOX_EDT_ENABLED;
    2166             :     else
    2167           0 :         nImpFlags &= ~SVLBOX_EDT_ENABLED;
    2168           2 : }
    2169             : 
    2170           0 : void SvTreeListBox::KeyInput( const KeyEvent& rKEvt )
    2171             : {
    2172             :     // under OS/2, we get key up/down even while editing
    2173           0 :     if( IsEditingActive() )
    2174           0 :         return;
    2175             : 
    2176           0 :     nImpFlags |= SVLBOX_IS_TRAVELSELECT;
    2177             : 
    2178           0 :     if( !pImp->KeyInput( rKEvt ) )
    2179             :     {
    2180           0 :         bool bHandled = HandleKeyInput( rKEvt );
    2181           0 :         if ( !bHandled )
    2182           0 :             Control::KeyInput( rKEvt );
    2183             :     }
    2184             : 
    2185           0 :     nImpFlags &= ~SVLBOX_IS_TRAVELSELECT;
    2186             : }
    2187             : 
    2188           0 : void SvTreeListBox::RequestingChildren( SvTreeListEntry* pParent )
    2189             : {
    2190           0 :     if( !pParent->HasChildren() )
    2191           0 :         InsertEntry( OUString("<dummy>"), pParent, false, TREELIST_APPEND );
    2192           0 : }
    2193             : 
    2194         122 : void SvTreeListBox::GetFocus()
    2195             : {
    2196             :     //If there is no item in the tree, draw focus.
    2197         122 :     if( !First())
    2198             :     {
    2199           0 :         Invalidate();
    2200             :     }
    2201         122 :     pImp->GetFocus();
    2202         122 :     Control::GetFocus();
    2203             : 
    2204         122 :     SvTreeListEntry* pEntry = FirstSelected();
    2205         122 :     if ( !pEntry )
    2206             :     {
    2207         121 :         pEntry = pImp->GetCurrentEntry();
    2208             :     }
    2209         122 :     if (pImp->pCursor)
    2210             :     {
    2211           1 :         if (pEntry != pImp->pCursor)
    2212           0 :             pEntry = pImp->pCursor;
    2213             :     }
    2214         122 :     if ( pEntry )
    2215           1 :         pImp->CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS, pEntry );
    2216             : 
    2217         122 : }
    2218             : 
    2219          20 : void SvTreeListBox::LoseFocus()
    2220             : {
    2221             :     //If there is no item in the tree, delete visual focus.
    2222          20 :     if( !First())
    2223             :     {
    2224           0 :         Invalidate();
    2225             :     }
    2226          20 :     pImp->LoseFocus();
    2227          20 :     Control::LoseFocus();
    2228          20 : }
    2229             : 
    2230         622 : void SvTreeListBox::ModelHasCleared()
    2231             : {
    2232         622 :     pImp->pCursor = 0; // else we crash in GetFocus when editing in-place
    2233         622 :     delete pEdCtrl;
    2234         622 :     pEdCtrl = NULL;
    2235         622 :     pImp->Clear();
    2236         622 :     nFocusWidth = -1;
    2237             : 
    2238         622 :     nContextBmpWidthMax = 0;
    2239         622 :     SetDefaultExpandedEntryBmp( GetDefaultExpandedEntryBmp() );
    2240         622 :     SetDefaultCollapsedEntryBmp( GetDefaultCollapsedEntryBmp() );
    2241             : 
    2242         622 :     if( !(nTreeFlags & TREEFLAG_FIXEDHEIGHT ))
    2243         622 :         nEntryHeight = 0;
    2244         622 :     AdjustEntryHeight( GetFont() );
    2245         622 :     AdjustEntryHeight( GetDefaultExpandedEntryBmp() );
    2246         622 :     AdjustEntryHeight( GetDefaultCollapsedEntryBmp() );
    2247             : 
    2248         622 :     SvListView::ModelHasCleared();
    2249         622 : }
    2250             : 
    2251           0 : void SvTreeListBox::ShowTargetEmphasis( SvTreeListEntry* pEntry, bool /*bShow*/ )
    2252             : {
    2253           0 :     pImp->PaintDDCursor( pEntry );
    2254           0 : }
    2255             : 
    2256           0 : void SvTreeListBox::ScrollOutputArea( short nDeltaEntries )
    2257             : {
    2258           0 :     if( !nDeltaEntries || !pImp->aVerSBar.IsVisible() )
    2259           0 :         return;
    2260             : 
    2261           0 :     long nThumb = pImp->aVerSBar.GetThumbPos();
    2262           0 :     long nMax = pImp->aVerSBar.GetRange().Max();
    2263             : 
    2264           0 :     NotifyBeginScroll();
    2265           0 :     if( nDeltaEntries < 0 )
    2266             :     {
    2267             :         // move window up
    2268           0 :         nDeltaEntries *= -1;
    2269           0 :         long nVis = pImp->aVerSBar.GetVisibleSize();
    2270           0 :         long nTemp = nThumb + nVis;
    2271           0 :         if( nDeltaEntries > (nMax - nTemp) )
    2272           0 :             nDeltaEntries = (short)(nMax - nTemp);
    2273           0 :         pImp->PageDown( (sal_uInt16)nDeltaEntries );
    2274             :     }
    2275             :     else
    2276             :     {
    2277           0 :         if( nDeltaEntries > nThumb )
    2278           0 :             nDeltaEntries = (short)nThumb;
    2279           0 :         pImp->PageUp( (sal_uInt16)nDeltaEntries );
    2280             :     }
    2281           0 :     pImp->SyncVerThumb();
    2282           0 :     NotifyEndScroll();
    2283             : }
    2284             : 
    2285           0 : void SvTreeListBox::ScrollToAbsPos( long nPos )
    2286             : {
    2287           0 :     pImp->ScrollToAbsPos( nPos );
    2288           0 : }
    2289             : 
    2290         264 : void SvTreeListBox::SetSelectionMode( SelectionMode eSelectMode )
    2291             : {
    2292         264 :     eSelMode = eSelectMode;
    2293         264 :     pImp->SetSelectionMode( eSelectMode );
    2294         264 : }
    2295             : 
    2296         364 : void SvTreeListBox::SetDragDropMode( DragDropMode nDDMode )
    2297             : {
    2298         364 :     nDragDropMode = nDDMode;
    2299         364 :     pImp->SetDragDropMode( nDDMode );
    2300         364 : }
    2301             : 
    2302        4428 : short SvTreeListBox::GetHeightOffset(const Image& rBmp, Size& aSizeLogic )
    2303             : {
    2304        4428 :     short nOffset = 0;
    2305        4428 :     aSizeLogic = rBmp.GetSizePixel();
    2306        4428 :     if( GetEntryHeight() > aSizeLogic.Height() )
    2307        4428 :         nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
    2308        4428 :     return nOffset;
    2309             : }
    2310             : 
    2311        1580 : short SvTreeListBox::GetHeightOffset(const vcl::Font& /* rFont */, Size& aSizeLogic )
    2312             : {
    2313        1580 :     short nOffset = 0;
    2314        1580 :     aSizeLogic = Size(GetTextWidth(OUString('X')), GetTextHeight());
    2315        1580 :     if( GetEntryHeight() > aSizeLogic.Height() )
    2316         160 :         nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
    2317        1580 :     return nOffset;
    2318             : }
    2319             : 
    2320        1454 : void SvTreeListBox::SetEntryHeight( SvTreeListEntry* pEntry )
    2321             : {
    2322        1454 :     short nHeight, nHeightMax=0;
    2323        1454 :     sal_uInt16 nCount = pEntry->ItemCount();
    2324        1454 :     sal_uInt16 nCur = 0;
    2325        1454 :     SvViewDataEntry* pViewData = GetViewDataEntry( pEntry );
    2326        5816 :     while( nCur < nCount )
    2327             :     {
    2328        2908 :         SvLBoxItem* pItem = pEntry->GetItem( nCur );
    2329        2908 :         nHeight = (short)(pItem->GetSize( pViewData, nCur ).Height());
    2330        2908 :         if( nHeight > nHeightMax )
    2331        1454 :             nHeightMax = nHeight;
    2332        2908 :         nCur++;
    2333             :     }
    2334             : 
    2335        1454 :     if( nHeightMax > nEntryHeight )
    2336             :     {
    2337           2 :         nEntryHeight = nHeightMax;
    2338           2 :         Control::SetFont( GetFont() );
    2339           2 :         pImp->SetEntryHeight( nHeightMax );
    2340             :     }
    2341        1454 : }
    2342             : 
    2343           0 : void SvTreeListBox::SetEntryHeight( short nHeight, bool bAlways )
    2344             : {
    2345             : 
    2346           0 :     if( bAlways || nHeight > nEntryHeight )
    2347             :     {
    2348           0 :         nEntryHeight = nHeight;
    2349           0 :         if( nEntryHeight )
    2350           0 :             nTreeFlags |= TREEFLAG_FIXEDHEIGHT;
    2351             :         else
    2352           0 :             nTreeFlags &= ~TREEFLAG_FIXEDHEIGHT;
    2353           0 :         Control::SetFont( GetFont() );
    2354           0 :         pImp->SetEntryHeight( nHeight );
    2355             :     }
    2356           0 : }
    2357             : 
    2358             : 
    2359        1536 : void SvTreeListBox::AdjustEntryHeight( const Image& rBmp )
    2360             : {
    2361        1536 :     Size aSize;
    2362        1536 :     GetHeightOffset( rBmp, aSize );
    2363        1536 :     if( aSize.Height() > nEntryHeight )
    2364             :     {
    2365           0 :         nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
    2366           0 :         pImp->SetEntryHeight( nEntryHeight );
    2367             :     }
    2368        1536 : }
    2369             : 
    2370        1580 : void SvTreeListBox::AdjustEntryHeight( const vcl::Font& rFont )
    2371             : {
    2372        1580 :     Size aSize;
    2373        1580 :     GetHeightOffset( rFont, aSize );
    2374        1580 :     if( aSize.Height()  >  nEntryHeight )
    2375             :     {
    2376         888 :         nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
    2377         888 :         pImp->SetEntryHeight( nEntryHeight );
    2378             :     }
    2379        1580 : }
    2380             : 
    2381           4 : bool SvTreeListBox::Expand( SvTreeListEntry* pParent )
    2382             : {
    2383           4 :     pHdlEntry = pParent;
    2384           4 :     bool bExpanded = false;
    2385             :     sal_uInt16 nFlags;
    2386             : 
    2387           4 :     if( pParent->HasChildrenOnDemand() )
    2388           2 :         RequestingChildren( pParent );
    2389           4 :     if( pParent->HasChildren() )
    2390             :     {
    2391           4 :         nImpFlags |= SVLBOX_IS_EXPANDING;
    2392           4 :         if( ExpandingHdl() )
    2393             :         {
    2394           4 :             bExpanded = true;
    2395           4 :             ExpandListEntry( pParent );
    2396           4 :             pImp->EntryExpanded( pParent );
    2397           4 :             pHdlEntry = pParent;
    2398           4 :             ExpandedHdl();
    2399             :         }
    2400           4 :         nFlags = pParent->GetFlags();
    2401           4 :         nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
    2402           4 :         nFlags |= SV_ENTRYFLAG_HAD_CHILDREN;
    2403           4 :         pParent->SetFlags( nFlags );
    2404             :     }
    2405             :     else
    2406             :     {
    2407           0 :         nFlags = pParent->GetFlags();
    2408           0 :         nFlags |= SV_ENTRYFLAG_NO_NODEBMP;
    2409           0 :         pParent->SetFlags( nFlags );
    2410           0 :         GetModel()->InvalidateEntry( pParent ); // repaint
    2411             :     }
    2412             : 
    2413             :     // #i92103#
    2414           4 :     if ( bExpanded )
    2415             :     {
    2416           4 :         pImp->CallEventListeners( VCLEVENT_ITEM_EXPANDED, pParent );
    2417             :     }
    2418             : 
    2419           4 :     return bExpanded;
    2420             : }
    2421             : 
    2422           0 : bool SvTreeListBox::Collapse( SvTreeListEntry* pParent )
    2423             : {
    2424           0 :     nImpFlags &= ~SVLBOX_IS_EXPANDING;
    2425           0 :     pHdlEntry = pParent;
    2426           0 :     bool bCollapsed = false;
    2427             : 
    2428           0 :     if( ExpandingHdl() )
    2429             :     {
    2430           0 :         bCollapsed = true;
    2431           0 :         pImp->CollapsingEntry( pParent );
    2432           0 :         CollapseListEntry( pParent );
    2433           0 :         pImp->EntryCollapsed( pParent );
    2434           0 :         pHdlEntry = pParent;
    2435           0 :         ExpandedHdl();
    2436             :     }
    2437             : 
    2438             :     // #i92103#
    2439           0 :     if ( bCollapsed )
    2440             :     {
    2441           0 :         pImp->CallEventListeners( VCLEVENT_ITEM_COLLAPSED, pParent );
    2442             :     }
    2443             : 
    2444           0 :     return bCollapsed;
    2445             : }
    2446             : 
    2447         132 : bool SvTreeListBox::Select( SvTreeListEntry* pEntry, bool bSelect )
    2448             : {
    2449             :     DBG_ASSERT(pEntry,"Select: Null-Ptr");
    2450         132 :     bool bRetVal = SelectListEntry( pEntry, bSelect );
    2451             :     DBG_ASSERT(IsSelected(pEntry)==bSelect,"Select failed");
    2452         132 :     if( bRetVal )
    2453             :     {
    2454         127 :         pImp->EntrySelected( pEntry, bSelect );
    2455         127 :         pHdlEntry = pEntry;
    2456         127 :         if( bSelect )
    2457             :         {
    2458         125 :             SelectHdl();
    2459         125 :             CallEventListeners( VCLEVENT_LISTBOX_TREESELECT, pEntry);
    2460             :         }
    2461             :         else
    2462           2 :             DeselectHdl();
    2463             :     }
    2464         132 :     return bRetVal;
    2465             : }
    2466             : 
    2467           0 : sal_uLong SvTreeListBox::SelectChildren( SvTreeListEntry* pParent, bool bSelect )
    2468             : {
    2469           0 :     pImp->DestroyAnchor();
    2470           0 :     sal_uLong nRet = 0;
    2471           0 :     if( !pParent->HasChildren() )
    2472           0 :         return 0;
    2473           0 :     sal_uInt16 nRefDepth = pModel->GetDepth( pParent );
    2474           0 :     SvTreeListEntry* pChild = FirstChild( pParent );
    2475           0 :     do {
    2476           0 :         nRet++;
    2477           0 :         Select( pChild, bSelect );
    2478           0 :         pChild = Next( pChild );
    2479           0 :     } while( pChild && pModel->GetDepth( pChild ) > nRefDepth );
    2480           0 :     return nRet;
    2481             : }
    2482             : 
    2483          12 : void SvTreeListBox::SelectAll( bool bSelect, bool )
    2484             : {
    2485             :     pImp->SelAllDestrAnch(
    2486             :         bSelect,
    2487             :         true,       // delete anchor,
    2488          12 :         true );     // even when using SINGLE_SELECTION, deselect the cursor
    2489          12 : }
    2490             : 
    2491           0 : void SvTreeListBox::ModelHasInsertedTree( SvTreeListEntry* pEntry )
    2492             : {
    2493           0 :     sal_uInt16 nRefDepth = pModel->GetDepth( (SvTreeListEntry*)pEntry );
    2494           0 :     SvTreeListEntry* pTmp = (SvTreeListEntry*)pEntry;
    2495           0 :     do
    2496             :     {
    2497           0 :         ImpEntryInserted( pTmp );
    2498           0 :         pTmp = Next( pTmp );
    2499           0 :     } while( pTmp && nRefDepth < pModel->GetDepth( pTmp ) );
    2500           0 :     pImp->TreeInserted( (SvTreeListEntry*)pEntry );
    2501           0 : }
    2502             : 
    2503        1450 : void SvTreeListBox::ModelHasInserted( SvTreeListEntry* pEntry )
    2504             : {
    2505        1450 :     ImpEntryInserted( (SvTreeListEntry*)pEntry );
    2506        1450 :     pImp->EntryInserted( (SvTreeListEntry*)pEntry );
    2507        1450 : }
    2508             : 
    2509           0 : void SvTreeListBox::ModelIsMoving(SvTreeListEntry* pSource,
    2510             :                                         SvTreeListEntry* /* pTargetParent */,
    2511             :                                         sal_uLong /* nChildPos */ )
    2512             : {
    2513           0 :     pImp->MovingEntry( (SvTreeListEntry*)pSource );
    2514           0 : }
    2515             : 
    2516           0 : void SvTreeListBox::ModelHasMoved( SvTreeListEntry* pSource )
    2517             : {
    2518           0 :     pImp->EntryMoved( (SvTreeListEntry*)pSource );
    2519           0 : }
    2520             : 
    2521           0 : void SvTreeListBox::ModelIsRemoving( SvTreeListEntry* pEntry )
    2522             : {
    2523           0 :     if(pEdEntry == pEntry)
    2524           0 :         pEdEntry = NULL;
    2525             : 
    2526           0 :     pImp->RemovingEntry( (SvTreeListEntry*)pEntry );
    2527           0 :     NotifyRemoving( (SvTreeListEntry*)pEntry );
    2528           0 : }
    2529             : 
    2530           0 : void SvTreeListBox::ModelHasRemoved( SvTreeListEntry* pEntry  )
    2531             : {
    2532           0 :     if ( pEntry == pHdlEntry)
    2533           0 :         pHdlEntry = NULL;
    2534           0 :     pImp->EntryRemoved();
    2535           0 : }
    2536             : 
    2537         146 : void SvTreeListBox::SetCollapsedNodeBmp( const Image& rBmp)
    2538             : {
    2539         146 :     AdjustEntryHeight( rBmp );
    2540         146 :     pImp->SetCollapsedNodeBmp( rBmp );
    2541         146 : }
    2542             : 
    2543         146 : void SvTreeListBox::SetExpandedNodeBmp( const Image& rBmp )
    2544             : {
    2545         146 :     AdjustEntryHeight( rBmp );
    2546         146 :     pImp->SetExpandedNodeBmp( rBmp );
    2547         146 : }
    2548             : 
    2549             : 
    2550         522 : void SvTreeListBox::SetFont( const vcl::Font& rFont )
    2551             : {
    2552         522 :     vcl::Font aTempFont( rFont );
    2553         538 :     vcl::Font aOrigFont( GetFont() );
    2554         522 :     aTempFont.SetTransparent( true );
    2555         522 :     if (aTempFont == aOrigFont)
    2556         506 :         return;
    2557          16 :     Control::SetFont( aTempFont );
    2558             : 
    2559          16 :     aTempFont.SetColor(aOrigFont.GetColor());
    2560          16 :     aTempFont.SetFillColor(aOrigFont.GetFillColor());
    2561          16 :     aTempFont.SetTransparent(aOrigFont.IsTransparent());
    2562             : 
    2563          16 :     if (aTempFont == aOrigFont)
    2564           0 :         return;
    2565             : 
    2566          32 :     AdjustEntryHeightAndRecalc( GetFont() );
    2567             : }
    2568             : 
    2569         958 : void SvTreeListBox::AdjustEntryHeightAndRecalc( const vcl::Font& rFont )
    2570             : {
    2571         958 :     AdjustEntryHeight( rFont );
    2572             :     // always invalidate, else things go wrong in SetEntryHeight
    2573         958 :     RecalcViewData();
    2574         958 : }
    2575             : 
    2576         285 : void SvTreeListBox::Paint( const Rectangle& rRect )
    2577             : {
    2578         285 :     Control::Paint( rRect );
    2579         285 :     if( nTreeFlags & TREEFLAG_RECALCTABS )
    2580           0 :         SetTabs();
    2581         285 :     pImp->Paint( rRect );
    2582             :     //Add visual focus draw
    2583         285 :     if( !First() )
    2584             :     {
    2585         134 :         if( HasFocus() )
    2586             :         {
    2587         108 :             long tempHeight = GetTextHeight();
    2588             :             Rectangle tempRect(
    2589         216 :                                 Point(0,0),Size(GetSizePixel().Width(),tempHeight)
    2590         108 :                                );
    2591         108 :             ShowFocus(tempRect);
    2592             :         }
    2593             : 
    2594             :         else{
    2595          26 :             HideFocus();
    2596             :         }
    2597             :     }
    2598         285 : }
    2599             : 
    2600           0 : void SvTreeListBox::MouseButtonDown( const MouseEvent& rMEvt )
    2601             : {
    2602           0 :     pImp->MouseButtonDown( rMEvt );
    2603           0 : }
    2604             : 
    2605           0 : void SvTreeListBox::MouseButtonUp( const MouseEvent& rMEvt )
    2606             : {
    2607           0 :     pImp->MouseButtonUp( rMEvt );
    2608           0 : }
    2609             : 
    2610           0 : void SvTreeListBox::MouseMove( const MouseEvent& rMEvt )
    2611             : {
    2612           0 :     pImp->MouseMove( rMEvt );
    2613           0 : }
    2614             : 
    2615             : 
    2616        1672 : void SvTreeListBox::SetUpdateMode( bool bUpdate )
    2617             : {
    2618        1672 :     pImp->SetUpdateMode( bUpdate );
    2619        1672 : }
    2620             : 
    2621         410 : void SvTreeListBox::SetSpaceBetweenEntries( short nOffsLogic )
    2622             : {
    2623         410 :     if( nOffsLogic != nEntryHeightOffs )
    2624             :     {
    2625         410 :         nEntryHeight = nEntryHeight - nEntryHeightOffs;
    2626         410 :         nEntryHeightOffs = (short)nOffsLogic;
    2627         410 :         nEntryHeight = nEntryHeight + nOffsLogic;
    2628         410 :         AdjustEntryHeightAndRecalc( GetFont() );
    2629         410 :         pImp->SetEntryHeight( nEntryHeight );
    2630             :     }
    2631         410 : }
    2632             : 
    2633           2 : void SvTreeListBox::SetCursor( SvTreeListEntry* pEntry, bool bForceNoSelect )
    2634             : {
    2635           2 :     pImp->SetCursor(pEntry, bForceNoSelect);
    2636           2 : }
    2637             : 
    2638           4 : void SvTreeListBox::SetCurEntry( SvTreeListEntry* pEntry )
    2639             : {
    2640           4 :     pImp->SetCurEntry( pEntry );
    2641           4 : }
    2642             : 
    2643        1832 : Image SvTreeListBox::GetExpandedNodeBmp( ) const
    2644             : {
    2645        1832 :     return pImp->GetExpandedNodeBmp( );
    2646             : }
    2647             : 
    2648           0 : Point SvTreeListBox::GetEntryPosition( SvTreeListEntry* pEntry ) const
    2649             : {
    2650           0 :     return pImp->GetEntryPosition( pEntry );
    2651             : }
    2652             : 
    2653           0 : void SvTreeListBox::ShowEntry( SvTreeListEntry* pEntry )
    2654             : {
    2655           0 :     MakeVisible( pEntry );
    2656           0 : }
    2657             : 
    2658           2 : void SvTreeListBox::MakeVisible( SvTreeListEntry* pEntry )
    2659             : {
    2660           2 :     pImp->MakeVisible(pEntry);
    2661           2 : }
    2662             : 
    2663           0 : void SvTreeListBox::MakeVisible( SvTreeListEntry* pEntry, bool bMoveToTop )
    2664             : {
    2665           0 :     pImp->MakeVisible( pEntry, bMoveToTop );
    2666           0 : }
    2667             : 
    2668          14 : void SvTreeListBox::ModelHasEntryInvalidated( SvTreeListEntry* pEntry )
    2669             : {
    2670             : 
    2671             :     // reinitialize the separate items of the entries
    2672          14 :     sal_uInt16 nCount = ((SvTreeListEntry*)pEntry)->ItemCount();
    2673          42 :     for( sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++ )
    2674             :     {
    2675          28 :         SvLBoxItem* pItem = ((SvTreeListEntry*)pEntry)->GetItem( nIdx );
    2676          28 :         pItem->InitViewData( this, (SvTreeListEntry*)pEntry, 0 );
    2677             :     }
    2678             : 
    2679             :     // repaint
    2680          14 :     pImp->InvalidateEntry( (SvTreeListEntry*)pEntry );
    2681          14 : }
    2682             : 
    2683           0 : void SvTreeListBox::EditItemText( SvTreeListEntry* pEntry, SvLBoxString* pItem,
    2684             :     const Selection& rSelection )
    2685             : {
    2686             :     DBG_ASSERT(pEntry&&pItem,"EditItemText: Bad params");
    2687           0 :     if( IsSelected( pEntry ))
    2688             :     {
    2689           0 :         pImp->ShowCursor( false );
    2690           0 :         SelectListEntry( pEntry, false );
    2691           0 :         PaintEntry( pEntry );
    2692           0 :         SelectListEntry( pEntry, true );
    2693           0 :         pImp->ShowCursor( true );
    2694             :     }
    2695           0 :     pEdEntry = pEntry;
    2696           0 :     pEdItem = pItem;
    2697           0 :     SvLBoxTab* pTab = GetTab( pEntry, pItem );
    2698             :     DBG_ASSERT(pTab,"EditItemText:Tab not found");
    2699             : 
    2700           0 :     Size aItemSize( pItem->GetSize(this, pEntry) );
    2701           0 :     Point aPos = GetEntryPosition( pEntry );
    2702           0 :     aPos.Y() += ( nEntryHeight - aItemSize.Height() ) / 2;
    2703           0 :     aPos.X() = GetTabPos( pEntry, pTab );
    2704           0 :     long nOutputWidth = pImp->GetOutputSize().Width();
    2705           0 :     Size aSize( nOutputWidth - aPos.X(), aItemSize.Height() );
    2706           0 :     sal_uInt16 nPos = std::find( aTabs.begin(), aTabs.end(), pTab ) - aTabs.begin();
    2707           0 :     if( nPos+1 < (sal_uInt16)aTabs.size() )
    2708             :     {
    2709           0 :         SvLBoxTab* pRightTab = aTabs[ nPos + 1 ];
    2710           0 :         long nRight = GetTabPos( pEntry, pRightTab );
    2711           0 :         if( nRight <= nOutputWidth )
    2712           0 :             aSize.Width() = nRight - aPos.X();
    2713             :     }
    2714           0 :     Point aOrigin( GetMapMode().GetOrigin() );
    2715           0 :     aPos += aOrigin; // convert to win coordinates
    2716           0 :     aSize.Width() -= aOrigin.X();
    2717           0 :     Rectangle aRect( aPos, aSize );
    2718           0 :     EditText( pItem->GetText(), aRect, rSelection );
    2719           0 : }
    2720             : 
    2721           0 : void SvTreeListBox::EditEntry( SvTreeListEntry* pEntry )
    2722             : {
    2723           0 :     pImp->aEditClickPos = Point( -1, -1 );
    2724           0 :     ImplEditEntry( pEntry );
    2725           0 : }
    2726             : 
    2727           0 : void SvTreeListBox::ImplEditEntry( SvTreeListEntry* pEntry )
    2728             : {
    2729           0 :     if( IsEditingActive() )
    2730           0 :         EndEditing();
    2731           0 :     if( !pEntry )
    2732           0 :         pEntry = GetCurEntry();
    2733           0 :     if( pEntry )
    2734             :     {
    2735           0 :         long nClickX = pImp->aEditClickPos.X();
    2736           0 :         bool bIsMouseTriggered = nClickX >= 0;
    2737             : 
    2738           0 :         SvLBoxString* pItem = NULL;
    2739           0 :         sal_uInt16 nCount = pEntry->ItemCount();
    2740           0 :         long nTabPos, nNextTabPos = 0;
    2741           0 :         for( sal_uInt16 i = 0 ; i < nCount ; i++ )
    2742             :         {
    2743           0 :             SvLBoxItem* pTmpItem = pEntry->GetItem( i );
    2744           0 :             if (pTmpItem->GetType() != SV_ITEM_ID_LBOXSTRING)
    2745           0 :                 continue;
    2746             : 
    2747           0 :             SvLBoxTab* pTab = GetTab( pEntry, pTmpItem );
    2748           0 :             nNextTabPos = -1;
    2749           0 :             if( i < nCount - 1 )
    2750             :             {
    2751           0 :                 SvLBoxItem* pNextItem = pEntry->GetItem( i + 1 );
    2752           0 :                 SvLBoxTab* pNextTab = GetTab( pEntry, pNextItem );
    2753           0 :                 nNextTabPos = pNextTab->GetPos();
    2754             :             }
    2755             : 
    2756           0 :             if( pTab && pTab->IsEditable() )
    2757             :             {
    2758           0 :                 nTabPos = pTab->GetPos();
    2759           0 :                 if( !bIsMouseTriggered || (nClickX > nTabPos && (nNextTabPos == -1 || nClickX < nNextTabPos ) ) )
    2760             :                 {
    2761           0 :                     pItem = static_cast<SvLBoxString*>( pTmpItem );
    2762           0 :                     break;
    2763             :                 }
    2764             :             }
    2765             :         }
    2766             : 
    2767           0 :         Selection aSel( SELECTION_MIN, SELECTION_MAX );
    2768           0 :         if( pItem && EditingEntry( pEntry, aSel ) )
    2769             :         {
    2770           0 :             SelectAll( false );
    2771           0 :             MakeVisible( pEntry );
    2772           0 :             EditItemText( pEntry, pItem, aSel );
    2773             :         }
    2774             :     }
    2775           0 : }
    2776             : 
    2777           0 : bool SvTreeListBox::AreChildrenTransient() const
    2778             : {
    2779           0 :     return pImp->AreChildrenTransient();
    2780             : }
    2781             : 
    2782           0 : void SvTreeListBox::SetChildrenNotTransient()
    2783             : {
    2784           0 :     pImp->SetChildrenNotTransient();
    2785           0 : }
    2786             : 
    2787           0 : void SvTreeListBox::EditedText( const OUString& rStr )
    2788             : 
    2789             : {
    2790           0 :     if(pEdEntry) // we have to check if this entry is null that means that it is removed while editing
    2791             :     {
    2792           0 :         if( EditedEntry( pEdEntry, rStr ) )
    2793             :         {
    2794           0 :             static_cast<SvLBoxString*>(pEdItem)->SetText( rStr );
    2795           0 :             pModel->InvalidateEntry( pEdEntry );
    2796             :         }
    2797           0 :         if( GetSelectionCount() == 0 )
    2798           0 :             Select( pEdEntry );
    2799           0 :         if( GetSelectionMode() == MULTIPLE_SELECTION && !GetCurEntry() )
    2800           0 :             SetCurEntry( pEdEntry );
    2801             :     }
    2802           0 : }
    2803             : 
    2804           0 : SvTreeListEntry* SvTreeListBox::GetDropTarget( const Point& rPos )
    2805             : {
    2806             :     // scroll
    2807           0 :     if( rPos.Y() < 12 )
    2808             :     {
    2809           0 :         ImplShowTargetEmphasis(pTargetEntry, false);
    2810           0 :         ScrollOutputArea( +1 );
    2811             :     }
    2812             :     else
    2813             :     {
    2814           0 :         Size aSize( pImp->GetOutputSize() );
    2815           0 :         if( rPos.Y() > aSize.Height() - 12 )
    2816             :         {
    2817           0 :             ImplShowTargetEmphasis(pTargetEntry, false);
    2818           0 :             ScrollOutputArea( -1 );
    2819             :         }
    2820             :     }
    2821             : 
    2822           0 :     SvTreeListEntry* pTarget = pImp->GetEntry( rPos );
    2823             :     // when dropping in a vacant space, use the last entry
    2824           0 :     if( !pTarget )
    2825           0 :         return (SvTreeListEntry*)LastVisible();
    2826           0 :     else if( (GetDragDropMode() & SV_DRAGDROP_ENABLE_TOP) &&
    2827           0 :              pTarget == First() && rPos.Y() < 6 )
    2828           0 :         return 0;
    2829             : 
    2830           0 :     return pTarget;
    2831             : }
    2832             : 
    2833             : 
    2834           0 : SvTreeListEntry* SvTreeListBox::GetEntry( const Point& rPos, bool bHit ) const
    2835             : {
    2836           0 :     SvTreeListEntry* pEntry = pImp->GetEntry( rPos );
    2837           0 :     if( pEntry && bHit )
    2838             :     {
    2839           0 :         long nLine = pImp->GetEntryLine( pEntry );
    2840           0 :         if( !(pImp->EntryReallyHit( pEntry, rPos, nLine)) )
    2841           0 :             return 0;
    2842             :     }
    2843           0 :     return pEntry;
    2844             : }
    2845             : 
    2846           6 : SvTreeListEntry* SvTreeListBox::GetCurEntry() const
    2847             : {
    2848           6 :     return pImp->GetCurEntry();
    2849             : }
    2850             : 
    2851         628 : void SvTreeListBox::ImplInitStyle()
    2852             : {
    2853             : 
    2854         628 :     const WinBits nWindowStyle = GetStyle();
    2855             : 
    2856         628 :     nTreeFlags |= TREEFLAG_RECALCTABS;
    2857         628 :     if( nWindowStyle & WB_SORT )
    2858             :     {
    2859           6 :         GetModel()->SetSortMode( SortAscending );
    2860           6 :         GetModel()->SetCompareHdl( LINK(this,SvTreeListBox,DefaultCompare));
    2861             :     }
    2862             :     else
    2863             :     {
    2864         622 :         GetModel()->SetSortMode( SortNone );
    2865         622 :         GetModel()->SetCompareHdl( Link() );
    2866             :     }
    2867         628 :     pImp->SetStyle( nWindowStyle );
    2868         628 :     pImp->Resize();
    2869         628 :     Invalidate();
    2870         628 : }
    2871             : 
    2872           0 : void SvTreeListBox::PaintEntry( SvTreeListEntry* pEntry )
    2873             : {
    2874             :     DBG_ASSERT(pEntry,"PaintEntry:No Entry");
    2875           0 :     if( pEntry )
    2876           0 :         pImp->PaintEntry( pEntry );
    2877           0 : }
    2878             : 
    2879           0 : void SvTreeListBox::InvalidateEntry( SvTreeListEntry* pEntry )
    2880             : {
    2881             :     DBG_ASSERT(pEntry,"InvalidateEntry:No Entry");
    2882           0 :     if( pEntry )
    2883             :     {
    2884           0 :         GetModel()->InvalidateEntry( pEntry );
    2885             :     }
    2886           0 : }
    2887             : 
    2888           0 : long SvTreeListBox::PaintEntry(SvTreeListEntry* pEntry,long nLine,sal_uInt16 nTabFlags)
    2889             : {
    2890           0 :     return PaintEntry1(pEntry,nLine,nTabFlags);
    2891             : }
    2892             : 
    2893        1783 : long SvTreeListBox::PaintEntry1(SvTreeListEntry* pEntry,long nLine,sal_uInt16 nTabFlags,
    2894             :     bool bHasClipRegion )
    2895             : {
    2896             : 
    2897        1783 :     Rectangle aRect; // multi purpose
    2898             : 
    2899        1783 :     bool bHorSBar = pImp->HasHorScrollBar();
    2900        1783 :     PreparePaint( pEntry );
    2901             : 
    2902        1783 :     pImp->UpdateContextBmpWidthMax( pEntry );
    2903             : 
    2904        1783 :     if( nTreeFlags & TREEFLAG_RECALCTABS )
    2905           0 :         SetTabs();
    2906             : 
    2907        1783 :     short nTempEntryHeight = GetEntryHeight();
    2908        1783 :     long nWidth = pImp->GetOutputSize().Width();
    2909             : 
    2910             :     // Did we turn on the scrollbar within PreparePaints? If yes, we have to set
    2911             :     // the ClipRegion anew.
    2912        1783 :     if( !bHorSBar && pImp->HasHorScrollBar() )
    2913           0 :         SetClipRegion( vcl::Region(pImp->GetClipRegionRect()) );
    2914             : 
    2915        1783 :     Point aEntryPos( GetMapMode().GetOrigin() );
    2916        1783 :     aEntryPos.X() *= -1; // conversion document coordinates
    2917        1783 :     long nMaxRight = nWidth + aEntryPos.X() - 1;
    2918             : 
    2919        1783 :     Color aBackupTextColor( GetTextColor() );
    2920        1783 :     vcl::Font aBackupFont( GetFont() );
    2921        1783 :     Color aBackupColor = GetFillColor();
    2922             : 
    2923        1783 :     bool bCurFontIsSel = false;
    2924        1783 :     bool bInUse = pEntry->HasInUseEmphasis();
    2925             :     // if a ClipRegion was set from outside, we don't have to reset it
    2926        1783 :     const WinBits nWindowStyle = GetStyle();
    2927        1783 :     const bool bResetClipRegion = !bHasClipRegion;
    2928        1783 :     const bool bHideSelection = (nWindowStyle & WB_HIDESELECTION) !=0 && !HasFocus();
    2929        1783 :     const StyleSettings& rSettings = GetSettings().GetStyleSettings();
    2930             : 
    2931        3566 :     vcl::Font aHighlightFont( GetFont() );
    2932        1783 :     const Color aHighlightTextColor( rSettings.GetHighlightTextColor() );
    2933        1783 :     aHighlightFont.SetColor( aHighlightTextColor );
    2934             : 
    2935        1783 :     Size aRectSize( 0, nTempEntryHeight );
    2936             : 
    2937        1783 :     if( !bHasClipRegion && nWindowStyle & WB_HSCROLL )
    2938             :     {
    2939         127 :         SetClipRegion( vcl::Region(pImp->GetClipRegionRect()) );
    2940         127 :         bHasClipRegion = true;
    2941             :     }
    2942             : 
    2943        1783 :     SvViewDataEntry* pViewDataEntry = GetViewDataEntry( pEntry );
    2944             : 
    2945        1783 :     sal_uInt16 nTabCount = aTabs.size();
    2946        1783 :     sal_uInt16 nItemCount = pEntry->ItemCount();
    2947        1783 :     sal_uInt16 nCurTab = 0;
    2948        1783 :     sal_uInt16 nCurItem = 0;
    2949             : 
    2950        7132 :     while( nCurTab < nTabCount && nCurItem < nItemCount )
    2951             :     {
    2952        3566 :         SvLBoxTab* pTab = aTabs[ nCurTab ];
    2953        3566 :         sal_uInt16 nNextTab = nCurTab + 1;
    2954        3566 :         SvLBoxTab* pNextTab = nNextTab < nTabCount ? aTabs[nNextTab] : 0;
    2955        3566 :         SvLBoxItem* pItem = nCurItem < nItemCount ? pEntry->GetItem(nCurItem) : 0;
    2956             : 
    2957        3566 :         sal_uInt16 nFlags = pTab->nFlags;
    2958        3566 :         Size aSize( pItem->GetSize( pViewDataEntry, nCurItem ));
    2959        3566 :         long nTabPos = GetTabPos( pEntry, pTab );
    2960             : 
    2961             :         long nNextTabPos;
    2962        3566 :         if( pNextTab )
    2963        1783 :             nNextTabPos = GetTabPos( pEntry, pNextTab );
    2964             :         else
    2965             :         {
    2966        1783 :             nNextTabPos = nMaxRight;
    2967        1783 :             if( nTabPos > nMaxRight )
    2968           0 :                 nNextTabPos += 50;
    2969             :         }
    2970             : 
    2971             :         long nX;
    2972        3566 :         if( pTab->nFlags & SV_LBOXTAB_ADJUST_RIGHT )
    2973             :             // avoid cutting the right edge off the tab separation
    2974           0 :             nX = nTabPos + pTab->CalcOffset(aSize.Width(), (nNextTabPos-SV_TAB_BORDER-1) -nTabPos);
    2975             :         else
    2976        3566 :             nX = nTabPos + pTab->CalcOffset(aSize.Width(), nNextTabPos-nTabPos);
    2977             : 
    2978        3566 :         if( nFlags & nTabFlags )
    2979             :         {
    2980        3566 :             if( !bHasClipRegion && nX + aSize.Width() >= nMaxRight )
    2981             :             {
    2982           0 :                 SetClipRegion( vcl::Region(pImp->GetClipRegionRect()) );
    2983           0 :                 bHasClipRegion = true;
    2984             :             }
    2985        3566 :             aEntryPos.X() = nX;
    2986        3566 :             aEntryPos.Y() = nLine;
    2987             : 
    2988             :             // set background pattern/color
    2989             : 
    2990        3566 :             Wallpaper aWallpaper = GetBackground();
    2991             : 
    2992        3566 :             int bSelTab = nFlags & SV_LBOXTAB_SHOW_SELECTION;
    2993        3566 :             sal_uInt16 nItemType = pItem->GetType();
    2994             : 
    2995        3566 :             if (pViewDataEntry->IsHighlighted() && bSelTab && !pViewDataEntry->IsCursored())
    2996             :             {
    2997         153 :                 Color aNewWallColor = rSettings.GetHighlightColor();
    2998         153 :                 if ( !bInUse || nItemType != SV_ITEM_ID_LBOXCONTEXTBMP )
    2999             :                 {
    3000             :                     // if the face color is bright then the deactive color is also bright
    3001             :                     // -> so you can't see any deactive selection
    3002         153 :                     if ( bHideSelection && !rSettings.GetFaceColor().IsBright() &&
    3003           0 :                          aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright() )
    3004           0 :                         aNewWallColor = rSettings.GetDeactiveColor();
    3005             :                     // set font color to highlight
    3006         153 :                     if ( !bCurFontIsSel )
    3007             :                     {
    3008         153 :                         SetTextColor( aHighlightTextColor );
    3009         153 :                         Control::SetFont( aHighlightFont );
    3010         153 :                         bCurFontIsSel = true;
    3011             :                     }
    3012             :                 }
    3013         153 :                 aWallpaper.SetColor( aNewWallColor );
    3014             :             }
    3015             :             else  // no selection
    3016             :             {
    3017        3413 :                 if( bInUse && nItemType == SV_ITEM_ID_LBOXCONTEXTBMP )
    3018           0 :                     aWallpaper.SetColor( rSettings.GetFieldColor() );
    3019        3413 :                 else if( bCurFontIsSel )
    3020             :                 {
    3021           0 :                     bCurFontIsSel = false;
    3022           0 :                     SetTextColor( aBackupTextColor );
    3023           0 :                     Control::SetFont( aBackupFont );
    3024             :                 }
    3025             :             }
    3026             : 
    3027             :             // draw background
    3028        3566 :             if( !(nTreeFlags & TREEFLAG_USESEL))
    3029             :             {
    3030             :                 // only draw the area that is used by the item
    3031        3566 :                 aRectSize.Width() = aSize.Width();
    3032        3566 :                 aRect.SetPos( aEntryPos );
    3033        3566 :                 aRect.SetSize( aRectSize );
    3034             :             }
    3035             :             else
    3036             :             {
    3037             :                 // draw from the current to the next tab
    3038           0 :                 if( nCurTab != 0 )
    3039           0 :                     aRect.Left() = nTabPos;
    3040             :                 else
    3041             :                     // if we're in the 0th tab, always draw from column 0 --
    3042             :                     // else we get problems with centered tabs
    3043           0 :                     aRect.Left() = 0;
    3044           0 :                 aRect.Top() = nLine;
    3045           0 :                 aRect.Bottom() = nLine + nTempEntryHeight - 1;
    3046           0 :                 if( pNextTab )
    3047             :                 {
    3048             :                     long nRight;
    3049           0 :                     nRight = GetTabPos(pEntry,pNextTab)-1;
    3050           0 :                     if( nRight > nMaxRight )
    3051           0 :                         nRight = nMaxRight;
    3052           0 :                     aRect.Right() = nRight;
    3053             :                 }
    3054             :                 else
    3055           0 :                     aRect.Right() = nMaxRight;
    3056             :             }
    3057             :             // A custom selection that starts at a tab position > 0, do not fill
    3058             :             // the background of the 0th item, else e.g. we might not be able to
    3059             :             // realize tab listboxes with lines.
    3060        3566 :             if( !(nCurTab==0 && (nTreeFlags & TREEFLAG_USESEL) && nFirstSelTab) )
    3061             :             {
    3062        3566 :                 SetFillColor( aWallpaper.GetColor() );
    3063             :                 // this case may occur for smaller horizontal resizes
    3064        3566 :                 if( aRect.Left() < aRect.Right() )
    3065        3566 :                     DrawRect( aRect );
    3066             :             }
    3067             :             // draw item
    3068             :             // center vertically
    3069        3566 :             aEntryPos.Y() += ( nTempEntryHeight - aSize.Height() ) / 2;
    3070        3566 :             pItem->Paint(aEntryPos, *this, pViewDataEntry, pEntry);
    3071             : 
    3072             :             // division line between tabs
    3073        3566 :             if (pNextTab && pItem->GetType() == SV_ITEM_ID_LBOXSTRING &&
    3074             :                 // not at the right edge of the window!
    3075           0 :                 aRect.Right() < nMaxRight)
    3076             :             {
    3077           0 :                 aRect.Left() = aRect.Right() - SV_TAB_BORDER;
    3078           0 :                 DrawRect( aRect );
    3079             :             }
    3080             : 
    3081        3566 :             SetFillColor( aBackupColor );
    3082             :         }
    3083        3566 :         nCurItem++;
    3084        3566 :         nCurTab++;
    3085             :     }
    3086        1783 :     if( pViewDataEntry->IsCursored() && !HasFocus() )
    3087             :     {
    3088             :         // cursor emphasis
    3089           0 :         SetFillColor();
    3090           0 :         Color aOldLineColor = GetLineColor();
    3091           0 :         SetLineColor( Color( COL_BLACK ) );
    3092           0 :         aRect = GetFocusRect( pEntry, nLine );
    3093           0 :         aRect.Top()++;
    3094           0 :         aRect.Bottom()--;
    3095           0 :         DrawRect( aRect );
    3096           0 :         SetLineColor( aOldLineColor );
    3097           0 :         SetFillColor( aBackupColor );
    3098             :     }
    3099             : 
    3100        1783 :     if( bCurFontIsSel )
    3101             :     {
    3102         153 :         SetTextColor( aBackupTextColor );
    3103         153 :         Control::SetFont( aBackupFont );
    3104             :     }
    3105             : 
    3106             :     sal_uInt16 nFirstDynTabPos;
    3107        1783 :     SvLBoxTab* pFirstDynamicTab = GetFirstDynamicTab( nFirstDynTabPos );
    3108        1783 :     long nDynTabPos = GetTabPos( pEntry, pFirstDynamicTab );
    3109        1783 :     nDynTabPos += pImp->nNodeBmpTabDistance;
    3110        1783 :     nDynTabPos += pImp->nNodeBmpWidth / 2;
    3111        1783 :     nDynTabPos += 4; // 4 pixels of buffer, so the node bitmap is not too close
    3112             :                      // to the next tab
    3113             : 
    3114        5349 :     if( (!(pEntry->GetFlags() & SV_ENTRYFLAG_NO_NODEBMP)) &&
    3115        5381 :         (nWindowStyle & WB_HASBUTTONS) && pFirstDynamicTab &&
    3116        3546 :         ( pEntry->HasChildren() || pEntry->HasChildrenOnDemand() ) )
    3117             :     {
    3118             :         // find first tab and check if the node bitmap extends into it
    3119          32 :         sal_uInt16 nNextTab = nFirstDynTabPos;
    3120             :         SvLBoxTab* pNextTab;
    3121          64 :         do
    3122             :         {
    3123          64 :             nNextTab++;
    3124          64 :             pNextTab = nNextTab < nTabCount ? aTabs[nNextTab] : 0;
    3125          64 :         } while( pNextTab && pNextTab->IsDynamic() );
    3126             : 
    3127          32 :         if( !pNextTab || (GetTabPos( pEntry, pNextTab ) > nDynTabPos) )
    3128             :         {
    3129          32 :             if((nWindowStyle & WB_HASBUTTONSATROOT) || pModel->GetDepth(pEntry) > 0)
    3130             :             {
    3131          32 :                 Point aPos( GetTabPos(pEntry,pFirstDynamicTab), nLine );
    3132          32 :                 aPos.X() += pImp->nNodeBmpTabDistance;
    3133             : 
    3134          32 :                 const Image* pImg = 0;
    3135             : 
    3136          32 :                 if( IsExpanded(pEntry) )
    3137          14 :                     pImg = &pImp->GetExpandedNodeBmp( );
    3138             :                 else
    3139             :                 {
    3140          84 :                     if( (!pEntry->HasChildren()) && pEntry->HasChildrenOnDemand() &&
    3141          72 :                         (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
    3142          54 :                         pImp->GetDontKnowNodeBmp().GetSizePixel().Width() )
    3143           0 :                         pImg = &pImp->GetDontKnowNodeBmp( );
    3144             :                     else
    3145          18 :                         pImg = &pImp->GetCollapsedNodeBmp( );
    3146             :                 }
    3147          32 :                 aPos.Y() += (nTempEntryHeight - pImg->GetSizePixel().Height()) / 2;
    3148             : 
    3149          32 :                 sal_uInt16 nStyle = 0;
    3150          32 :                 if ( !IsEnabled() )
    3151           0 :                     nStyle |= IMAGE_DRAW_DISABLE;
    3152             : 
    3153             :                 //native
    3154          32 :                 bool bNativeOK = false;
    3155          32 :                 if ( IsNativeControlSupported( CTRL_LISTNODE, PART_ENTIRE_CONTROL) )
    3156             :                 {
    3157           0 :                     ImplControlValue    aControlValue;
    3158           0 :                     Rectangle           aCtrlRegion( aPos,  pImg->GetSizePixel() );
    3159           0 :                     ControlState        nState = 0;
    3160             : 
    3161           0 :                     if ( IsEnabled() )  nState |= CTRL_STATE_ENABLED;
    3162             : 
    3163           0 :                     if ( IsExpanded(pEntry) )
    3164           0 :                         aControlValue.setTristateVal( BUTTONVALUE_ON );//expanded node
    3165             :                     else
    3166             :                     {
    3167           0 :                         if( (!pEntry->HasChildren() )                              &&
    3168           0 :                               pEntry->HasChildrenOnDemand()                        &&
    3169           0 :                              (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
    3170           0 :                             pImp->GetDontKnowNodeBmp().GetSizePixel().Width()
    3171             :                         )
    3172           0 :                             aControlValue.setTristateVal( BUTTONVALUE_DONTKNOW ); //dont know
    3173             :                         else
    3174           0 :                             aControlValue.setTristateVal( BUTTONVALUE_OFF ); //collapsed node
    3175             :                     }
    3176             : 
    3177             :                     bNativeOK = DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL,
    3178           0 :                                             aCtrlRegion, nState, aControlValue, OUString() );
    3179             :                 }
    3180             : 
    3181          32 :                 if( !bNativeOK) {
    3182          32 :                     DrawImage( aPos, *pImg ,nStyle);
    3183             :                 }
    3184             :             }
    3185             :         }
    3186             :     }
    3187             : 
    3188             : 
    3189        1783 :     if( bHasClipRegion && bResetClipRegion )
    3190         127 :         SetClipRegion();
    3191        3566 :     return 0; // nRowLen;
    3192             : }
    3193             : 
    3194        1783 : void SvTreeListBox::PreparePaint( SvTreeListEntry* )
    3195             : {
    3196        1783 : }
    3197             : 
    3198         123 : Rectangle SvTreeListBox::GetFocusRect( SvTreeListEntry* pEntry, long nLine )
    3199             : {
    3200         123 :     Size aSize;
    3201         123 :     Rectangle aRect;
    3202         123 :     aRect.Top() = nLine;
    3203         123 :     aSize.Height() = GetEntryHeight();
    3204             : 
    3205         123 :     long nRealWidth = pImp->GetOutputSize().Width();
    3206         123 :     nRealWidth -= GetMapMode().GetOrigin().X();
    3207             : 
    3208             :     sal_uInt16 nCurTab;
    3209         123 :     SvLBoxTab* pTab = GetFirstTab( SV_LBOXTAB_SHOW_SELECTION, nCurTab );
    3210         123 :     long nTabPos = 0;
    3211         123 :     if( pTab )
    3212         123 :         nTabPos = GetTabPos( pEntry, pTab );
    3213             :     long nNextTabPos;
    3214         123 :     if( pTab && nCurTab < aTabs.size() - 1 )
    3215             :     {
    3216           0 :         SvLBoxTab* pNextTab = aTabs[ nCurTab + 1 ];
    3217           0 :         nNextTabPos = GetTabPos( pEntry, pNextTab );
    3218             :     }
    3219             :     else
    3220             :     {
    3221         123 :         nNextTabPos = nRealWidth;
    3222         123 :         if( nTabPos > nRealWidth )
    3223           0 :             nNextTabPos += 50;
    3224             :     }
    3225             : 
    3226         123 :     bool bUserSelection = ( nTreeFlags & TREEFLAG_USESEL ) != 0;
    3227         123 :     if( !bUserSelection )
    3228             :     {
    3229         123 :         if( pTab && nCurTab < pEntry->ItemCount() )
    3230             :         {
    3231         123 :             SvLBoxItem* pItem = pEntry->GetItem( nCurTab );
    3232         123 :             aSize.Width() = pItem->GetSize( this, pEntry ).Width();
    3233         123 :             if( !aSize.Width() )
    3234           0 :                 aSize.Width() = 15;
    3235         123 :             long nX = nTabPos; //GetTabPos( pEntry, pTab );
    3236             :             // alignment
    3237         123 :             nX += pTab->CalcOffset( aSize.Width(), nNextTabPos - nTabPos );
    3238         123 :             aRect.Left() = nX;
    3239             :             // make sure that first and last letter aren't cut off slightly
    3240         123 :             aRect.SetSize( aSize );
    3241         123 :             if( aRect.Left() > 0 )
    3242         123 :                 aRect.Left()--;
    3243         123 :             aRect.Right()++;
    3244             :         }
    3245             :     }
    3246             :     else
    3247             :     {
    3248             :         // if SelTab != 0, we have to calculate also
    3249           0 :         if( nFocusWidth == -1 || nFirstSelTab )
    3250             :         {
    3251           0 :             SvLBoxTab* pLastTab = NULL; // default to select whole width
    3252             : 
    3253             :             sal_uInt16 nLastTab;
    3254           0 :             GetLastTab(SV_LBOXTAB_SHOW_SELECTION,nLastTab);
    3255           0 :             nLastTab++;
    3256           0 :             if( nLastTab < aTabs.size() ) // is there another one?
    3257           0 :                 pLastTab = aTabs[ nLastTab ];
    3258             : 
    3259           0 :             aSize.Width() = pLastTab ? pLastTab->GetPos() : 0x0fffffff;
    3260           0 :             nFocusWidth = (short)aSize.Width();
    3261           0 :             if( pTab )
    3262           0 :                 nFocusWidth = nFocusWidth - (short)nTabPos; //pTab->GetPos();
    3263             :         }
    3264             :         else
    3265             :         {
    3266           0 :             aSize.Width() = nFocusWidth;
    3267           0 :             if( pTab )
    3268             :             {
    3269           0 :                 if( nCurTab )
    3270           0 :                     aSize.Width() += nTabPos;
    3271             :                 else
    3272           0 :                     aSize.Width() += pTab->GetPos(); // Tab0 always from the leftmost position
    3273             :             }
    3274             :         }
    3275             :         // if selection starts with 0th tab, draw from column 0 on
    3276           0 :         if( nCurTab != 0 )
    3277             :         {
    3278           0 :             aRect.Left() = nTabPos;
    3279           0 :             aSize.Width() -= nTabPos;
    3280             :         }
    3281           0 :         aRect.SetSize( aSize );
    3282             :     }
    3283             :     // adjust right edge because of clipping
    3284         123 :     if( aRect.Right() >= nRealWidth )
    3285             :     {
    3286           0 :         aRect.Right() = nRealWidth-1;
    3287           0 :         nFocusWidth = (short)aRect.GetWidth();
    3288             :     }
    3289         123 :     return aRect;
    3290             : }
    3291             : 
    3292             : 
    3293         318 : sal_IntPtr SvTreeListBox::GetTabPos( SvTreeListEntry* pEntry, SvLBoxTab* pTab)
    3294             : {
    3295             :     DBG_ASSERT(pTab,"No Tab");
    3296         318 :     sal_IntPtr nPos = pTab->GetPos();
    3297         318 :     if( pTab->IsDynamic() )
    3298             :     {
    3299         318 :         sal_uInt16 nDepth = pModel->GetDepth( pEntry );
    3300         318 :         nDepth = nDepth * (sal_uInt16)nIndent;
    3301         318 :         nPos += (sal_IntPtr)nDepth;
    3302             :     }
    3303         318 :     return nPos;
    3304             : }
    3305             : 
    3306           0 : SvLBoxItem* SvTreeListBox::GetItem_Impl( SvTreeListEntry* pEntry, long nX,
    3307             :     SvLBoxTab** ppTab, sal_uInt16 nEmptyWidth )
    3308             : {
    3309           0 :     SvLBoxItem* pItemClicked = 0;
    3310           0 :     sal_uInt16 nTabCount = aTabs.size();
    3311           0 :     sal_uInt16 nItemCount = pEntry->ItemCount();
    3312           0 :     SvLBoxTab* pTab = aTabs.front();
    3313           0 :     SvLBoxItem* pItem = pEntry->GetItem(0);
    3314           0 :     sal_uInt16 nNextItem = 1;
    3315           0 :     nX -= GetMapMode().GetOrigin().X();
    3316           0 :     long nRealWidth = pImp->GetOutputSize().Width();
    3317           0 :     nRealWidth -= GetMapMode().GetOrigin().X();
    3318             : 
    3319             :     while( true )
    3320             :     {
    3321           0 :         SvLBoxTab* pNextTab=nNextItem<nTabCount ? aTabs[nNextItem] : 0;
    3322           0 :         long nStart = GetTabPos( pEntry, pTab );
    3323             : 
    3324             :         long nNextTabPos;
    3325           0 :         if( pNextTab )
    3326           0 :             nNextTabPos = GetTabPos( pEntry, pNextTab );
    3327             :         else
    3328             :         {
    3329           0 :             nNextTabPos = nRealWidth;
    3330           0 :             if( nStart > nRealWidth )
    3331           0 :                 nNextTabPos += 50;
    3332             :         }
    3333             : 
    3334           0 :         Size aItemSize( pItem->GetSize(this, pEntry));
    3335           0 :         nStart += pTab->CalcOffset( aItemSize.Width(), nNextTabPos - nStart );
    3336           0 :         long nLen = aItemSize.Width();
    3337           0 :         if( pNextTab )
    3338             :         {
    3339           0 :             long nTabWidth = GetTabPos( pEntry, pNextTab ) - nStart;
    3340           0 :             if( nTabWidth < nLen )
    3341           0 :                 nLen = nTabWidth;
    3342             :         }
    3343             : 
    3344           0 :         if( !nLen )
    3345           0 :             nLen = nEmptyWidth;
    3346             : 
    3347           0 :         if( nX >= nStart && nX < (nStart+nLen ) )
    3348             :         {
    3349           0 :             pItemClicked = pItem;
    3350           0 :             if( ppTab )
    3351             :             {
    3352           0 :                 *ppTab = pTab;
    3353           0 :                 break;
    3354             :             }
    3355             :         }
    3356           0 :         if( nNextItem >= nItemCount || nNextItem >= nTabCount)
    3357             :             break;
    3358           0 :         pTab = aTabs[ nNextItem ];
    3359           0 :         pItem = pEntry->GetItem( nNextItem );
    3360           0 :         nNextItem++;
    3361             :     }
    3362           0 :     return pItemClicked;
    3363             : }
    3364             : 
    3365           0 : long SvTreeListBox::getPreferredDimensions(std::vector<long> &rWidths) const
    3366             : {
    3367           0 :     long nHeight = 0;
    3368           0 :     rWidths.clear();
    3369           0 :     SvTreeListEntry* pEntry = First();
    3370           0 :     while (pEntry)
    3371             :     {
    3372           0 :         sal_uInt16 nCount = pEntry->ItemCount();
    3373           0 :         sal_uInt16 nCurPos = 0;
    3374           0 :         if (nCount > rWidths.size())
    3375           0 :             rWidths.resize(nCount);
    3376           0 :         while (nCurPos < nCount)
    3377             :         {
    3378           0 :             SvLBoxItem* pItem = pEntry->GetItem( nCurPos );
    3379           0 :             long nWidth = pItem->GetSize(this, pEntry).Width();
    3380           0 :             if (nWidth)
    3381             :             {
    3382           0 :                 nWidth += SV_TAB_BORDER * 2;
    3383           0 :                 if (nWidth > rWidths[nCurPos])
    3384           0 :                    rWidths[nCurPos] = nWidth;
    3385             :             }
    3386           0 :             ++nCurPos;
    3387             :         }
    3388           0 :         pEntry = Next( pEntry );
    3389           0 :         nHeight += GetEntryHeight();
    3390             :     }
    3391           0 :     return nHeight;
    3392             : }
    3393             : 
    3394           0 : Size SvTreeListBox::GetOptimalSize() const
    3395             : {
    3396           0 :     std::vector<long> aWidths;
    3397           0 :     Size aRet(0, getPreferredDimensions(aWidths));
    3398           0 :     for (size_t i = 0; i < aWidths.size(); ++i)
    3399           0 :         aRet.Width() += aWidths[i];
    3400           0 :     if (GetStyle() & WB_BORDER)
    3401             :     {
    3402           0 :         const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    3403           0 :         aRet.Width() += rStyleSettings.GetBorderSize() * 2;
    3404           0 :         aRet.Height() += rStyleSettings.GetBorderSize() * 2;
    3405             :     }
    3406           0 :     long nMinWidth = nMinWidthInChars * approximate_char_width();
    3407           0 :     aRet.Width() = std::max(aRet.Width(), nMinWidth);
    3408           0 :     return aRet;
    3409             : }
    3410             : 
    3411           0 : void SvTreeListBox::SetAlternatingRowColors( bool bEnable )
    3412             : {
    3413           0 :     mbAlternatingRowColors = bEnable;
    3414           0 :     if( mbAlternatingRowColors )
    3415             :     {
    3416           0 :         SvTreeListEntry* pEntry = pModel->First();
    3417           0 :         for(size_t i = 0; pEntry; ++i)
    3418             :         {
    3419           0 :             pEntry->SetBackColor( i % 2 == 0 ? GetSettings().GetStyleSettings().GetRowColor() :
    3420           0 :                                                GetSettings().GetStyleSettings().GetAlternatingRowColor());
    3421           0 :             pEntry = pModel->Next(pEntry);
    3422             :         }
    3423             :     }
    3424             :     else
    3425           0 :         for(SvTreeListEntry* pEntry = pModel->First(); pEntry; pEntry = pModel->Next(pEntry))
    3426           0 :             pEntry->SetBackColor( GetSettings().GetStyleSettings().GetRowColor() );
    3427             : 
    3428           0 :     pImp->UpdateAll();
    3429           0 : }
    3430             : 
    3431           0 : SvLBoxItem* SvTreeListBox::GetItem(SvTreeListEntry* pEntry,long nX,SvLBoxTab** ppTab)
    3432             : {
    3433           0 :     return GetItem_Impl( pEntry, nX, ppTab, 0 );
    3434             : }
    3435             : 
    3436           0 : SvLBoxItem* SvTreeListBox::GetItem(SvTreeListEntry* pEntry,long nX )
    3437             : {
    3438             :     SvLBoxTab* pDummyTab;
    3439           0 :     return GetItem_Impl( pEntry, nX, &pDummyTab, 0 );
    3440             : }
    3441             : 
    3442        3664 : void SvTreeListBox::AddTab(long nTabPos,sal_uInt16 nFlags,void* pUserData )
    3443             : {
    3444        3664 :     nFocusWidth = -1;
    3445        3664 :     SvLBoxTab* pTab = new SvLBoxTab( nTabPos, nFlags );
    3446        3664 :     pTab->SetUserData( pUserData );
    3447        3664 :     aTabs.push_back( pTab );
    3448        3664 :     if( nTreeFlags & TREEFLAG_USESEL )
    3449             :     {
    3450           0 :         sal_uInt16 nPos = aTabs.size() - 1;
    3451           0 :         if( nPos >= nFirstSelTab && nPos <= nLastSelTab )
    3452           0 :             pTab->nFlags |= SV_LBOXTAB_SHOW_SELECTION;
    3453             :         else
    3454             :             // string items usually have to be selected -- turn this off
    3455             :             // explicitly
    3456           0 :             pTab->nFlags &= ~SV_LBOXTAB_SHOW_SELECTION;
    3457             :     }
    3458        3664 : }
    3459             : 
    3460             : 
    3461             : 
    3462        1795 : SvLBoxTab* SvTreeListBox::GetFirstDynamicTab( sal_uInt16& rPos ) const
    3463             : {
    3464        1795 :     sal_uInt16 nCurTab = 0;
    3465        1795 :     sal_uInt16 nTabCount = aTabs.size();
    3466        3590 :     while( nCurTab < nTabCount )
    3467             :     {
    3468        1795 :         SvLBoxTab* pTab = aTabs[nCurTab];
    3469        1795 :         if( pTab->nFlags & SV_LBOXTAB_DYNAMIC )
    3470             :         {
    3471        1795 :             rPos = nCurTab;
    3472        1795 :             return pTab;
    3473             :         }
    3474           0 :         nCurTab++;
    3475             :     }
    3476           0 :     return 0;
    3477             : }
    3478             : 
    3479          12 : SvLBoxTab* SvTreeListBox::GetFirstDynamicTab() const
    3480             : {
    3481             :     sal_uInt16 nDummy;
    3482          12 :     return GetFirstDynamicTab( nDummy );
    3483             : }
    3484             : 
    3485           0 : SvLBoxTab* SvTreeListBox::GetTab( SvTreeListEntry* pEntry, SvLBoxItem* pItem) const
    3486             : {
    3487           0 :     sal_uInt16 nPos = pEntry->GetPos( pItem );
    3488           0 :     return aTabs[ nPos ];
    3489             : }
    3490             : 
    3491        2094 : void SvTreeListBox::ClearTabList()
    3492             : {
    3493        2094 :     sal_uInt16 nTabCount = aTabs.size();
    3494        7844 :     while( nTabCount )
    3495             :     {
    3496        3656 :         nTabCount--;
    3497        3656 :         SvLBoxTab* pDelTab = aTabs[ nTabCount ];
    3498        3656 :         delete pDelTab;
    3499             :     }
    3500        2094 :     aTabs.clear();
    3501        2094 : }
    3502             : 
    3503             : 
    3504           2 : Size SvTreeListBox::GetOutputSizePixel() const
    3505             : {
    3506           2 :     Size aSize = pImp->GetOutputSize();
    3507           2 :     return aSize;
    3508             : }
    3509             : 
    3510           0 : void SvTreeListBox::NotifyBeginScroll()
    3511             : {
    3512           0 : }
    3513             : 
    3514           0 : void SvTreeListBox::NotifyEndScroll()
    3515             : {
    3516           0 : }
    3517             : 
    3518           0 : void SvTreeListBox::NotifyScrolling( long )
    3519             : {
    3520           0 : }
    3521             : 
    3522           0 : void SvTreeListBox::NotifyScrolled()
    3523             : {
    3524           0 :     aScrolledHdl.Call( this );
    3525           0 : }
    3526             : 
    3527        2935 : void SvTreeListBox::NotifyInvalidating()
    3528             : {
    3529        2935 : }
    3530             : 
    3531         822 : void SvTreeListBox::Invalidate( sal_uInt16 nInvalidateFlags )
    3532             : {
    3533         822 :     if( nFocusWidth == -1 )
    3534             :         // to make sure that the control doesn't show the wrong focus rectangle
    3535             :         // after painting
    3536         822 :         pImp->RecalcFocusRect();
    3537         822 :     NotifyInvalidating();
    3538         822 :     Control::Invalidate( nInvalidateFlags );
    3539         822 :     pImp->Invalidate();
    3540         822 : }
    3541             : 
    3542        2113 : void SvTreeListBox::Invalidate( const Rectangle& rRect, sal_uInt16 nInvalidateFlags )
    3543             : {
    3544        2113 :     if( nFocusWidth == -1 )
    3545             :         // to make sure that the control doesn't show the wrong focus rectangle
    3546             :         // after painting
    3547        2113 :         pImp->RecalcFocusRect();
    3548        2113 :     NotifyInvalidating();
    3549        2113 :     Control::Invalidate( rRect, nInvalidateFlags );
    3550        2113 : }
    3551             : 
    3552             : 
    3553           0 : void SvTreeListBox::SetHighlightRange( sal_uInt16 nStart, sal_uInt16 nEnd)
    3554             : {
    3555             : 
    3556             :     sal_uInt16 nTemp;
    3557           0 :     nTreeFlags |= TREEFLAG_USESEL;
    3558           0 :     if( nStart > nEnd )
    3559             :     {
    3560           0 :         nTemp = nStart;
    3561           0 :         nStart = nEnd;
    3562           0 :         nEnd = nTemp;
    3563             :     }
    3564             :     // select all tabs that lie within the area
    3565           0 :     nTreeFlags |= TREEFLAG_RECALCTABS;
    3566           0 :     nFirstSelTab = nStart;
    3567           0 :     nLastSelTab = nEnd;
    3568           0 :     pImp->RecalcFocusRect();
    3569           0 : }
    3570             : 
    3571           0 : void SvTreeListBox::Command( const CommandEvent& rCEvt )
    3572             : {
    3573             :     // FIXME gnumake2 resync to DEV300_m84
    3574           0 :     pImp->Command( rCEvt );
    3575           0 : }
    3576             : 
    3577             : 
    3578           0 : void SvTreeListBox::RemoveParentKeepChildren( SvTreeListEntry* pParent )
    3579             : {
    3580             :     DBG_ASSERT(pParent,"RemoveParentKeepChildren:No Parent");
    3581           0 :     SvTreeListEntry* pNewParent = GetParent( pParent );
    3582           0 :     if( pParent->HasChildren())
    3583             :     {
    3584           0 :         SvTreeListEntry* pChild = FirstChild( pParent );
    3585           0 :         while( pChild )
    3586             :         {
    3587           0 :             pModel->Move( pChild, pNewParent, TREELIST_APPEND );
    3588           0 :             pChild = FirstChild( pParent );
    3589             :         }
    3590             :     }
    3591           0 :     pModel->Remove( pParent );
    3592           0 : }
    3593             : 
    3594         123 : SvLBoxTab* SvTreeListBox::GetFirstTab( sal_uInt16 nFlagMask, sal_uInt16& rPos )
    3595             : {
    3596         123 :     sal_uInt16 nTabCount = aTabs.size();
    3597         246 :     for( sal_uInt16 nPos = 0; nPos < nTabCount; nPos++ )
    3598             :     {
    3599         246 :         SvLBoxTab* pTab = aTabs[ nPos ];
    3600         246 :         if( (pTab->nFlags & nFlagMask) )
    3601             :         {
    3602         123 :             rPos = nPos;
    3603         123 :             return pTab;
    3604             :         }
    3605             :     }
    3606           0 :     rPos = 0xffff;
    3607           0 :     return 0;
    3608             : }
    3609             : 
    3610           0 : SvLBoxTab* SvTreeListBox::GetLastTab( sal_uInt16 nFlagMask, sal_uInt16& rTabPos )
    3611             : {
    3612           0 :     sal_uInt16 nPos = (sal_uInt16)aTabs.size();
    3613           0 :     while( nPos )
    3614             :     {
    3615           0 :         --nPos;
    3616           0 :         SvLBoxTab* pTab = aTabs[ nPos ];
    3617           0 :         if( (pTab->nFlags & nFlagMask) )
    3618             :         {
    3619           0 :             rTabPos = nPos;
    3620           0 :             return pTab;
    3621             :         }
    3622             :     }
    3623           0 :     rTabPos = 0xffff;
    3624           0 :     return 0;
    3625             : }
    3626             : 
    3627           0 : void SvTreeListBox::RequestHelp( const HelpEvent& rHEvt )
    3628             : {
    3629           0 :     if( !pImp->RequestHelp( rHEvt ) )
    3630           0 :         Control::RequestHelp( rHEvt );
    3631           0 : }
    3632             : 
    3633           0 : void SvTreeListBox::CursorMoved( SvTreeListEntry* )
    3634             : {
    3635           0 : }
    3636             : 
    3637           0 : IMPL_LINK( SvTreeListBox, DefaultCompare, SvSortData*, pData )
    3638             : {
    3639           0 :     const SvTreeListEntry* pLeft = pData->pLeft;
    3640           0 :     const SvTreeListEntry* pRight = pData->pRight;
    3641           0 :     OUString aLeft( static_cast<const SvLBoxString*>(pLeft->GetFirstItem(SV_ITEM_ID_LBOXSTRING))->GetText());
    3642           0 :     OUString aRight( static_cast<const SvLBoxString*>(pRight->GetFirstItem(SV_ITEM_ID_LBOXSTRING))->GetText());
    3643           0 :     pImp->UpdateStringSorter();
    3644           0 :     return pImp->m_pStringSorter->compare(aLeft, aRight);
    3645             : }
    3646             : 
    3647        2708 : void SvTreeListBox::ModelNotification( SvListAction nActionId, SvTreeListEntry* pEntry1,
    3648             :                         SvTreeListEntry* pEntry2, sal_uLong nPos )
    3649             : {
    3650        2708 :     SolarMutexGuard aSolarGuard;
    3651             : 
    3652        2708 :     if( nActionId == SvListAction::CLEARING )
    3653         622 :         CancelTextEditing();
    3654             : 
    3655        2708 :     SvListView::ModelNotification( nActionId, pEntry1, pEntry2, nPos );
    3656        2708 :     switch( nActionId )
    3657             :     {
    3658             :         case SvListAction::INSERTED:
    3659             :         {
    3660        1450 :             SvTreeListEntry* pEntry( dynamic_cast< SvTreeListEntry* >( pEntry1 ) );
    3661        1450 :             if ( !pEntry )
    3662             :             {
    3663             :                 SAL_WARN( "svtools.contnr", "SvTreeListBox::ModelNotification: invalid entry!" );
    3664           0 :                 break;
    3665             :             }
    3666             : 
    3667        1450 :             SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
    3668        1450 :             if ( !pBmpItem )
    3669           0 :                 break;
    3670        1450 :             const Image& rBitmap1( pBmpItem->GetBitmap1() );
    3671        1450 :             const Image& rBitmap2( pBmpItem->GetBitmap2() );
    3672        1450 :             short nMaxWidth = short( std::max( rBitmap1.GetSizePixel().Width(), rBitmap2.GetSizePixel().Width() ) );
    3673        1450 :             nMaxWidth = pImp->UpdateContextBmpWidthVector( pEntry, nMaxWidth );
    3674        1450 :             if( nMaxWidth > nContextBmpWidthMax )
    3675             :             {
    3676           0 :                 nContextBmpWidthMax = nMaxWidth;
    3677           0 :                 SetTabs();
    3678             :             }
    3679        1450 :             if (get_width_request() == -1)
    3680        1450 :                 queue_resize();
    3681             :         }
    3682        1450 :         break;
    3683             : 
    3684             :         case SvListAction::RESORTING:
    3685           0 :             SetUpdateMode( false );
    3686           0 :             break;
    3687             : 
    3688             :         case SvListAction::RESORTED:
    3689             :             // after a selection: show first entry and also keep the selection
    3690           0 :             MakeVisible( (SvTreeListEntry*)pModel->First(), true );
    3691           0 :             SetUpdateMode( true );
    3692           0 :             break;
    3693             : 
    3694             :         case SvListAction::CLEARED:
    3695         622 :             if( IsUpdateMode() )
    3696         622 :                 Update();
    3697         622 :             break;
    3698             : 
    3699         636 :         default: break;
    3700        2708 :     }
    3701        2708 : }
    3702             : 
    3703           0 : void SvTreeListBox::EndSelection()
    3704             : {
    3705           0 :     pImp->EndSelection();
    3706           0 : }
    3707             : 
    3708           0 : void SvTreeListBox::RepaintScrollBars() const
    3709             : {
    3710           0 :     ((SvTreeListBox*)this)->pImp->RepaintScrollBars();
    3711           0 : }
    3712             : 
    3713         238 : ScrollBar *SvTreeListBox::GetVScroll()
    3714             : {
    3715         238 :     return &((SvTreeListBox*)this)->pImp->aVerSBar;
    3716             : }
    3717             : 
    3718           0 : ScrollBar *SvTreeListBox::GetHScroll()
    3719             : {
    3720           0 :     return &((SvTreeListBox*)this)->pImp->aHorSBar;
    3721             : }
    3722             : 
    3723         120 : void SvTreeListBox::EnableAsyncDrag( bool b )
    3724             : {
    3725         120 :     pImp->EnableAsyncDrag( b );
    3726         120 : }
    3727             : 
    3728           0 : SvTreeListEntry* SvTreeListBox::GetFirstEntryInView() const
    3729             : {
    3730           0 :     Point aPos;
    3731           0 :     return GetEntry( aPos );
    3732             : }
    3733             : 
    3734           0 : SvTreeListEntry* SvTreeListBox::GetNextEntryInView(SvTreeListEntry* pEntry ) const
    3735             : {
    3736           0 :     SvTreeListEntry* pNext = (SvTreeListEntry*)NextVisible( pEntry );
    3737           0 :     if( pNext )
    3738             :     {
    3739           0 :         Point aPos( GetEntryPosition(pNext) );
    3740           0 :         const Size& rSize = pImp->GetOutputSize();
    3741           0 :         if( aPos.Y() < 0 || aPos.Y() >= rSize.Height() )
    3742           0 :             return 0;
    3743             :     }
    3744           0 :     return pNext;
    3745             : }
    3746             : 
    3747           0 : SvTreeListEntry* SvTreeListBox::GetLastEntryInView() const
    3748             : {
    3749           0 :     SvTreeListEntry* pEntry = GetFirstEntryInView();
    3750           0 :     SvTreeListEntry* pNext = 0;
    3751           0 :     while( pEntry )
    3752             :     {
    3753           0 :         pNext = (SvTreeListEntry*)NextVisible( pEntry );
    3754           0 :         if( pNext )
    3755             :         {
    3756           0 :           Point aPos( GetEntryPosition(pNext) );
    3757           0 :           const Size& rSize = pImp->GetOutputSize();
    3758           0 :           if( aPos.Y() < 0 || aPos.Y() + GetEntryHeight() >= rSize.Height() )
    3759           0 :               break;
    3760             :           else
    3761           0 :               pEntry = pNext;
    3762             :         }
    3763             :         else
    3764           0 :             break;
    3765             :     }
    3766           0 :     return pEntry;
    3767             : }
    3768             : 
    3769           0 : void SvTreeListBox::ShowFocusRect( const SvTreeListEntry* pEntry )
    3770             : {
    3771           0 :     pImp->ShowFocusRect( pEntry );
    3772           0 : }
    3773             : 
    3774           0 : void SvTreeListBox::DataChanged( const DataChangedEvent& rDCEvt )
    3775             : {
    3776           0 :     if( (rDCEvt.GetType()==DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
    3777             :     {
    3778           0 :         nEntryHeight = 0;   // _together_ with true of 1. par (bFont) of InitSettings() a zero-height
    3779             :                             //  forces complete recalc of heights!
    3780           0 :         InitSettings( true, true, true );
    3781           0 :         Invalidate();
    3782             :     }
    3783             :     else
    3784           0 :         Control::DataChanged( rDCEvt );
    3785           0 : }
    3786             : 
    3787         780 : void SvTreeListBox::StateChanged( StateChangedType eType )
    3788             : {
    3789         780 :     if( eType == StateChangedType::ENABLE )
    3790          22 :         Invalidate( INVALIDATE_CHILDREN );
    3791             : 
    3792         780 :     Control::StateChanged( eType );
    3793             : 
    3794         780 :     if ( eType == StateChangedType::STYLE )
    3795         362 :         ImplInitStyle();
    3796         780 : }
    3797             : 
    3798         266 : void SvTreeListBox::InitSettings(bool bFont, bool bForeground, bool bBackground)
    3799             : {
    3800         266 :     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
    3801         266 :     if( bFont )
    3802             :     {
    3803         266 :         vcl::Font aFont;
    3804         266 :         aFont = rStyleSettings.GetFieldFont();
    3805         266 :         aFont.SetColor( rStyleSettings.GetWindowTextColor() );
    3806         266 :         SetPointFont( aFont );
    3807         266 :         AdjustEntryHeightAndRecalc( aFont );
    3808             :     }
    3809             : 
    3810         266 :     if( bForeground || bFont )
    3811             :     {
    3812         266 :         SetTextColor( rStyleSettings.GetFieldTextColor() );
    3813         266 :         SetTextFillColor();
    3814             :     }
    3815             : 
    3816         266 :     if( bBackground )
    3817         266 :         SetBackground( rStyleSettings.GetFieldColor() );
    3818             : 
    3819             :     // always try to re-create default-SvLBoxButtonData
    3820         266 :     if( pCheckButtonData && pCheckButtonData->HasDefaultImages() )
    3821           0 :         pCheckButtonData->SetDefaultImages( this );
    3822         266 : }
    3823             : 
    3824           0 : bool SvTreeListBox::IsCellFocusEnabled() const
    3825             : {
    3826           0 :     return pImp->IsCellFocusEnabled();
    3827             : }
    3828             : 
    3829           0 : bool SvTreeListBox::SetCurrentTabPos( sal_uInt16 _nNewPos )
    3830             : {
    3831           0 :     return pImp->SetCurrentTabPos( _nNewPos );
    3832             : }
    3833             : 
    3834           0 : sal_uInt16 SvTreeListBox::GetCurrentTabPos() const
    3835             : {
    3836           0 :     return pImp->GetCurrentTabPos();
    3837             : }
    3838             : 
    3839           0 : void SvTreeListBox::InitStartEntry()
    3840             : {
    3841           0 :     if( !pImp->pStartEntry )
    3842           0 :         pImp->pStartEntry = GetModel()->First();
    3843           0 : }
    3844             : 
    3845           0 : PopupMenu* SvTreeListBox::CreateContextMenu( void )
    3846             : {
    3847           0 :     return NULL;
    3848             : }
    3849             : 
    3850           0 : void SvTreeListBox::ExcecuteContextMenuAction( sal_uInt16 )
    3851             : {
    3852             :     DBG_WARNING( "SvTreeListBox::ExcecuteContextMenuAction(): now there's happening nothing!" );
    3853           0 : }
    3854             : 
    3855         248 : void SvTreeListBox::EnableContextMenuHandling( void )
    3856             : {
    3857             :     assert(pImp && "-SvTreeListBox::EnableContextMenuHandling(): No implementation!");
    3858         248 :     pImp->bContextMenuHandling = true;
    3859         248 : }
    3860             : 
    3861           0 : void SvTreeListBox::EnableList( bool _bEnable )
    3862             : {
    3863             :     // call base class method
    3864           0 :     Window::Enable(_bEnable);
    3865             :     // then paint immediately
    3866           0 :     Paint( Rectangle( Point(), GetSizePixel() ) );
    3867           0 : }
    3868             : 
    3869           6 : ::com::sun::star::uno::Reference< XAccessible > SvTreeListBox::CreateAccessible()
    3870             : {
    3871           6 :     vcl::Window* pParent = GetAccessibleParentWindow();
    3872             :     DBG_ASSERT( pParent, "SvTreeListBox::CreateAccessible - accessible parent not found" );
    3873             : 
    3874           6 :     ::com::sun::star::uno::Reference< XAccessible > xAccessible;
    3875           6 :     if ( pParent )
    3876             :     {
    3877           6 :         ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
    3878           6 :         if ( xAccParent.is() )
    3879             :         {
    3880             :             // need to be done here to get the vclxwindow later on in the accessbile
    3881           6 :             ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xTemp(GetComponentInterface());
    3882           6 :             xAccessible = pImp->m_aFactoryAccess.getFactory().createAccessibleTreeListBox( *this, xAccParent );
    3883           6 :         }
    3884             :     }
    3885           6 :     return xAccessible;
    3886             : }
    3887             : 
    3888          72 : void SvTreeListBox::FillAccessibleEntryStateSet( SvTreeListEntry* pEntry, ::utl::AccessibleStateSetHelper& rStateSet ) const
    3889             : {
    3890             :     assert(pEntry && "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry");
    3891             : 
    3892          72 :     if ( pEntry->HasChildrenOnDemand() || pEntry->HasChildren() )
    3893             :     {
    3894           0 :         rStateSet.AddState( AccessibleStateType::EXPANDABLE );
    3895           0 :         if ( IsExpanded( pEntry ) )
    3896           0 :             rStateSet.AddState( (sal_Int16)AccessibleStateType::EXPANDED );
    3897             :     }
    3898             : 
    3899          72 :     if ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED )
    3900           0 :         rStateSet.AddState( AccessibleStateType::CHECKED );
    3901          72 :     if ( IsEntryVisible( pEntry ) )
    3902          72 :         rStateSet.AddState( AccessibleStateType::VISIBLE );
    3903          72 :     if ( IsSelected( pEntry ) )
    3904           6 :         rStateSet.AddState( AccessibleStateType::SELECTED );
    3905          72 :     if ( IsEnabled() )
    3906             :     {
    3907          72 :         rStateSet.AddState( AccessibleStateType::ENABLED );
    3908          72 :         rStateSet.AddState( AccessibleStateType::FOCUSABLE );
    3909          72 :         rStateSet.AddState( AccessibleStateType::SELECTABLE );
    3910          72 :         SvViewDataEntry* pViewDataNewCur = GetViewDataEntry(pEntry);
    3911          72 :         if (pViewDataNewCur && pViewDataNewCur->HasFocus())
    3912           6 :             rStateSet.AddState( AccessibleStateType::FOCUSED );
    3913             :     }
    3914          72 : }
    3915             : 
    3916           0 : Rectangle SvTreeListBox::GetBoundingRect( SvTreeListEntry* pEntry )
    3917             : {
    3918           0 :     Point aPos = GetEntryPosition( pEntry );
    3919           0 :     Rectangle aRect = GetFocusRect( pEntry, aPos.Y() );
    3920           0 :     return aRect;
    3921             : }
    3922             : 
    3923           0 : void SvTreeListBox::EnableCellFocus()
    3924             : {
    3925           0 :     pImp->EnableCellFocus();
    3926           0 : }
    3927             : 
    3928        1014 : void SvTreeListBox::CallImplEventListeners(sal_uLong nEvent, void* pData)
    3929             : {
    3930        1014 :     CallEventListeners(nEvent, pData);
    3931        1014 : }
    3932             : 
    3933           0 : void SvTreeListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& /*rStateSet*/ ) const
    3934             : {
    3935           0 : }
    3936             : 
    3937           0 : void SvTreeListBox::set_min_width_in_chars(sal_Int32 nChars)
    3938             : {
    3939           0 :     nMinWidthInChars = nChars;
    3940           0 :     queue_resize();
    3941           0 : }
    3942             : 
    3943           0 : bool SvTreeListBox::set_property(const OString &rKey, const OString &rValue)
    3944             : {
    3945           0 :     if (rKey == "min-width-chars")
    3946             :     {
    3947           0 :         set_min_width_in_chars(rValue.toInt32());
    3948             :     }
    3949             :     else
    3950           0 :         return Control::set_property(rKey, rValue);
    3951           0 :     return true;
    3952        1227 : }
    3953             : 
    3954             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10