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

Generated by: LCOV version 1.11