1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
22 - delete anchor in SelectionEngine when selecting manually
23 - SelectAll( false ) => only repaint the delselected entries
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>
38 #include <svtools/svmedit.hxx>
39 #include <svtools/svlbitm.hxx>
40 #include <svtools/treelistentry.hxx>
41 #include <svtools/viewdataentry.hxx>
42 #include "svimpbox.hxx"
48 using namespace css::accessibility
;
51 static VclPtr
<SvTreeListBox
> pDDSource
;
52 static VclPtr
<SvTreeListBox
> pDDTarget
;
54 #define SVLBOX_ACC_RETURN 1
55 #define SVLBOX_ACC_ESCAPE 2
57 // ***************************************************************
59 class MyEdit_Impl
: public Edit
61 SvInplaceEdit2
* pOwner
;
63 MyEdit_Impl( vcl::Window
* pParent
, SvInplaceEdit2
* pOwner
);
64 virtual ~MyEdit_Impl() { disposeOnce(); }
65 virtual void dispose() SAL_OVERRIDE
{ pOwner
= NULL
; Edit::dispose(); }
66 virtual void KeyInput( const KeyEvent
& rKEvt
) SAL_OVERRIDE
;
67 virtual void LoseFocus() SAL_OVERRIDE
;
70 class MyMultiEdit_Impl
: public MultiLineEdit
72 SvInplaceEdit2
* pOwner
;
74 MyMultiEdit_Impl( vcl::Window
* pParent
, SvInplaceEdit2
* pOwner
);
75 virtual ~MyMultiEdit_Impl() { disposeOnce(); }
76 virtual void dispose() SAL_OVERRIDE
{ pOwner
= NULL
; MultiLineEdit::dispose(); }
77 virtual void KeyInput( const KeyEvent
& rKEvt
) SAL_OVERRIDE
;
78 virtual void LoseFocus() SAL_OVERRIDE
;
81 MyEdit_Impl::MyEdit_Impl( vcl::Window
* pParent
, SvInplaceEdit2
* _pOwner
) :
83 Edit( pParent
, WB_LEFT
),
90 void MyEdit_Impl::KeyInput( const KeyEvent
& rKEvt
)
92 if( !pOwner
->KeyInput( rKEvt
))
93 Edit::KeyInput( rKEvt
);
96 void MyEdit_Impl::LoseFocus()
102 MyMultiEdit_Impl::MyMultiEdit_Impl( vcl::Window
* pParent
, SvInplaceEdit2
* _pOwner
)
103 : MultiLineEdit( pParent
,
109 void MyMultiEdit_Impl::KeyInput( const KeyEvent
& rKEvt
)
111 if( !pOwner
->KeyInput( rKEvt
))
112 MultiLineEdit::KeyInput( rKEvt
);
115 void MyMultiEdit_Impl::LoseFocus()
122 SvInplaceEdit2::SvInplaceEdit2
124 vcl::Window
* pParent
, const Point
& rPos
,
126 const OUString
& rData
,
127 const Link
<>& rNotifyEditEnd
,
128 const Selection
& rSelection
,
132 aCallBackHdl ( rNotifyEditEnd
),
134 bAlreadyInCallBack ( false )
139 pEdit
= VclPtr
<MyMultiEdit_Impl
>::Create( pParent
, this );
141 pEdit
= VclPtr
<MyEdit_Impl
>::Create( pParent
, this );
143 vcl::Font
aFont( pParent
->GetFont() );
144 aFont
.SetTransparent( false );
145 Color
aColor( pParent
->GetBackground().GetColor() );
146 aFont
.SetFillColor(aColor
);
147 pEdit
->SetFont( aFont
);
148 pEdit
->SetBackground( pParent
->GetBackground() );
149 pEdit
->SetPosPixel( rPos
);
150 pEdit
->SetSizePixel( rSize
);
151 pEdit
->SetText( rData
);
152 pEdit
->SetSelection( rSelection
);
155 aAccReturn
.InsertItem( SVLBOX_ACC_RETURN
, vcl::KeyCode(KEY_RETURN
) );
156 aAccEscape
.InsertItem( SVLBOX_ACC_ESCAPE
, vcl::KeyCode(KEY_ESCAPE
) );
158 aAccReturn
.SetActivateHdl( LINK( this, SvInplaceEdit2
, ReturnHdl_Impl
) );
159 aAccEscape
.SetActivateHdl( LINK( this, SvInplaceEdit2
, EscapeHdl_Impl
) );
160 Application::InsertAccel( &aAccReturn
);
161 Application::InsertAccel( &aAccEscape
);
167 SvInplaceEdit2::~SvInplaceEdit2()
169 if( !bAlreadyInCallBack
)
171 Application::RemoveAccel( &aAccReturn
);
172 Application::RemoveAccel( &aAccEscape
);
174 pEdit
.disposeAndClear();
177 OUString
SvInplaceEdit2::GetSavedValue() const
179 return pEdit
->GetSavedValue();
182 void SvInplaceEdit2::Hide()
188 IMPL_LINK_NOARG(SvInplaceEdit2
, ReturnHdl_Impl
)
191 CallCallBackHdl_Impl();
195 IMPL_LINK_NOARG(SvInplaceEdit2
, EscapeHdl_Impl
)
198 CallCallBackHdl_Impl();
202 bool SvInplaceEdit2::KeyInput( const KeyEvent
& rKEvt
)
204 vcl::KeyCode aCode
= rKEvt
.GetKeyCode();
205 sal_uInt16 nCode
= aCode
.GetCode();
211 CallCallBackHdl_Impl();
216 CallCallBackHdl_Impl();
222 void SvInplaceEdit2::StopEditing( bool bCancel
)
224 if ( !bAlreadyInCallBack
)
227 CallCallBackHdl_Impl();
231 void SvInplaceEdit2::LoseFocus()
233 if ( !bAlreadyInCallBack
234 && ((!Application::GetFocusWindow()) || !pEdit
->IsChild( Application::GetFocusWindow()) )
238 aIdle
.SetPriority(SchedulerPriority::REPAINT
);
239 aIdle
.SetIdleHdl(LINK(this,SvInplaceEdit2
,Timeout_Impl
));
244 IMPL_LINK_NOARG_TYPED(SvInplaceEdit2
, Timeout_Impl
, Idle
*, void)
246 CallCallBackHdl_Impl();
249 void SvInplaceEdit2::CallCallBackHdl_Impl()
252 if ( !bAlreadyInCallBack
)
254 bAlreadyInCallBack
= true;
255 Application::RemoveAccel( &aAccReturn
);
256 Application::RemoveAccel( &aAccEscape
);
258 aCallBackHdl
.Call( this );
262 OUString
SvInplaceEdit2::GetText() const
264 return pEdit
->GetText();
267 // ***************************************************************
269 // ***************************************************************
272 SvLBoxTab::SvLBoxTab()
276 nFlags
= SvLBoxTabFlags::NONE
;
279 SvLBoxTab::SvLBoxTab( long nPosition
, SvLBoxTabFlags nTabFlags
)
286 SvLBoxTab::SvLBoxTab( const SvLBoxTab
& rTab
)
289 pUserData
= rTab
.pUserData
;
290 nFlags
= rTab
.nFlags
;
293 SvLBoxTab::~SvLBoxTab()
298 long SvLBoxTab::CalcOffset( long nItemWidth
, long nTabWidth
)
301 if ( nFlags
& SvLBoxTabFlags::ADJUST_RIGHT
)
303 nOffset
= nTabWidth
- nItemWidth
;
307 else if ( nFlags
& SvLBoxTabFlags::ADJUST_CENTER
)
309 if( nFlags
& SvLBoxTabFlags::FORCE
)
311 // correct implementation of centering
312 nOffset
= ( nTabWidth
- nItemWidth
) / 2;
318 // historically grown, wrong calculation of tabs which is needed by
319 // Abo-Tabbox, Tools/Options/Customize etc.
321 nOffset
= -( nItemWidth
/ 2 );
327 // ***************************************************************
329 // ***************************************************************
332 SvLBoxItem::SvLBoxItem( SvTreeListEntry
*, sal_uInt16
)
336 SvLBoxItem::SvLBoxItem()
340 SvLBoxItem::~SvLBoxItem()
344 const Size
& SvLBoxItem::GetSize(const SvTreeListBox
* pView
, const SvTreeListEntry
* pEntry
) const
346 const SvViewDataItem
* pViewData
= pView
->GetViewDataItem( pEntry
, this );
347 return pViewData
->maSize
;
350 const Size
& SvLBoxItem::GetSize(const SvViewDataEntry
* pData
, sal_uInt16 nItemPos
)
352 const SvViewDataItem
* pIData
= pData
->GetItem(nItemPos
);
353 return pIData
->maSize
;
356 struct SvTreeListBoxImpl
358 bool m_bIsEmptyTextAllowed
:1;
359 bool m_bEntryMnemonicsEnabled
:1;
360 bool m_bDoingQuickSelection
:1;
364 vcl::MnemonicEngine m_aMnemonicEngine
;
365 vcl::QuickSelectionEngine m_aQuickSelectionEngine
;
367 SvTreeListBoxImpl(SvTreeListBox
& _rBox
) :
368 m_bIsEmptyTextAllowed(true),
369 m_bEntryMnemonicsEnabled(false),
370 m_bDoingQuickSelection(false),
372 m_aMnemonicEngine(_rBox
),
373 m_aQuickSelectionEngine(_rBox
) {}
377 SvTreeListBox::SvTreeListBox(vcl::Window
* pParent
, WinBits nWinStyle
) :
378 Control(pParent
, nWinStyle
| WB_CLIPCHILDREN
),
379 DropTargetHelper(this),
380 DragSourceHelper(this),
381 mpImpl(new SvTreeListBoxImpl(*this)),
382 mbContextBmpExpanded(false),
383 mbAlternatingRowColors(false),
384 eSelMode(NO_SELECTION
),
387 nDragOptions
= DND_ACTION_COPYMOVE
| DND_ACTION_LINK
;
388 nImpFlags
= SvTreeListBoxFlags::NONE
;
390 nDragDropMode
= DragDropMode::NONE
;
391 SvTreeList
* pTempModel
= new SvTreeList
;
392 pTempModel
->SetRefCount( 0 );
393 SetBaseModel(pTempModel
);
394 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
395 pModel
->InsertView( this );
398 eSelMode
= SINGLE_SELECTION
;
399 nDragDropMode
= DragDropMode::NONE
;
400 SetType(WINDOW_TREELISTBOX
);
404 SetSublistOpenWithLeftRight();
407 SvTreeListBox::SvTreeListBox(vcl::Window
* pParent
, const ResId
& rResId
) :
408 Control(pParent
, rResId
),
409 DropTargetHelper(this),
410 DragSourceHelper(this),
411 mpImpl(new SvTreeListBoxImpl(*this)),
412 mbContextBmpExpanded(false),
413 mbAlternatingRowColors(false),
414 eSelMode(NO_SELECTION
),
418 nImpFlags
= SvTreeListBoxFlags::NONE
;
419 nDragOptions
= DND_ACTION_COPYMOVE
| DND_ACTION_LINK
;
420 nDragDropMode
= DragDropMode::NONE
;
421 SvTreeList
* pTempModel
= new SvTreeList
;
422 pTempModel
->SetRefCount( 0 );
423 SetBaseModel(pTempModel
);
424 pModel
->InsertView( this );
427 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
428 SetType(WINDOW_TREELISTBOX
);
433 SetSublistOpenWithLeftRight();
436 VCL_BUILDER_DECL_FACTORY(SvTreeListBox
)
438 WinBits nWinStyle
= WB_TABSTOP
;
439 OString sBorder
= VclBuilder::extractCustomProperty(rMap
);
440 if (!sBorder
.isEmpty())
441 nWinStyle
|= WB_BORDER
;
442 rRet
= VclPtr
<SvTreeListBox
>::Create(pParent
, nWinStyle
);
445 void SvTreeListBox::Clear()
448 pModel
->Clear(); // Model calls SvTreeListBox::ModelHasCleared()
451 void SvTreeListBox::EnableEntryMnemonics( bool _bEnable
)
453 if ( _bEnable
== IsEntryMnemonicsEnabled() )
456 mpImpl
->m_bEntryMnemonicsEnabled
= _bEnable
;
460 bool SvTreeListBox::IsEntryMnemonicsEnabled() const
462 return mpImpl
->m_bEntryMnemonicsEnabled
;
465 IMPL_LINK( SvTreeListBox
, CloneHdl_Impl
, SvTreeListEntry
*, pEntry
)
467 return reinterpret_cast<sal_IntPtr
>(CloneEntry(pEntry
));
470 sal_uLong
SvTreeListBox::Insert( SvTreeListEntry
* pEntry
, SvTreeListEntry
* pParent
, sal_uLong nPos
)
472 sal_uLong nInsPos
= pModel
->Insert( pEntry
, pParent
, nPos
);
473 pEntry
->SetBackColor( GetBackground().GetColor() );
474 if(mbAlternatingRowColors
)
476 if(nPos
== TREELIST_APPEND
)
478 if(Prev(pEntry
) && Prev(pEntry
)->GetBackColor() == GetBackground().GetColor())
479 pEntry
->SetBackColor( GetSettings().GetStyleSettings().GetAlternatingRowColor() );
482 SetAlternatingRowColors( true );
487 sal_uLong
SvTreeListBox::Insert( SvTreeListEntry
* pEntry
,sal_uLong nRootPos
)
489 sal_uLong nInsPos
= pModel
->Insert( pEntry
, nRootPos
);
490 pEntry
->SetBackColor( GetBackground().GetColor() );
491 if(mbAlternatingRowColors
)
493 if(nRootPos
== TREELIST_APPEND
)
495 if(Prev(pEntry
) && Prev(pEntry
)->GetBackColor() == GetBackground().GetColor())
496 pEntry
->SetBackColor( GetSettings().GetStyleSettings().GetAlternatingRowColor() );
499 SetAlternatingRowColors( true );
504 bool SvTreeListBox::ExpandingHdl()
506 return !aExpandingHdl
.IsSet() || aExpandingHdl
.Call( this );
509 void SvTreeListBox::ExpandedHdl()
511 aExpandedHdl
.Call( this );
514 void SvTreeListBox::SelectHdl()
516 aSelectHdl
.Call( this );
519 void SvTreeListBox::DeselectHdl()
521 aDeselectHdl
.Call( this );
524 bool SvTreeListBox::DoubleClickHdl()
526 aDoubleClickHdl
.Call( this );
531 bool SvTreeListBox::CheckDragAndDropMode( SvTreeListBox
* pSource
, sal_Int8 nAction
)
533 if ( pSource
== this )
535 if ( !(nDragDropMode
& (DragDropMode::CTRL_MOVE
| DragDropMode::CTRL_COPY
) ) )
536 return false; // D&D locked within list
537 if( DND_ACTION_MOVE
== nAction
)
539 if ( !(nDragDropMode
& DragDropMode::CTRL_MOVE
) )
540 return false; // no local move
544 if ( !(nDragDropMode
& DragDropMode::CTRL_COPY
))
545 return false; // no local copy
550 if ( !(nDragDropMode
& DragDropMode::APP_DROP
) )
551 return false; // no drop
552 if ( DND_ACTION_MOVE
== nAction
)
554 if ( !(nDragDropMode
& DragDropMode::APP_MOVE
) )
555 return false; // no global move
559 if ( !(nDragDropMode
& DragDropMode::APP_COPY
))
560 return false; // no global copy
575 1. target doesn't have children
576 - entry becomes sibling of target. entry comes after target
577 (->Window: below the target)
578 2. target is an expanded parent
579 - entry inserted at the beginning of the target childlist
580 3. target is a collapsed parent
581 - entry is inserted at the end of the target childlist
584 TriState
SvTreeListBox::NotifyMoving(
585 SvTreeListEntry
* pTarget
, // D&D dropping position in this->GetModel()
586 SvTreeListEntry
* pEntry
, // entry that we want to move, from
587 // GetSourceListBox()->GetModel()
588 SvTreeListEntry
*& rpNewParent
, // new target parent
589 sal_uLong
& rNewChildPos
) // position in childlist of target parent
591 TriState
SvTreeListBox::NotifyMoving(
592 SvTreeListEntry
* pTarget
, // D&D dropping position in this->GetModel()
593 SvTreeListEntry
*, // entry that we want to move, from
594 // GetSourceListBox()->GetModel()
595 SvTreeListEntry
*& rpNewParent
, // new target parent
596 sal_uLong
& rNewChildPos
) // position in childlist of target parent
599 DBG_ASSERT(pEntry
,"NotifyMoving:SoureEntry?");
604 return TRISTATE_TRUE
;
606 if ( !pTarget
->HasChildren() && !pTarget
->HasChildrenOnDemand() )
609 rpNewParent
= GetParent( pTarget
);
610 rNewChildPos
= SvTreeList::GetRelPos( pTarget
) + 1;
611 rNewChildPos
+= nCurEntrySelPos
;
617 rpNewParent
= pTarget
;
618 if( IsExpanded(pTarget
))
621 rNewChildPos
= TREELIST_APPEND
;
623 return TRISTATE_TRUE
;
626 TriState
SvTreeListBox::NotifyCopying(
627 SvTreeListEntry
* pTarget
, // D&D dropping position in this->GetModel()
628 SvTreeListEntry
* pEntry
, // entry that we want to move, from
629 // GetSourceListBox()->GetModel()
630 SvTreeListEntry
*& rpNewParent
, // new target parent
631 sal_uLong
& rNewChildPos
) // position in childlist of target parent
633 return NotifyMoving(pTarget
,pEntry
,rpNewParent
,rNewChildPos
);
636 SvTreeListEntry
* SvTreeListBox::FirstChild( SvTreeListEntry
* pParent
) const
638 return pModel
->FirstChild(pParent
);
641 SvTreeListEntry
* SvTreeListBox::NextSibling( SvTreeListEntry
* pEntry
)
643 return SvTreeList::NextSibling(pEntry
);
646 SvTreeListEntry
* SvTreeListBox::PrevSibling( SvTreeListEntry
* pEntry
)
648 return SvTreeList::PrevSibling(pEntry
);
651 // return: all entries copied
652 bool SvTreeListBox::CopySelection( SvTreeListBox
* pSource
, SvTreeListEntry
* pTarget
)
654 nCurEntrySelPos
= 0; // selection counter for NotifyMoving/Copying
655 bool bSuccess
= true;
656 std::vector
<SvTreeListEntry
*> aList
;
657 bool bClone
= ( pSource
->GetModel() != GetModel() );
658 Link
<> aCloneLink( pModel
->GetCloneLink() );
659 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
661 // cache selection to simplify iterating over the selection when doing a D&D
662 // exchange within the same listbox
663 SvTreeListEntry
* pSourceEntry
= pSource
->FirstSelected();
664 while ( pSourceEntry
)
666 // children are copied automatically
667 pSource
->SelectChildren( pSourceEntry
, false );
668 aList
.push_back( pSourceEntry
);
669 pSourceEntry
= pSource
->NextSelected( pSourceEntry
);
672 std::vector
<SvTreeListEntry
*>::const_iterator it
= aList
.begin(), itEnd
= aList
.end();
673 for (; it
!= itEnd
; ++it
)
676 SvTreeListEntry
* pNewParent
= 0;
677 sal_uLong nInsertionPos
= TREELIST_APPEND
;
678 TriState nOk
= NotifyCopying(pTarget
,pSourceEntry
,pNewParent
,nInsertionPos
);
683 sal_uLong nCloneCount
= 0;
684 pSourceEntry
= pModel
->Clone(pSourceEntry
, nCloneCount
);
685 pModel
->InsertTree(pSourceEntry
, pNewParent
, nInsertionPos
);
689 sal_uLong nListPos
= pModel
->Copy(pSourceEntry
, pNewParent
, nInsertionPos
);
690 pSourceEntry
= GetEntry( pNewParent
, nListPos
);
696 if (nOk
== TRISTATE_INDET
) // HACK: make visible moved entry
697 MakeVisible( pSourceEntry
);
699 pModel
->SetCloneLink( aCloneLink
);
703 // return: all entries were moved
704 bool SvTreeListBox::MoveSelection( SvTreeListBox
* pSource
, SvTreeListEntry
* pTarget
)
706 return MoveSelectionCopyFallbackPossible( pSource
, pTarget
, false );
709 bool SvTreeListBox::MoveSelectionCopyFallbackPossible( SvTreeListBox
* pSource
, SvTreeListEntry
* pTarget
, bool bAllowCopyFallback
)
711 nCurEntrySelPos
= 0; // selection counter for NotifyMoving/Copying
712 bool bSuccess
= true;
713 std::vector
<SvTreeListEntry
*> aList
;
714 bool bClone
= ( pSource
->GetModel() != GetModel() );
715 Link
<> aCloneLink( pModel
->GetCloneLink() );
717 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
719 SvTreeListEntry
* pSourceEntry
= pSource
->FirstSelected();
720 while ( pSourceEntry
)
722 // children are automatically moved
723 pSource
->SelectChildren( pSourceEntry
, false );
724 aList
.push_back( pSourceEntry
);
725 pSourceEntry
= pSource
->NextSelected( pSourceEntry
);
728 std::vector
<SvTreeListEntry
*>::const_iterator it
= aList
.begin(), itEnd
= aList
.end();
729 for (; it
!= itEnd
; ++it
)
733 SvTreeListEntry
* pNewParent
= 0;
734 sal_uLong nInsertionPos
= TREELIST_APPEND
;
735 TriState nOk
= NotifyMoving(pTarget
,pSourceEntry
,pNewParent
,nInsertionPos
);
736 TriState nCopyOk
= nOk
;
737 if ( !nOk
&& bAllowCopyFallback
)
739 nInsertionPos
= TREELIST_APPEND
;
740 nCopyOk
= NotifyCopying(pTarget
,pSourceEntry
,pNewParent
,nInsertionPos
);
743 if ( nOk
|| nCopyOk
)
747 sal_uLong nCloneCount
= 0;
748 pSourceEntry
= pModel
->Clone(pSourceEntry
, nCloneCount
);
749 pModel
->InsertTree(pSourceEntry
, pNewParent
, nInsertionPos
);
754 pModel
->Move(pSourceEntry
, pNewParent
, nInsertionPos
);
756 pModel
->Copy(pSourceEntry
, pNewParent
, nInsertionPos
);
762 if (nOk
== TRISTATE_INDET
) // HACK: make moved entry visible
763 MakeVisible( pSourceEntry
);
765 pModel
->SetCloneLink( aCloneLink
);
769 void SvTreeListBox::RemoveSelection()
771 std::vector
<const SvTreeListEntry
*> aList
;
772 // cache selection, as the implementation deselects everything on the first
774 SvTreeListEntry
* pEntry
= FirstSelected();
777 aList
.push_back( pEntry
);
778 if ( pEntry
->HasChildren() )
779 // remove deletes all children automatically
780 SelectChildren(pEntry
, false);
781 pEntry
= NextSelected( pEntry
);
784 std::vector
<const SvTreeListEntry
*>::const_iterator it
= aList
.begin(), itEnd
= aList
.end();
785 for (; it
!= itEnd
; ++it
)
789 SvTreeListBox
* SvTreeListBox::GetSourceView()
794 void SvTreeListBox::RecalcViewData()
796 SvTreeListEntry
* pEntry
= First();
799 sal_uInt16 nCount
= pEntry
->ItemCount();
800 sal_uInt16 nCurPos
= 0;
801 while ( nCurPos
< nCount
)
803 SvLBoxItem
* pItem
= pEntry
->GetItem( nCurPos
);
804 pItem
->InitViewData( this, pEntry
);
807 pEntry
= Next( pEntry
);
811 void SvTreeListBox::ImplShowTargetEmphasis( SvTreeListEntry
* pEntry
, bool bShow
)
813 if ( bShow
&& (nImpFlags
& SvTreeListBoxFlags::TARGEMPH_VIS
) )
815 if ( !bShow
&& !(nImpFlags
& SvTreeListBoxFlags::TARGEMPH_VIS
) )
817 ShowTargetEmphasis( pEntry
, bShow
);
819 nImpFlags
|= SvTreeListBoxFlags::TARGEMPH_VIS
;
821 nImpFlags
&= ~SvTreeListBoxFlags::TARGEMPH_VIS
;
824 void SvTreeListBox::OnCurrentEntryChanged()
826 if ( !mpImpl
->m_bDoingQuickSelection
)
827 mpImpl
->m_aQuickSelectionEngine
.Reset();
830 SvTreeListEntry
* SvTreeListBox::GetEntry( SvTreeListEntry
* pParent
, sal_uLong nPos
) const
832 return pModel
->GetEntry(pParent
, nPos
);
835 SvTreeListEntry
* SvTreeListBox::GetEntry( sal_uLong nRootPos
) const
837 return pModel
->GetEntry(nRootPos
);
840 SvTreeListEntry
* SvTreeListBox::GetEntryFromPath( const ::std::deque
< sal_Int32
>& _rPath
) const
843 SvTreeListEntry
* pEntry
= NULL
;
844 SvTreeListEntry
* pParent
= NULL
;
845 for( ::std::deque
< sal_Int32
>::const_iterator pItem
= _rPath
.begin(); pItem
!= _rPath
.end(); ++pItem
)
847 pEntry
= GetEntry( pParent
, *pItem
);
856 void SvTreeListBox::FillEntryPath( SvTreeListEntry
* pEntry
, ::std::deque
< sal_Int32
>& _rPath
) const
861 SvTreeListEntry
* pParentEntry
= GetParent( pEntry
);
864 sal_uLong i
, nCount
= GetLevelChildCount( pParentEntry
);
865 for ( i
= 0; i
< nCount
; ++i
)
867 SvTreeListEntry
* pTemp
= GetEntry( pParentEntry
, i
);
868 DBG_ASSERT( pEntry
, "invalid entry" );
869 if ( pEntry
== pTemp
)
871 _rPath
.push_front( (sal_Int32
)i
);
878 pEntry
= pParentEntry
;
879 pParentEntry
= GetParent( pParentEntry
);
887 const SvTreeListEntry
* SvTreeListBox::GetParent( const SvTreeListEntry
* pEntry
) const
889 return pModel
->GetParent(pEntry
);
892 SvTreeListEntry
* SvTreeListBox::GetParent( SvTreeListEntry
* pEntry
) const
894 return pModel
->GetParent(pEntry
);
897 SvTreeListEntry
* SvTreeListBox::GetRootLevelParent( SvTreeListEntry
* pEntry
) const
899 return pModel
->GetRootLevelParent(pEntry
);
902 sal_uLong
SvTreeListBox::GetChildCount( SvTreeListEntry
* pParent
) const
904 return pModel
->GetChildCount(pParent
);
907 sal_uLong
SvTreeListBox::GetLevelChildCount( SvTreeListEntry
* _pParent
) const
910 //if _pParent is 0, then pEntry is the first child of the root.
911 SvTreeListEntry
* pEntry
= FirstChild( _pParent
);
913 if( !pEntry
)//there is only root, root don't have children
916 if( !_pParent
)//root and children of root
917 return pEntry
->pParent
->maChildren
.size();
919 return _pParent
->maChildren
.size();
922 SvViewDataEntry
* SvTreeListBox::GetViewDataEntry( SvTreeListEntry
* pEntry
) const
924 return const_cast<SvViewDataEntry
*>(SvListView::GetViewData(pEntry
));
927 SvViewDataItem
* SvTreeListBox::GetViewDataItem(SvTreeListEntry
* pEntry
, SvLBoxItem
* pItem
)
929 return const_cast<SvViewDataItem
*>(static_cast<const SvTreeListBox
*>(this)->GetViewDataItem(pEntry
, pItem
));
932 const SvViewDataItem
* SvTreeListBox::GetViewDataItem(const SvTreeListEntry
* pEntry
, const SvLBoxItem
* pItem
) const
934 const SvViewDataEntry
* pEntryData
= SvListView::GetViewData(pEntry
);
935 DBG_ASSERT(pEntryData
,"Entry not in View");
936 sal_uInt16 nItemPos
= pEntry
->GetPos(pItem
);
937 return pEntryData
->GetItem(nItemPos
);
940 SvViewDataEntry
* SvTreeListBox::CreateViewData( SvTreeListEntry
* )
942 SvViewDataEntry
* pEntryData
= new SvViewDataEntry
;
946 void SvTreeListBox::InitViewData( SvViewDataEntry
* pData
, SvTreeListEntry
* pEntry
)
948 SvTreeListEntry
* pInhEntry
= pEntry
;
949 SvViewDataEntry
* pEntryData
= pData
;
951 pEntryData
->Init(pInhEntry
->ItemCount());
952 sal_uInt16 nCount
= pInhEntry
->ItemCount();
953 sal_uInt16 nCurPos
= 0;
954 while( nCurPos
< nCount
)
956 SvLBoxItem
* pItem
= pInhEntry
->GetItem( nCurPos
);
957 SvViewDataItem
* pItemData
= pEntryData
->GetItem(nCurPos
);
958 pItem
->InitViewData( this, pInhEntry
, pItemData
);
964 void SvTreeListBox::EnableSelectionAsDropTarget( bool bEnable
, bool bWithChildren
)
966 sal_uInt16 nRefDepth
;
967 SvTreeListEntry
* pTemp
;
969 SvTreeListEntry
* pSelEntry
= FirstSelected();
974 pSelEntry
->nEntryFlags
|= SvTLEntryFlags::DISABLE_DROP
;
977 nRefDepth
= pModel
->GetDepth( pSelEntry
);
978 pTemp
= Next( pSelEntry
);
979 while( pTemp
&& pModel
->GetDepth( pTemp
) > nRefDepth
)
981 pTemp
->nEntryFlags
|= SvTLEntryFlags::DISABLE_DROP
;
982 pTemp
= Next( pTemp
);
988 pSelEntry
->nEntryFlags
&= (~SvTLEntryFlags::DISABLE_DROP
);
991 nRefDepth
= pModel
->GetDepth( pSelEntry
);
992 pTemp
= Next( pSelEntry
);
993 while( pTemp
&& pModel
->GetDepth( pTemp
) > nRefDepth
)
995 pTemp
->nEntryFlags
&= (~SvTLEntryFlags::DISABLE_DROP
);
996 pTemp
= Next( pTemp
);
1000 pSelEntry
= NextSelected( pSelEntry
);
1004 // ******************************************************************
1006 // ******************************************************************
1008 void SvTreeListBox::EditText( const OUString
& rStr
, const Rectangle
& rRect
,
1009 const Selection
& rSel
)
1011 EditText( rStr
, rRect
, rSel
, false );
1014 void SvTreeListBox::EditText( const OUString
& rStr
, const Rectangle
& rRect
,
1015 const Selection
& rSel
, bool bMulti
)
1019 nImpFlags
|= SvTreeListBoxFlags::IN_EDT
;
1020 nImpFlags
&= ~SvTreeListBoxFlags::EDTEND_CALLED
;
1022 pEdCtrl
= new SvInplaceEdit2(
1023 this, rRect
.TopLeft(), rRect
.GetSize(), rStr
,
1024 LINK( this, SvTreeListBox
, TextEditEndedHdl_Impl
),
1028 IMPL_LINK_NOARG(SvTreeListBox
, TextEditEndedHdl_Impl
)
1030 if ( nImpFlags
& SvTreeListBoxFlags::EDTEND_CALLED
) // avoid nesting
1032 nImpFlags
|= SvTreeListBoxFlags::EDTEND_CALLED
;
1034 if ( !pEdCtrl
->EditingCanceled() )
1035 aStr
= pEdCtrl
->GetText();
1037 aStr
= pEdCtrl
->GetSavedValue();
1038 if ( IsEmptyTextAllowed() || !aStr
.isEmpty() )
1040 // Hide may only be called after the new text was put into the entry, so
1041 // that we don't call the selection handler in the GetFocus of the listbox
1042 // with the old entry text.
1046 nImpFlags
&= (~SvTreeListBoxFlags::IN_EDT
);
1051 void SvTreeListBox::CancelTextEditing()
1054 pEdCtrl
->StopEditing( true );
1055 nImpFlags
&= (~SvTreeListBoxFlags::IN_EDT
);
1058 void SvTreeListBox::EndEditing( bool bCancel
)
1061 pEdCtrl
->StopEditing( bCancel
);
1062 nImpFlags
&= (~SvTreeListBoxFlags::IN_EDT
);
1066 bool SvTreeListBox::IsEmptyTextAllowed() const
1068 return mpImpl
->m_bIsEmptyTextAllowed
;
1071 void SvTreeListBox::ForbidEmptyText()
1073 mpImpl
->m_bIsEmptyTextAllowed
= false;
1076 SvTreeListEntry
* SvTreeListBox::CreateEntry() const
1078 return new SvTreeListEntry
;
1081 const void* SvTreeListBox::FirstSearchEntry( OUString
& _rEntryText
) const
1083 SvTreeListEntry
* pEntry
= GetCurEntry();
1085 pEntry
= const_cast< SvTreeListEntry
* >( static_cast< const SvTreeListEntry
* >( NextSearchEntry( pEntry
, _rEntryText
) ) );
1088 pEntry
= FirstSelected();
1094 _rEntryText
= GetEntryText( pEntry
);
1099 const void* SvTreeListBox::NextSearchEntry( const void* _pCurrentSearchEntry
, OUString
& _rEntryText
) const
1101 SvTreeListEntry
* pEntry
= const_cast< SvTreeListEntry
* >( static_cast< const SvTreeListEntry
* >( _pCurrentSearchEntry
) );
1103 if ( ( ( GetChildCount( pEntry
) > 0 )
1104 || ( pEntry
->HasChildrenOnDemand() )
1106 && !IsExpanded( pEntry
)
1109 pEntry
= NextSibling( pEntry
);
1113 pEntry
= Next( pEntry
);
1120 _rEntryText
= GetEntryText( pEntry
);
1125 void SvTreeListBox::SelectSearchEntry( const void* _pEntry
)
1127 SvTreeListEntry
* pEntry
= const_cast< SvTreeListEntry
* >( static_cast< const SvTreeListEntry
* >( _pEntry
) );
1128 DBG_ASSERT( pEntry
, "SvTreeListBox::SelectSearchEntry: invalid entry!" );
1133 SetCurEntry( pEntry
);
1137 void SvTreeListBox::ExecuteSearchEntry( const void* /*_pEntry*/ ) const
1139 // nothing to do here, we have no "execution"
1142 vcl::StringEntryIdentifier
SvTreeListBox::CurrentEntry( OUString
& _out_entryText
) const
1144 // always accept the current entry if there is one
1145 SvTreeListEntry
* pCurrentEntry( GetCurEntry() );
1146 if ( pCurrentEntry
)
1148 _out_entryText
= GetEntryText( pCurrentEntry
);
1149 return pCurrentEntry
;
1151 return FirstSearchEntry( _out_entryText
);
1154 vcl::StringEntryIdentifier
SvTreeListBox::NextEntry( vcl::StringEntryIdentifier _currentEntry
, OUString
& _out_entryText
) const
1156 return NextSearchEntry( _currentEntry
, _out_entryText
);
1159 void SvTreeListBox::SelectEntry( vcl::StringEntryIdentifier _entry
)
1161 SelectSearchEntry( _entry
);
1164 bool SvTreeListBox::HandleKeyInput( const KeyEvent
& _rKEvt
)
1166 if ( IsEntryMnemonicsEnabled()
1167 && mpImpl
->m_aMnemonicEngine
.HandleKeyEvent( _rKEvt
)
1171 if ( ( GetStyle() & WB_QUICK_SEARCH
) != 0 )
1173 mpImpl
->m_bDoingQuickSelection
= true;
1174 const bool bHandled
= mpImpl
->m_aQuickSelectionEngine
.HandleKeyEvent( _rKEvt
);
1175 mpImpl
->m_bDoingQuickSelection
= false;
1183 bool SvTreeListBox::EditingCanceled() const
1185 if( pEdCtrl
&& pEdCtrl
->EditingCanceled() )
1191 //JP 28.3.2001: new Drag & Drop API
1192 sal_Int8
SvTreeListBox::AcceptDrop( const AcceptDropEvent
& rEvt
)
1194 sal_Int8 nRet
= DND_ACTION_NONE
;
1196 if( rEvt
.mbLeaving
|| !CheckDragAndDropMode( pDDSource
, rEvt
.mnAction
) )
1198 ImplShowTargetEmphasis( pTargetEntry
, false );
1200 else if( nDragDropMode
== DragDropMode::NONE
)
1202 SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no target" );
1206 SvTreeListEntry
* pEntry
= GetDropTarget( rEvt
.maPosPixel
);
1207 if( !IsDropFormatSupported( SotClipboardFormatId::TREELISTBOX
) )
1209 SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no format" );
1213 DBG_ASSERT( pDDSource
, "SvTreeListBox::QueryDrop(): SourceBox == 0" );
1214 if( !( pEntry
&& pDDSource
->GetModel() == this->GetModel()
1215 && DND_ACTION_MOVE
== rEvt
.mnAction
1216 && ( pEntry
->nEntryFlags
& SvTLEntryFlags::DISABLE_DROP
) ))
1218 if( NotifyAcceptDrop( pEntry
))
1219 nRet
= rEvt
.mnAction
;
1223 // **** draw emphasis ****
1224 if( DND_ACTION_NONE
== nRet
)
1225 ImplShowTargetEmphasis( pTargetEntry
, false );
1226 else if( pEntry
!= pTargetEntry
|| !(nImpFlags
& SvTreeListBoxFlags::TARGEMPH_VIS
) )
1228 ImplShowTargetEmphasis( pTargetEntry
, false );
1229 pTargetEntry
= pEntry
;
1230 ImplShowTargetEmphasis( pTargetEntry
, true );
1236 sal_Int8
SvTreeListBox::ExecuteDrop( const ExecuteDropEvent
& rEvt
, SvTreeListBox
* pSourceView
)
1238 DBG_ASSERT( pSourceView
, "SvTreeListBox::ExecuteDrop(): no source view" );
1239 pSourceView
->EnableSelectionAsDropTarget( true, true );
1241 ImplShowTargetEmphasis( pTargetEntry
, false );
1244 TransferableDataHelper
aData( rEvt
.maDropEvent
.Transferable
);
1247 if( aData
.HasFormat( SotClipboardFormatId::TREELISTBOX
))
1248 nRet
= rEvt
.mnAction
;
1250 nRet
= DND_ACTION_NONE
;
1252 if( DND_ACTION_NONE
!= nRet
)
1254 nRet
= DND_ACTION_NONE
;
1256 SvTreeListEntry
* pTarget
= pTargetEntry
; // may be 0!
1258 if( DND_ACTION_COPY
== rEvt
.mnAction
)
1260 if ( CopySelection( pDDSource
, pTarget
) )
1261 nRet
= rEvt
.mnAction
;
1263 else if( DND_ACTION_MOVE
== rEvt
.mnAction
)
1265 if ( MoveSelection( pDDSource
, pTarget
) )
1266 nRet
= rEvt
.mnAction
;
1268 else if( DND_ACTION_COPYMOVE
== rEvt
.mnAction
)
1270 if ( MoveSelectionCopyFallbackPossible( pDDSource
, pTarget
, true ) )
1271 nRet
= rEvt
.mnAction
;
1277 sal_Int8
SvTreeListBox::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
1279 return ExecuteDrop( rEvt
, GetSourceView() );
1283 * This sets the global variables used to determine the
1284 * in-process drag source.
1286 void SvTreeListBox::SetupDragOrigin()
1292 void SvTreeListBox::StartDrag( sal_Int8
, const Point
& rPosPixel
)
1295 Point
aEventPos( rPosPixel
);
1296 MouseEvent
aMouseEvt( aEventPos
, 1, MouseEventModifiers::SELECT
, MOUSE_LEFT
);
1297 MouseButtonUp( aMouseEvt
);
1299 nOldDragMode
= GetDragDropMode();
1300 if ( nOldDragMode
== DragDropMode::NONE
)
1305 SvTreeListEntry
* pEntry
= GetEntry( rPosPixel
); // GetDropTarget( rPos );
1308 DragFinished( DND_ACTION_NONE
);
1312 TransferDataContainer
* pContainer
= new TransferDataContainer
;
1313 ::com::sun::star::uno::Reference
<
1314 ::com::sun::star::datatransfer::XTransferable
> xRef( pContainer
);
1315 nDragDropMode
= NotifyStartDrag( *pContainer
, pEntry
);
1316 if( nDragDropMode
== DragDropMode::NONE
|| 0 == GetSelectionCount() )
1318 nDragDropMode
= nOldDragMode
;
1319 DragFinished( DND_ACTION_NONE
);
1326 // apparently some (unused) content is needed
1327 pContainer
->CopyAnyData( SotClipboardFormatId::TREELISTBOX
,
1328 "unused", SAL_N_ELEMENTS("unused") );
1330 bool bOldUpdateMode
= Control::IsUpdateMode();
1331 Control::SetUpdateMode( true );
1333 Control::SetUpdateMode( bOldUpdateMode
);
1335 // Disallow using the selection and its children as drop targets.
1336 // Important: If the selection of the SourceListBox is changed in the
1337 // DropHandler, the entries have to be allowed as drop targets again:
1338 // (GetSourceListBox()->EnableSelectionAsDropTarget( true, true );)
1339 EnableSelectionAsDropTarget( false, true /* with children */ );
1341 pContainer
->StartDrag( this, nDragOptions
, GetDragFinishedHdl() );
1344 void SvTreeListBox::DragFinished( sal_Int8
1350 EnableSelectionAsDropTarget( true, true );
1353 if( (nAction
== DND_ACTION_MOVE
) && ( (pDDTarget
&&
1354 ((sal_uLong
)(pDDTarget
->GetModel())!=(sal_uLong
)(this->GetModel()))) ||
1361 ImplShowTargetEmphasis( pTargetEntry
, false );
1365 nDragDropMode
= nOldDragMode
;
1368 DragDropMode
SvTreeListBox::NotifyStartDrag( TransferDataContainer
&, SvTreeListEntry
* )
1370 return (DragDropMode
)0xffff;
1373 bool SvTreeListBox::NotifyAcceptDrop( SvTreeListEntry
* )
1378 // Handler and methods for Drag - finished handler.
1379 // The with get GetDragFinishedHdl() get link can set on the
1380 // TransferDataContainer. This link is a callback for the DragFinished
1381 // call. AddBox method is called from the GetDragFinishedHdl() and the
1382 // remove is called in link callback and in the destructor. So it can't
1383 // called to a deleted object.
1387 struct SortLBoxes
: public rtl::Static
<std::set
<sal_uLong
>, SortLBoxes
> {};
1390 void SvTreeListBox::AddBoxToDDList_Impl( const SvTreeListBox
& rB
)
1392 sal_uLong nVal
= reinterpret_cast<sal_uLong
>(&rB
);
1393 SortLBoxes::get().insert( nVal
);
1396 void SvTreeListBox::RemoveBoxFromDDList_Impl( const SvTreeListBox
& rB
)
1398 sal_uLong nVal
= reinterpret_cast<sal_uLong
>(&rB
);
1399 SortLBoxes::get().erase( nVal
);
1402 IMPL_LINK( SvTreeListBox
, DragFinishHdl_Impl
, sal_Int8
*, pAction
)
1404 sal_uLong nVal
= reinterpret_cast<sal_uLong
>(this);
1405 std::set
<sal_uLong
> &rSortLBoxes
= SortLBoxes::get();
1406 std::set
<sal_uLong
>::const_iterator it
= rSortLBoxes
.find(nVal
);
1407 if( it
!= rSortLBoxes
.end() )
1409 DragFinished( *pAction
);
1410 rSortLBoxes
.erase( it
);
1415 Link
<> SvTreeListBox::GetDragFinishedHdl() const
1417 AddBoxToDDList_Impl( *this );
1418 return LINK( const_cast<SvTreeListBox
*>(this), SvTreeListBox
, DragFinishHdl_Impl
);
1424 - calculate rectangle when editing in-place (bug with some fonts)
1425 - SetSpaceBetweenEntries: offset is not taken into account in SetEntryHeight
1428 #define SV_LBOX_DEFAULT_INDENT_PIXEL 20
1430 void SvTreeListBox::InitTreeView()
1432 pCheckButtonData
= NULL
;
1440 nAllItemAccRoleType
= SvTreeAccRoleType::NONE
;
1441 mnCheckboxItemWidth
= 0;
1443 Link
<>* pLink
= new Link
<>( LINK(this,SvTreeListBox
, DefaultCompare
) );
1444 mpImpl
->m_pLink
= pLink
;
1446 nTreeFlags
= SvTreeFlags::RECALCTABS
;
1447 nIndent
= SV_LBOX_DEFAULT_INDENT_PIXEL
;
1448 nEntryHeightOffs
= SV_ENTRYHEIGHTOFFS_PIXEL
;
1449 pImp
= new SvImpLBox( this, GetModel(), GetStyle() );
1451 mbContextBmpExpanded
= true;
1452 nContextBmpWidthMax
= 0;
1454 SetFont( GetFont() );
1455 AdjustEntryHeightAndRecalc( GetFont() );
1457 SetSpaceBetweenEntries( 0 );
1459 InitSettings( true, true, true );
1464 OUString
SvTreeListBox::GetEntryAltText( SvTreeListEntry
* ) const
1469 OUString
SvTreeListBox::GetEntryLongDescription( SvTreeListEntry
* ) const
1474 OUString
SvTreeListBox::SearchEntryTextWithHeadTitle( SvTreeListEntry
* pEntry
)
1476 DBG_ASSERT( pEntry
, "SvTreeListBox::SearchEntryText(): no entry" );
1479 sal_uInt16 nCount
= pEntry
->ItemCount();
1480 sal_uInt16 nCur
= 0;
1481 sal_uInt16 nHeaderCur
= 0;
1482 while( nCur
< nCount
)
1484 // MT: SV_ITEM_ID_EXTENDRLBOXSTRING / GetExtendText() was in use in IA2 cws, but only used in sc: ScSolverOptionsString. Needed?
1485 SvLBoxItem
* pItem
= pEntry
->GetItem( nCur
);
1486 if ( (pItem
->GetType() == SV_ITEM_ID_LBOXSTRING
) &&
1487 !static_cast<SvLBoxString
*>( pItem
)->GetText().isEmpty() )
1489 //want the column header
1490 if (!headString
.isEmpty())
1492 sal_Int32 nEnd
= headString
.indexOf('\t');
1495 if (!sRet
.isEmpty())
1499 if (!headString
.isEmpty())
1501 sRet
+= headString
;
1507 OUString aString
=headString
.getToken(nHeaderCur
, '\t');
1508 if (!sRet
.isEmpty())
1512 if (!aString
.isEmpty())
1519 sRet
+= static_cast<SvLBoxString
*>( pItem
)->GetText();
1523 sRet
+= static_cast<SvLBoxString
*>( pItem
)->GetText();
1526 //end want to the column header
1531 if (!sRet
.isEmpty())
1532 sRet
= sRet
.copy(0, sRet
.getLength() - 1);
1536 SvTreeListBox::~SvTreeListBox()
1541 void SvTreeListBox::dispose()
1545 pImp
->CallEventListeners( VCLEVENT_OBJECT_DYING
);
1551 delete mpImpl
->m_pLink
;
1552 mpImpl
->m_pLink
= NULL
;
1561 pModel
->RemoveView( this );
1562 if ( pModel
->GetRefCount() == 0 )
1570 SvTreeListBox::RemoveBoxFromDDList_Impl( *this );
1572 if( this == pDDSource
)
1574 if( this == pDDTarget
)
1583 void SvTreeListBox::SetExtendedWinBits( ExtendedWinBits _nBits
)
1585 pImp
->SetExtendedWindowBits( _nBits
);
1588 void SvTreeListBox::SetModel( SvTreeList
* pNewModel
)
1590 pImp
->SetModel( pNewModel
);
1591 SetBaseModel(pNewModel
);
1594 void SvTreeListBox::SetBaseModel( SvTreeList
* pNewModel
)
1597 SvListView::SetModel( pNewModel
);
1598 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
1599 SvTreeListEntry
* pEntry
= First();
1602 ModelHasInserted( pEntry
);
1603 pEntry
= Next( pEntry
);
1607 void SvTreeListBox::DisconnectFromModel()
1609 SvTreeList
* pNewModel
= new SvTreeList
;
1610 pNewModel
->SetRefCount( 0 ); // else this will never be deleted
1611 SvListView::SetModel( pNewModel
);
1613 pImp
->SetModel( GetModel() );
1616 void SvTreeListBox::SetSublistOpenWithReturn( bool b
)
1618 pImp
->bSubLstOpRet
= b
;
1621 void SvTreeListBox::SetSublistOpenWithLeftRight( bool b
)
1623 pImp
->bSubLstOpLR
= b
;
1626 void SvTreeListBox::Resize()
1628 if( IsEditingActive() )
1635 pImp
->ShowCursor( false );
1636 pImp
->ShowCursor( true );
1641 A) entries have bitmaps
1643 1. node buttons (can optionally also be on root items)
1644 2. node buttons (can optionally also be on root items) + CheckButton
1646 B) entries don't have bitmaps (=>via WindowBits because of D&D!)
1648 1. node buttons (can optionally also be on root items)
1649 2. node buttons (can optionally also be on root items) + CheckButton
1653 #define NO_BUTTONS 0
1654 #define NODE_BUTTONS 1
1655 #define NODE_AND_CHECK_BUTTONS 2
1656 #define CHECK_BUTTONS 3
1658 #define TABFLAGS_TEXT (SvLBoxTabFlags::DYNAMIC | \
1659 SvLBoxTabFlags::ADJUST_LEFT | \
1660 SvLBoxTabFlags::EDITABLE | \
1661 SvLBoxTabFlags::SHOW_SELECTION)
1663 #define TABFLAGS_CONTEXTBMP (SvLBoxTabFlags::DYNAMIC | SvLBoxTabFlags::ADJUST_CENTER)
1665 #define TABFLAGS_CHECKBTN (SvLBoxTabFlags::DYNAMIC | \
1666 SvLBoxTabFlags::ADJUST_CENTER | \
1667 SvLBoxTabFlags::PUSHABLE)
1669 #define TAB_STARTPOS 2
1671 // take care of GetTextOffset when doing changes
1672 void SvTreeListBox::SetTabs()
1674 if( IsEditingActive() )
1676 nTreeFlags
&= (~SvTreeFlags::RECALCTABS
);
1678 const WinBits
nStyle( GetStyle() );
1679 bool bHasButtons
= (nStyle
& WB_HASBUTTONS
)!=0;
1680 bool bHasButtonsAtRoot
= (nStyle
& (WB_HASLINESATROOT
|
1681 WB_HASBUTTONSATROOT
))!=0;
1682 long nStartPos
= TAB_STARTPOS
;
1683 long nNodeWidthPixel
= GetExpandedNodeBmp().GetSizePixel().Width();
1685 // pCheckButtonData->Width() knows nothing about the native checkbox width,
1686 // so we have mnCheckboxItemWidth which becomes valid when something is added.
1687 long nCheckWidth
= 0;
1688 if( nTreeFlags
& SvTreeFlags::CHKBTN
)
1689 nCheckWidth
= mnCheckboxItemWidth
;
1690 long nCheckWidthDIV2
= nCheckWidth
/ 2;
1692 long nContextWidth
= nContextBmpWidthMax
;
1693 long nContextWidthDIV2
= nContextWidth
/ 2;
1697 int nCase
= NO_BUTTONS
;
1698 if( !(nTreeFlags
& SvTreeFlags::CHKBTN
) )
1701 nCase
= NODE_BUTTONS
;
1706 nCase
= NODE_AND_CHECK_BUTTONS
;
1708 nCase
= CHECK_BUTTONS
;
1714 nStartPos
+= nContextWidthDIV2
; // because of centering
1715 AddTab( nStartPos
, TABFLAGS_CONTEXTBMP
);
1716 nStartPos
+= nContextWidthDIV2
; // right edge of context bitmap
1717 // only set a distance if there are bitmaps
1718 if( nContextBmpWidthMax
)
1719 nStartPos
+= 5; // distance context bitmap to text
1720 AddTab( nStartPos
, TABFLAGS_TEXT
);
1724 if( bHasButtonsAtRoot
)
1725 nStartPos
+= ( nIndent
+ (nNodeWidthPixel
/2) );
1727 nStartPos
+= nContextWidthDIV2
;
1728 AddTab( nStartPos
, TABFLAGS_CONTEXTBMP
);
1729 nStartPos
+= nContextWidthDIV2
; // right edge of context bitmap
1730 // only set a distance if there are bitmaps
1731 if( nContextBmpWidthMax
)
1732 nStartPos
+= 5; // distance context bitmap to text
1733 AddTab( nStartPos
, TABFLAGS_TEXT
);
1736 case NODE_AND_CHECK_BUTTONS
:
1737 if( bHasButtonsAtRoot
)
1738 nStartPos
+= ( nIndent
+ nNodeWidthPixel
);
1740 nStartPos
+= nCheckWidthDIV2
;
1741 AddTab( nStartPos
, TABFLAGS_CHECKBTN
);
1742 nStartPos
+= nCheckWidthDIV2
; // right edge of CheckButton
1743 nStartPos
+= 3; // distance CheckButton to context bitmap
1744 nStartPos
+= nContextWidthDIV2
; // center of context bitmap
1745 AddTab( nStartPos
, TABFLAGS_CONTEXTBMP
);
1746 nStartPos
+= nContextWidthDIV2
; // right edge of context bitmap
1747 // only set a distance if there are bitmaps
1748 if( nContextBmpWidthMax
)
1749 nStartPos
+= 5; // distance context bitmap to text
1750 AddTab( nStartPos
, TABFLAGS_TEXT
);
1753 case CHECK_BUTTONS
:
1754 nStartPos
+= nCheckWidthDIV2
;
1755 AddTab( nStartPos
, TABFLAGS_CHECKBTN
);
1756 nStartPos
+= nCheckWidthDIV2
; // right edge of CheckButton
1757 nStartPos
+= 3; // distance CheckButton to context bitmap
1758 nStartPos
+= nContextWidthDIV2
; // center of context bitmap
1759 AddTab( nStartPos
, TABFLAGS_CONTEXTBMP
);
1760 nStartPos
+= nContextWidthDIV2
; // right edge of context bitmap
1761 // only set a distance if there are bitmaps
1762 if( nContextBmpWidthMax
)
1763 nStartPos
+= 5; // distance context bitmap to text
1764 AddTab( nStartPos
, TABFLAGS_TEXT
);
1767 pImp
->NotifyTabsChanged();
1770 void SvTreeListBox::InitEntry(SvTreeListEntry
* pEntry
,
1771 const OUString
& aStr
, const Image
& aCollEntryBmp
, const Image
& aExpEntryBmp
,
1772 SvLBoxButtonKind eButtonKind
)
1774 SvLBoxString
* pString
;
1775 SvLBoxContextBmp
* pContextBmp
;
1777 if( nTreeFlags
& SvTreeFlags::CHKBTN
)
1779 SvLBoxButton
* pButton
= new SvLBoxButton( pEntry
,eButtonKind
,0,pCheckButtonData
);
1780 pEntry
->AddItem( pButton
);
1783 pContextBmp
= new SvLBoxContextBmp(
1784 pEntry
,0, aCollEntryBmp
,aExpEntryBmp
, mbContextBmpExpanded
);
1785 pEntry
->AddItem( pContextBmp
);
1787 pString
= new SvLBoxString( pEntry
, 0, aStr
);
1788 pEntry
->AddItem( pString
);
1791 OUString
SvTreeListBox::GetEntryText(SvTreeListEntry
* pEntry
) const
1793 DBG_ASSERT( pEntry
, "SvTreeListBox::GetEntryText(): no entry" );
1794 SvLBoxString
* pItem
= static_cast<SvLBoxString
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
1795 DBG_ASSERT( pEntry
, "SvTreeListBox::GetEntryText(): item not found" );
1796 return pItem
->GetText();
1799 const Image
& SvTreeListBox::GetExpandedEntryBmp(const SvTreeListEntry
* pEntry
)
1801 DBG_ASSERT(pEntry
,"Entry?");
1802 const SvLBoxContextBmp
* pItem
= static_cast<const SvLBoxContextBmp
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
1803 DBG_ASSERT(pItem
,"GetContextBmp:Item not found");
1804 return pItem
->GetBitmap2( );
1807 const Image
& SvTreeListBox::GetCollapsedEntryBmp( const SvTreeListEntry
* pEntry
)
1809 DBG_ASSERT(pEntry
,"Entry?");
1810 const SvLBoxContextBmp
* pItem
= static_cast<const SvLBoxContextBmp
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
1811 DBG_ASSERT(pItem
,"GetContextBmp:Item not found");
1812 return pItem
->GetBitmap1( );
1815 IMPL_LINK( SvTreeListBox
, CheckButtonClick
, SvLBoxButtonData
*, pData
)
1817 pHdlEntry
= pData
->GetActEntry();
1822 SvTreeListEntry
* SvTreeListBox::InsertEntry(
1823 const OUString
& rText
,
1824 SvTreeListEntry
* pParent
,
1825 bool bChildrenOnDemand
, sal_uLong nPos
,
1827 SvLBoxButtonKind eButtonKind
1830 nTreeFlags
|= SvTreeFlags::MANINS
;
1832 const Image
& rDefExpBmp
= pImp
->GetDefaultEntryExpBmp( );
1833 const Image
& rDefColBmp
= pImp
->GetDefaultEntryColBmp( );
1835 aCurInsertedExpBmp
= rDefExpBmp
;
1836 aCurInsertedColBmp
= rDefColBmp
;
1838 SvTreeListEntry
* pEntry
= CreateEntry();
1839 pEntry
->SetUserData( pUser
);
1840 InitEntry( pEntry
, rText
, rDefColBmp
, rDefExpBmp
, eButtonKind
);
1841 pEntry
->EnableChildrenOnDemand( bChildrenOnDemand
);
1844 Insert( pEntry
, nPos
);
1846 Insert( pEntry
, pParent
, nPos
);
1848 aPrevInsertedExpBmp
= rDefExpBmp
;
1849 aPrevInsertedColBmp
= rDefColBmp
;
1851 nTreeFlags
&= (~SvTreeFlags::MANINS
);
1856 SvTreeListEntry
* SvTreeListBox::InsertEntry( const OUString
& rText
,
1857 const Image
& aExpEntryBmp
, const Image
& aCollEntryBmp
,
1858 SvTreeListEntry
* pParent
, bool bChildrenOnDemand
, sal_uLong nPos
, void* pUser
,
1859 SvLBoxButtonKind eButtonKind
)
1861 nTreeFlags
|= SvTreeFlags::MANINS
;
1863 aCurInsertedExpBmp
= aExpEntryBmp
;
1864 aCurInsertedColBmp
= aCollEntryBmp
;
1866 SvTreeListEntry
* pEntry
= CreateEntry();
1867 pEntry
->SetUserData( pUser
);
1868 InitEntry( pEntry
, rText
, aCollEntryBmp
, aExpEntryBmp
, eButtonKind
);
1870 pEntry
->EnableChildrenOnDemand( bChildrenOnDemand
);
1873 Insert( pEntry
, nPos
);
1875 Insert( pEntry
, pParent
, nPos
);
1877 aPrevInsertedExpBmp
= aExpEntryBmp
;
1878 aPrevInsertedColBmp
= aCollEntryBmp
;
1880 nTreeFlags
&= (~SvTreeFlags::MANINS
);
1885 void SvTreeListBox::SetEntryText(SvTreeListEntry
* pEntry
, const OUString
& rStr
)
1887 SvLBoxString
* pItem
= static_cast<SvLBoxString
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
1888 DBG_ASSERT(pItem
,"SetText:Item not found");
1889 pItem
->SetText(rStr
);
1890 pItem
->InitViewData( this, pEntry
, 0 );
1891 GetModel()->InvalidateEntry( pEntry
);
1894 void SvTreeListBox::SetExpandedEntryBmp( SvTreeListEntry
* pEntry
, const Image
& aBmp
)
1896 SvLBoxContextBmp
* pItem
= static_cast<SvLBoxContextBmp
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
1898 DBG_ASSERT(pItem
,"SetExpBmp:Item not found");
1899 pItem
->SetBitmap2( aBmp
);
1901 GetModel()->InvalidateEntry( pEntry
);
1902 SetEntryHeight( pEntry
);
1903 Size aSize
= aBmp
.GetSizePixel();
1904 short nWidth
= pImp
->UpdateContextBmpWidthVector( pEntry
, (short)aSize
.Width() );
1905 if( nWidth
> nContextBmpWidthMax
)
1907 nContextBmpWidthMax
= nWidth
;
1912 void SvTreeListBox::SetCollapsedEntryBmp(SvTreeListEntry
* pEntry
,const Image
& aBmp
)
1914 SvLBoxContextBmp
* pItem
= static_cast<SvLBoxContextBmp
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
1916 DBG_ASSERT(pItem
,"SetExpBmp:Item not found");
1917 pItem
->SetBitmap1( aBmp
);
1919 GetModel()->InvalidateEntry( pEntry
);
1920 SetEntryHeight( pEntry
);
1921 Size aSize
= aBmp
.GetSizePixel();
1922 short nWidth
= pImp
->UpdateContextBmpWidthVector( pEntry
, (short)aSize
.Width() );
1923 if( nWidth
> nContextBmpWidthMax
)
1925 nContextBmpWidthMax
= nWidth
;
1930 void SvTreeListBox::ImpEntryInserted( SvTreeListEntry
* pEntry
)
1933 SvTreeListEntry
* pParent
= pModel
->GetParent( pEntry
);
1936 SvTLEntryFlags nFlags
= pParent
->GetFlags();
1937 nFlags
&= ~SvTLEntryFlags::NO_NODEBMP
;
1938 pParent
->SetFlags( nFlags
);
1941 if(!((nTreeFlags
& SvTreeFlags::MANINS
) &&
1942 (aPrevInsertedExpBmp
== aCurInsertedExpBmp
) &&
1943 (aPrevInsertedColBmp
== aCurInsertedColBmp
) ))
1945 Size aSize
= GetCollapsedEntryBmp( pEntry
).GetSizePixel();
1946 if( aSize
.Width() > nContextBmpWidthMax
)
1948 nContextBmpWidthMax
= (short)aSize
.Width();
1949 nTreeFlags
|= SvTreeFlags::RECALCTABS
;
1951 aSize
= GetExpandedEntryBmp( pEntry
).GetSizePixel();
1952 if( aSize
.Width() > nContextBmpWidthMax
)
1954 nContextBmpWidthMax
= (short)aSize
.Width();
1955 nTreeFlags
|= SvTreeFlags::RECALCTABS
;
1958 SetEntryHeight( pEntry
);
1960 if( nTreeFlags
& SvTreeFlags::CHKBTN
)
1962 SvLBoxButton
* pItem
= static_cast<SvLBoxButton
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
1965 long nWidth
= pItem
->GetSize(this, pEntry
).Width();
1966 if( mnCheckboxItemWidth
< nWidth
)
1968 mnCheckboxItemWidth
= nWidth
;
1969 nTreeFlags
|= SvTreeFlags::RECALCTABS
;
1977 void SvTreeListBox::SetCheckButtonState( SvTreeListEntry
* pEntry
, SvButtonState eState
)
1979 if( nTreeFlags
& SvTreeFlags::CHKBTN
)
1981 SvLBoxButton
* pItem
= static_cast<SvLBoxButton
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
1982 if(!(pItem
&& pItem
->CheckModification()))
1986 case SV_BUTTON_CHECKED
:
1987 pItem
->SetStateChecked();
1990 case SV_BUTTON_UNCHECKED
:
1991 pItem
->SetStateUnchecked();
1994 case SV_BUTTON_TRISTATE
:
1995 pItem
->SetStateTristate();
1998 InvalidateEntry( pEntry
);
2002 void SvTreeListBox::SetCheckButtonInvisible( SvTreeListEntry
* pEntry
)
2004 if( nTreeFlags
& SvTreeFlags::CHKBTN
)
2006 SvLBoxButton
* pItem
= static_cast<SvLBoxButton
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
2007 pItem
->SetStateInvisible();
2008 InvalidateEntry( pEntry
);
2012 SvButtonState
SvTreeListBox::GetCheckButtonState( SvTreeListEntry
* pEntry
) const
2014 SvButtonState eState
= SV_BUTTON_UNCHECKED
;
2015 if( nTreeFlags
& SvTreeFlags::CHKBTN
)
2017 SvLBoxButton
* pItem
= static_cast<SvLBoxButton
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
2019 return SV_BUTTON_TRISTATE
;
2020 SvItemStateFlags nButtonFlags
= pItem
->GetButtonFlags();
2021 eState
= SvLBoxButtonData::ConvertToButtonState( nButtonFlags
);
2026 void SvTreeListBox::CheckButtonHdl()
2028 aCheckButtonHdl
.Call( this );
2029 if ( pCheckButtonData
)
2030 pImp
->CallEventListeners( VCLEVENT_CHECKBOX_TOGGLE
, (void*)pCheckButtonData
->GetActEntry() );
2034 // TODO: Currently all data is cloned so that they conform to the default tree
2035 // view format. Actually, the model should be used as a reference here. This
2036 // leads to us _not_ calling SvTreeListEntry::Clone, but only its base class
2040 SvTreeListEntry
* SvTreeListBox::CloneEntry( SvTreeListEntry
* pSource
)
2043 Image aCollEntryBmp
;
2045 SvLBoxButtonKind eButtonKind
= SvLBoxButtonKind_enabledCheckbox
;
2047 SvLBoxString
* pStringItem
= static_cast<SvLBoxString
*>(pSource
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
2049 aStr
= pStringItem
->GetText();
2050 SvLBoxContextBmp
* pBmpItem
= static_cast<SvLBoxContextBmp
*>(pSource
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
2053 aCollEntryBmp
= pBmpItem
->GetBitmap1( );
2054 aExpEntryBmp
= pBmpItem
->GetBitmap2( );
2056 SvLBoxButton
* pButtonItem
= static_cast<SvLBoxButton
*>(pSource
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
2058 eButtonKind
= pButtonItem
->GetKind();
2059 SvTreeListEntry
* pClone
= CreateEntry();
2060 InitEntry( pClone
, aStr
, aCollEntryBmp
, aExpEntryBmp
, eButtonKind
);
2061 pClone
->SvTreeListEntry::Clone( pSource
);
2062 pClone
->EnableChildrenOnDemand( pSource
->HasChildrenOnDemand() );
2063 pClone
->SetUserData( pSource
->GetUserData() );
2068 void SvTreeListBox::SetIndent( short nNewIndent
)
2070 nIndent
= nNewIndent
;
2072 if( IsUpdateMode() )
2076 const Image
& SvTreeListBox::GetDefaultExpandedEntryBmp( ) const
2078 return pImp
->GetDefaultEntryExpBmp( );
2081 const Image
& SvTreeListBox::GetDefaultCollapsedEntryBmp( ) const
2083 return pImp
->GetDefaultEntryColBmp( );
2086 void SvTreeListBox::SetDefaultExpandedEntryBmp( const Image
& aBmp
)
2088 Size aSize
= aBmp
.GetSizePixel();
2089 if( aSize
.Width() > nContextBmpWidthMax
)
2090 nContextBmpWidthMax
= (short)aSize
.Width();
2093 pImp
->SetDefaultEntryExpBmp( aBmp
);
2096 void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image
& aBmp
)
2098 Size aSize
= aBmp
.GetSizePixel();
2099 if( aSize
.Width() > nContextBmpWidthMax
)
2100 nContextBmpWidthMax
= (short)aSize
.Width();
2103 pImp
->SetDefaultEntryColBmp( aBmp
);
2106 void SvTreeListBox::EnableCheckButton( SvLBoxButtonData
* pData
)
2108 DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0");
2110 nTreeFlags
&= (~SvTreeFlags::CHKBTN
);
2113 SetCheckButtonData( pData
);
2114 nTreeFlags
|= SvTreeFlags::CHKBTN
;
2115 pData
->SetLink( LINK(this, SvTreeListBox
, CheckButtonClick
));
2119 if( IsUpdateMode() )
2123 void SvTreeListBox::SetCheckButtonData( SvLBoxButtonData
* pData
)
2126 pCheckButtonData
= pData
;
2129 const Image
& SvTreeListBox::GetDefaultExpandedNodeImage( )
2131 return SvImpLBox::GetDefaultExpandedNodeImage( );
2134 const Image
& SvTreeListBox::GetDefaultCollapsedNodeImage( )
2136 return SvImpLBox::GetDefaultCollapsedNodeImage( );
2139 void SvTreeListBox::SetNodeBitmaps( const Image
& rCollapsedNodeBmp
, const Image
& rExpandedNodeBmp
)
2141 SetExpandedNodeBmp( rExpandedNodeBmp
);
2142 SetCollapsedNodeBmp( rCollapsedNodeBmp
);
2146 bool SvTreeListBox::EditingEntry( SvTreeListEntry
*, Selection
& )
2151 bool SvTreeListBox::EditedEntry( SvTreeListEntry
* /*pEntry*/,const OUString
& /*rNewText*/)
2156 void SvTreeListBox::EnableInplaceEditing( bool bOn
)
2159 nImpFlags
|= SvTreeListBoxFlags::EDT_ENABLED
;
2161 nImpFlags
&= ~SvTreeListBoxFlags::EDT_ENABLED
;
2164 void SvTreeListBox::KeyInput( const KeyEvent
& rKEvt
)
2166 // under OS/2, we get key up/down even while editing
2167 if( IsEditingActive() )
2170 nImpFlags
|= SvTreeListBoxFlags::IS_TRAVELSELECT
;
2172 if( !pImp
->KeyInput( rKEvt
) )
2174 bool bHandled
= HandleKeyInput( rKEvt
);
2176 Control::KeyInput( rKEvt
);
2179 nImpFlags
&= ~SvTreeListBoxFlags::IS_TRAVELSELECT
;
2182 void SvTreeListBox::RequestingChildren( SvTreeListEntry
* pParent
)
2184 if( !pParent
->HasChildren() )
2185 InsertEntry( OUString("<dummy>"), pParent
, false, TREELIST_APPEND
);
2188 void SvTreeListBox::GetFocus()
2190 //If there is no item in the tree, draw focus.
2196 Control::GetFocus();
2198 SvTreeListEntry
* pEntry
= FirstSelected();
2201 pEntry
= pImp
->GetCurrentEntry();
2205 if (pEntry
!= pImp
->pCursor
)
2206 pEntry
= pImp
->pCursor
;
2209 pImp
->CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS
, pEntry
);
2213 void SvTreeListBox::LoseFocus()
2215 // If there is no item in the tree, delete visual focus.
2220 Control::LoseFocus();
2223 void SvTreeListBox::ModelHasCleared()
2225 pImp
->pCursor
= 0; // else we crash in GetFocus when editing in-place
2231 nContextBmpWidthMax
= 0;
2232 SetDefaultExpandedEntryBmp( GetDefaultExpandedEntryBmp() );
2233 SetDefaultCollapsedEntryBmp( GetDefaultCollapsedEntryBmp() );
2235 if( !(nTreeFlags
& SvTreeFlags::FIXEDHEIGHT
))
2237 AdjustEntryHeight( GetFont() );
2238 AdjustEntryHeight( GetDefaultExpandedEntryBmp() );
2239 AdjustEntryHeight( GetDefaultCollapsedEntryBmp() );
2241 SvListView::ModelHasCleared();
2244 void SvTreeListBox::ShowTargetEmphasis( SvTreeListEntry
* pEntry
, bool /*bShow*/ )
2246 pImp
->PaintDDCursor( pEntry
);
2249 void SvTreeListBox::ScrollOutputArea( short nDeltaEntries
)
2251 if( !nDeltaEntries
|| !pImp
->aVerSBar
->IsVisible() )
2254 long nThumb
= pImp
->aVerSBar
->GetThumbPos();
2255 long nMax
= pImp
->aVerSBar
->GetRange().Max();
2257 if( nDeltaEntries
< 0 )
2260 nDeltaEntries
*= -1;
2261 long nVis
= pImp
->aVerSBar
->GetVisibleSize();
2262 long nTemp
= nThumb
+ nVis
;
2263 if( nDeltaEntries
> (nMax
- nTemp
) )
2264 nDeltaEntries
= (short)(nMax
- nTemp
);
2265 pImp
->PageDown( (sal_uInt16
)nDeltaEntries
);
2269 if( nDeltaEntries
> nThumb
)
2270 nDeltaEntries
= (short)nThumb
;
2271 pImp
->PageUp( (sal_uInt16
)nDeltaEntries
);
2273 pImp
->SyncVerThumb();
2277 void SvTreeListBox::ScrollToAbsPos( long nPos
)
2279 pImp
->ScrollToAbsPos( nPos
);
2282 void SvTreeListBox::SetSelectionMode( SelectionMode eSelectMode
)
2284 eSelMode
= eSelectMode
;
2285 pImp
->SetSelectionMode( eSelectMode
);
2288 void SvTreeListBox::SetDragDropMode( DragDropMode nDDMode
)
2290 nDragDropMode
= nDDMode
;
2291 pImp
->SetDragDropMode( nDDMode
);
2294 short SvTreeListBox::GetHeightOffset(const Image
& rBmp
, Size
& aSizeLogic
)
2297 aSizeLogic
= rBmp
.GetSizePixel();
2298 if( GetEntryHeight() > aSizeLogic
.Height() )
2299 nOffset
= ( GetEntryHeight() - (short)aSizeLogic
.Height()) / 2;
2303 short SvTreeListBox::GetHeightOffset(const vcl::Font
& /* rFont */, Size
& aSizeLogic
)
2306 aSizeLogic
= Size(GetTextWidth(OUString('X')), GetTextHeight());
2307 if( GetEntryHeight() > aSizeLogic
.Height() )
2308 nOffset
= ( GetEntryHeight() - (short)aSizeLogic
.Height()) / 2;
2312 void SvTreeListBox::SetEntryHeight( SvTreeListEntry
* pEntry
)
2315 sal_uInt16 nCount
= pEntry
->ItemCount();
2316 sal_uInt16 nCur
= 0;
2317 SvViewDataEntry
* pViewData
= GetViewDataEntry( pEntry
);
2318 while( nCur
< nCount
)
2320 short nHeight
= (short)(SvLBoxItem::GetSize( pViewData
, nCur
).Height());
2321 if( nHeight
> nHeightMax
)
2322 nHeightMax
= nHeight
;
2326 if( nHeightMax
> nEntryHeight
)
2328 nEntryHeight
= nHeightMax
;
2329 Control::SetFont( GetFont() );
2330 pImp
->SetEntryHeight( nHeightMax
);
2334 void SvTreeListBox::SetEntryHeight( short nHeight
, bool bAlways
)
2337 if( bAlways
|| nHeight
> nEntryHeight
)
2339 nEntryHeight
= nHeight
;
2341 nTreeFlags
|= SvTreeFlags::FIXEDHEIGHT
;
2343 nTreeFlags
&= ~SvTreeFlags::FIXEDHEIGHT
;
2344 Control::SetFont( GetFont() );
2345 pImp
->SetEntryHeight( nHeight
);
2350 void SvTreeListBox::AdjustEntryHeight( const Image
& rBmp
)
2353 GetHeightOffset( rBmp
, aSize
);
2354 if( aSize
.Height() > nEntryHeight
)
2356 nEntryHeight
= (short)aSize
.Height() + nEntryHeightOffs
;
2357 pImp
->SetEntryHeight( nEntryHeight
);
2361 void SvTreeListBox::AdjustEntryHeight( const vcl::Font
& rFont
)
2364 GetHeightOffset( rFont
, aSize
);
2365 if( aSize
.Height() > nEntryHeight
)
2367 nEntryHeight
= (short)aSize
.Height() + nEntryHeightOffs
;
2368 pImp
->SetEntryHeight( nEntryHeight
);
2372 bool SvTreeListBox::Expand( SvTreeListEntry
* pParent
)
2374 pHdlEntry
= pParent
;
2375 bool bExpanded
= false;
2376 SvTLEntryFlags nFlags
;
2378 if( pParent
->HasChildrenOnDemand() )
2379 RequestingChildren( pParent
);
2380 if( pParent
->HasChildren() )
2382 nImpFlags
|= SvTreeListBoxFlags::IS_EXPANDING
;
2383 if( ExpandingHdl() )
2386 ExpandListEntry( pParent
);
2387 pImp
->EntryExpanded( pParent
);
2388 pHdlEntry
= pParent
;
2391 nFlags
= pParent
->GetFlags();
2392 nFlags
&= ~SvTLEntryFlags::NO_NODEBMP
;
2393 nFlags
|= SvTLEntryFlags::HAD_CHILDREN
;
2394 pParent
->SetFlags( nFlags
);
2398 nFlags
= pParent
->GetFlags();
2399 nFlags
|= SvTLEntryFlags::NO_NODEBMP
;
2400 pParent
->SetFlags( nFlags
);
2401 GetModel()->InvalidateEntry( pParent
); // repaint
2407 pImp
->CallEventListeners( VCLEVENT_ITEM_EXPANDED
, pParent
);
2413 bool SvTreeListBox::Collapse( SvTreeListEntry
* pParent
)
2415 nImpFlags
&= ~SvTreeListBoxFlags::IS_EXPANDING
;
2416 pHdlEntry
= pParent
;
2417 bool bCollapsed
= false;
2419 if( ExpandingHdl() )
2422 pImp
->CollapsingEntry( pParent
);
2423 CollapseListEntry( pParent
);
2424 pImp
->EntryCollapsed( pParent
);
2425 pHdlEntry
= pParent
;
2432 pImp
->CallEventListeners( VCLEVENT_ITEM_COLLAPSED
, pParent
);
2438 bool SvTreeListBox::Select( SvTreeListEntry
* pEntry
, bool bSelect
)
2440 DBG_ASSERT(pEntry
,"Select: Null-Ptr");
2441 bool bRetVal
= SelectListEntry( pEntry
, bSelect
);
2442 DBG_ASSERT(IsSelected(pEntry
)==bSelect
,"Select failed");
2445 pImp
->EntrySelected( pEntry
, bSelect
);
2450 CallEventListeners( VCLEVENT_LISTBOX_TREESELECT
, pEntry
);
2458 sal_uLong
SvTreeListBox::SelectChildren( SvTreeListEntry
* pParent
, bool bSelect
)
2460 pImp
->DestroyAnchor();
2462 if( !pParent
->HasChildren() )
2464 sal_uInt16 nRefDepth
= pModel
->GetDepth( pParent
);
2465 SvTreeListEntry
* pChild
= FirstChild( pParent
);
2468 Select( pChild
, bSelect
);
2469 pChild
= Next( pChild
);
2470 } while( pChild
&& pModel
->GetDepth( pChild
) > nRefDepth
);
2474 void SvTreeListBox::SelectAll( bool bSelect
, bool )
2476 pImp
->SelAllDestrAnch(
2478 true, // delete anchor,
2479 true ); // even when using SINGLE_SELECTION, deselect the cursor
2482 void SvTreeListBox::ModelHasInsertedTree( SvTreeListEntry
* pEntry
)
2484 sal_uInt16 nRefDepth
= pModel
->GetDepth( pEntry
);
2485 SvTreeListEntry
* pTmp
= pEntry
;
2488 ImpEntryInserted( pTmp
);
2489 pTmp
= Next( pTmp
);
2490 } while( pTmp
&& nRefDepth
< pModel
->GetDepth( pTmp
) );
2491 pImp
->TreeInserted( pEntry
);
2494 void SvTreeListBox::ModelHasInserted( SvTreeListEntry
* pEntry
)
2496 ImpEntryInserted( pEntry
);
2497 pImp
->EntryInserted( pEntry
);
2500 void SvTreeListBox::ModelIsMoving(SvTreeListEntry
* pSource
,
2501 SvTreeListEntry
* /* pTargetParent */,
2502 sal_uLong
/* nChildPos */ )
2504 pImp
->MovingEntry( pSource
);
2507 void SvTreeListBox::ModelHasMoved( SvTreeListEntry
* pSource
)
2509 pImp
->EntryMoved( pSource
);
2512 void SvTreeListBox::ModelIsRemoving( SvTreeListEntry
* pEntry
)
2514 if(pEdEntry
== pEntry
)
2517 pImp
->RemovingEntry( pEntry
);
2520 void SvTreeListBox::ModelHasRemoved( SvTreeListEntry
* pEntry
)
2522 if ( pEntry
== pHdlEntry
)
2524 pImp
->EntryRemoved();
2527 void SvTreeListBox::SetCollapsedNodeBmp( const Image
& rBmp
)
2529 AdjustEntryHeight( rBmp
);
2530 pImp
->SetCollapsedNodeBmp( rBmp
);
2533 void SvTreeListBox::SetExpandedNodeBmp( const Image
& rBmp
)
2535 AdjustEntryHeight( rBmp
);
2536 pImp
->SetExpandedNodeBmp( rBmp
);
2540 void SvTreeListBox::SetFont( const vcl::Font
& rFont
)
2542 vcl::Font
aTempFont( rFont
);
2543 vcl::Font
aOrigFont( GetFont() );
2544 aTempFont
.SetTransparent( true );
2545 if (aTempFont
== aOrigFont
)
2547 Control::SetFont( aTempFont
);
2549 aTempFont
.SetColor(aOrigFont
.GetColor());
2550 aTempFont
.SetFillColor(aOrigFont
.GetFillColor());
2551 aTempFont
.SetTransparent(aOrigFont
.IsTransparent());
2553 if (aTempFont
== aOrigFont
)
2556 AdjustEntryHeightAndRecalc( GetFont() );
2559 void SvTreeListBox::AdjustEntryHeightAndRecalc( const vcl::Font
& rFont
)
2561 AdjustEntryHeight( rFont
);
2562 // always invalidate, else things go wrong in SetEntryHeight
2566 void SvTreeListBox::Paint(vcl::RenderContext
& rRenderContext
, const Rectangle
& rRect
)
2568 Control::Paint(rRenderContext
, rRect
);
2569 if (nTreeFlags
& SvTreeFlags::RECALCTABS
)
2571 pImp
->Paint(rRenderContext
, rRect
);
2573 //Add visual focus draw
2578 long nHeight
= rRenderContext
.GetTextHeight();
2579 Rectangle
aRect(Point(0, 0), Size(GetSizePixel().Width(), nHeight
));
2589 void SvTreeListBox::MouseButtonDown( const MouseEvent
& rMEvt
)
2591 pImp
->MouseButtonDown( rMEvt
);
2594 void SvTreeListBox::MouseButtonUp( const MouseEvent
& rMEvt
)
2596 pImp
->MouseButtonUp( rMEvt
);
2599 void SvTreeListBox::MouseMove( const MouseEvent
& rMEvt
)
2601 pImp
->MouseMove( rMEvt
);
2605 void SvTreeListBox::SetUpdateMode( bool bUpdate
)
2607 pImp
->SetUpdateMode( bUpdate
);
2610 void SvTreeListBox::SetSpaceBetweenEntries( short nOffsLogic
)
2612 if( nOffsLogic
!= nEntryHeightOffs
)
2614 nEntryHeight
= nEntryHeight
- nEntryHeightOffs
;
2615 nEntryHeightOffs
= (short)nOffsLogic
;
2616 nEntryHeight
= nEntryHeight
+ nOffsLogic
;
2617 AdjustEntryHeightAndRecalc( GetFont() );
2618 pImp
->SetEntryHeight( nEntryHeight
);
2622 void SvTreeListBox::SetCursor( SvTreeListEntry
* pEntry
, bool bForceNoSelect
)
2624 pImp
->SetCursor(pEntry
, bForceNoSelect
);
2627 void SvTreeListBox::SetCurEntry( SvTreeListEntry
* pEntry
)
2629 pImp
->SetCurEntry( pEntry
);
2632 Image
SvTreeListBox::GetExpandedNodeBmp( ) const
2634 return pImp
->GetExpandedNodeBmp( );
2637 Point
SvTreeListBox::GetEntryPosition( SvTreeListEntry
* pEntry
) const
2639 return pImp
->GetEntryPosition( pEntry
);
2642 void SvTreeListBox::ShowEntry( SvTreeListEntry
* pEntry
)
2644 MakeVisible( pEntry
);
2647 void SvTreeListBox::MakeVisible( SvTreeListEntry
* pEntry
)
2649 pImp
->MakeVisible(pEntry
);
2652 void SvTreeListBox::MakeVisible( SvTreeListEntry
* pEntry
, bool bMoveToTop
)
2654 pImp
->MakeVisible( pEntry
, bMoveToTop
);
2657 void SvTreeListBox::ModelHasEntryInvalidated( SvTreeListEntry
* pEntry
)
2660 // reinitialize the separate items of the entries
2661 sal_uInt16 nCount
= pEntry
->ItemCount();
2662 for( sal_uInt16 nIdx
= 0; nIdx
< nCount
; nIdx
++ )
2664 SvLBoxItem
* pItem
= pEntry
->GetItem( nIdx
);
2665 pItem
->InitViewData( this, pEntry
, 0 );
2669 pImp
->InvalidateEntry( pEntry
);
2672 void SvTreeListBox::EditItemText(SvTreeListEntry
* pEntry
, SvLBoxString
* pItem
, const Selection
& rSelection
)
2674 DBG_ASSERT(pEntry
&&pItem
,"EditItemText: Bad params");
2675 if( IsSelected( pEntry
))
2677 pImp
->ShowCursor( false );
2678 SelectListEntry( pEntry
, false );
2679 pImp
->InvalidateEntry(pEntry
);
2680 SelectListEntry( pEntry
, true );
2681 pImp
->ShowCursor( true );
2685 SvLBoxTab
* pTab
= GetTab( pEntry
, pItem
);
2686 DBG_ASSERT(pTab
,"EditItemText:Tab not found");
2688 Size
aItemSize( pItem
->GetSize(this, pEntry
) );
2689 Point aPos
= GetEntryPosition( pEntry
);
2690 aPos
.Y() += ( nEntryHeight
- aItemSize
.Height() ) / 2;
2691 aPos
.X() = GetTabPos( pEntry
, pTab
);
2692 long nOutputWidth
= pImp
->GetOutputSize().Width();
2693 Size
aSize( nOutputWidth
- aPos
.X(), aItemSize
.Height() );
2694 sal_uInt16 nPos
= std::find( aTabs
.begin(), aTabs
.end(), pTab
) - aTabs
.begin();
2695 if( nPos
+1 < (sal_uInt16
)aTabs
.size() )
2697 SvLBoxTab
* pRightTab
= aTabs
[ nPos
+ 1 ];
2698 long nRight
= GetTabPos( pEntry
, pRightTab
);
2699 if( nRight
<= nOutputWidth
)
2700 aSize
.Width() = nRight
- aPos
.X();
2702 Point
aOrigin( GetMapMode().GetOrigin() );
2703 aPos
+= aOrigin
; // convert to win coordinates
2704 aSize
.Width() -= aOrigin
.X();
2705 Rectangle
aRect( aPos
, aSize
);
2706 EditText( pItem
->GetText(), aRect
, rSelection
);
2709 void SvTreeListBox::EditEntry( SvTreeListEntry
* pEntry
)
2711 pImp
->aEditClickPos
= Point( -1, -1 );
2712 ImplEditEntry( pEntry
);
2715 void SvTreeListBox::ImplEditEntry( SvTreeListEntry
* pEntry
)
2717 if( IsEditingActive() )
2720 pEntry
= GetCurEntry();
2723 long nClickX
= pImp
->aEditClickPos
.X();
2724 bool bIsMouseTriggered
= nClickX
>= 0;
2726 SvLBoxString
* pItem
= NULL
;
2727 sal_uInt16 nCount
= pEntry
->ItemCount();
2728 long nTabPos
, nNextTabPos
= 0;
2729 for( sal_uInt16 i
= 0 ; i
< nCount
; i
++ )
2731 SvLBoxItem
* pTmpItem
= pEntry
->GetItem( i
);
2732 if (pTmpItem
->GetType() != SV_ITEM_ID_LBOXSTRING
)
2735 SvLBoxTab
* pTab
= GetTab( pEntry
, pTmpItem
);
2737 if( i
< nCount
- 1 )
2739 SvLBoxItem
* pNextItem
= pEntry
->GetItem( i
+ 1 );
2740 SvLBoxTab
* pNextTab
= GetTab( pEntry
, pNextItem
);
2741 nNextTabPos
= pNextTab
->GetPos();
2744 if( pTab
&& pTab
->IsEditable() )
2746 nTabPos
= pTab
->GetPos();
2747 if( !bIsMouseTriggered
|| (nClickX
> nTabPos
&& (nNextTabPos
== -1 || nClickX
< nNextTabPos
) ) )
2749 pItem
= static_cast<SvLBoxString
*>( pTmpItem
);
2755 Selection
aSel( SELECTION_MIN
, SELECTION_MAX
);
2756 if( pItem
&& EditingEntry( pEntry
, aSel
) )
2759 MakeVisible( pEntry
);
2760 EditItemText( pEntry
, pItem
, aSel
);
2765 bool SvTreeListBox::AreChildrenTransient() const
2767 return pImp
->AreChildrenTransient();
2770 void SvTreeListBox::SetChildrenNotTransient()
2772 pImp
->SetChildrenNotTransient();
2775 void SvTreeListBox::EditedText( const OUString
& rStr
)
2778 if(pEdEntry
) // we have to check if this entry is null that means that it is removed while editing
2780 if( EditedEntry( pEdEntry
, rStr
) )
2782 static_cast<SvLBoxString
*>(pEdItem
)->SetText( rStr
);
2783 pModel
->InvalidateEntry( pEdEntry
);
2785 if( GetSelectionCount() == 0 )
2787 if( GetSelectionMode() == MULTIPLE_SELECTION
&& !GetCurEntry() )
2788 SetCurEntry( pEdEntry
);
2792 SvTreeListEntry
* SvTreeListBox::GetDropTarget( const Point
& rPos
)
2797 ImplShowTargetEmphasis(pTargetEntry
, false);
2798 ScrollOutputArea( +1 );
2802 Size
aSize( pImp
->GetOutputSize() );
2803 if( rPos
.Y() > aSize
.Height() - 12 )
2805 ImplShowTargetEmphasis(pTargetEntry
, false);
2806 ScrollOutputArea( -1 );
2810 SvTreeListEntry
* pTarget
= pImp
->GetEntry( rPos
);
2811 // when dropping in a vacant space, use the last entry
2813 return LastVisible();
2814 else if( (GetDragDropMode() & DragDropMode::ENABLE_TOP
) &&
2815 pTarget
== First() && rPos
.Y() < 6 )
2822 SvTreeListEntry
* SvTreeListBox::GetEntry( const Point
& rPos
, bool bHit
) const
2824 SvTreeListEntry
* pEntry
= pImp
->GetEntry( rPos
);
2825 if( pEntry
&& bHit
)
2827 long nLine
= pImp
->GetEntryLine( pEntry
);
2828 if( !(pImp
->EntryReallyHit( pEntry
, rPos
, nLine
)) )
2834 SvTreeListEntry
* SvTreeListBox::GetCurEntry() const
2836 return pImp
? pImp
->GetCurEntry() : NULL
;
2839 void SvTreeListBox::ImplInitStyle()
2841 const WinBits nWindowStyle
= GetStyle();
2843 nTreeFlags
|= SvTreeFlags::RECALCTABS
;
2844 if (nWindowStyle
& WB_SORT
)
2846 GetModel()->SetSortMode(SortAscending
);
2847 GetModel()->SetCompareHdl(LINK(this, SvTreeListBox
, DefaultCompare
));
2851 GetModel()->SetSortMode(SortNone
);
2852 GetModel()->SetCompareHdl(Link
<>());
2854 pImp
->SetStyle(nWindowStyle
);
2859 void SvTreeListBox::InvalidateEntry(SvTreeListEntry
* pEntry
)
2861 DBG_ASSERT(pEntry
,"InvalidateEntry:No Entry");
2864 GetModel()->InvalidateEntry(pEntry
);
2868 long SvTreeListBox::PaintEntry(SvTreeListEntry
* pEntry
, long nLine
, vcl::RenderContext
& rRenderContext
, SvLBoxTabFlags nTabFlags
)
2870 return PaintEntry1(pEntry
, nLine
, rRenderContext
, nTabFlags
);
2873 long SvTreeListBox::PaintEntry1(SvTreeListEntry
* pEntry
, long nLine
, vcl::RenderContext
& rRenderContext
,
2874 SvLBoxTabFlags nTabFlags
, bool bHasClipRegion
)
2877 Rectangle aRect
; // multi purpose
2879 bool bHorSBar
= pImp
->HasHorScrollBar();
2880 PreparePaint(rRenderContext
, pEntry
);
2882 pImp
->UpdateContextBmpWidthMax(pEntry
);
2884 if (nTreeFlags
& SvTreeFlags::RECALCTABS
)
2887 short nTempEntryHeight
= GetEntryHeight();
2888 long nWidth
= pImp
->GetOutputSize().Width();
2890 // Did we turn on the scrollbar within PreparePaints? If yes, we have to set
2891 // the ClipRegion anew.
2892 if (!bHorSBar
&& pImp
->HasHorScrollBar())
2893 rRenderContext
.SetClipRegion(vcl::Region(pImp
->GetClipRegionRect()));
2895 Point
aEntryPos(rRenderContext
.GetMapMode().GetOrigin());
2896 aEntryPos
.X() *= -1; // conversion document coordinates
2897 long nMaxRight
= nWidth
+ aEntryPos
.X() - 1;
2899 Color
aBackupTextColor(rRenderContext
.GetTextColor());
2900 vcl::Font
aBackupFont(rRenderContext
.GetFont());
2901 Color aBackupColor
= rRenderContext
.GetFillColor();
2903 bool bCurFontIsSel
= false;
2904 bool bInUse
= pEntry
->HasInUseEmphasis();
2905 // if a ClipRegion was set from outside, we don't have to reset it
2906 const WinBits nWindowStyle
= GetStyle();
2907 const bool bResetClipRegion
= !bHasClipRegion
;
2908 const bool bHideSelection
= (nWindowStyle
& WB_HIDESELECTION
) !=0 && !HasFocus();
2909 const StyleSettings
& rSettings
= rRenderContext
.GetSettings().GetStyleSettings();
2911 vcl::Font
aHighlightFont(rRenderContext
.GetFont());
2912 const Color
aHighlightTextColor(rSettings
.GetHighlightTextColor());
2913 aHighlightFont
.SetColor(aHighlightTextColor
);
2915 Size
aRectSize(0, nTempEntryHeight
);
2917 if (!bHasClipRegion
&& nWindowStyle
& WB_HSCROLL
)
2919 rRenderContext
.SetClipRegion(vcl::Region(pImp
->GetClipRegionRect()));
2920 bHasClipRegion
= true;
2923 SvViewDataEntry
* pViewDataEntry
= GetViewDataEntry( pEntry
);
2925 sal_uInt16 nTabCount
= aTabs
.size();
2926 sal_uInt16 nItemCount
= pEntry
->ItemCount();
2927 sal_uInt16 nCurTab
= 0;
2928 sal_uInt16 nCurItem
= 0;
2930 while (nCurTab
< nTabCount
&& nCurItem
< nItemCount
)
2932 SvLBoxTab
* pTab
= aTabs
[nCurTab
];
2933 sal_uInt16 nNextTab
= nCurTab
+ 1;
2934 SvLBoxTab
* pNextTab
= nNextTab
< nTabCount
? aTabs
[nNextTab
] : 0;
2935 SvLBoxItem
* pItem
= nCurItem
< nItemCount
? pEntry
->GetItem(nCurItem
) : 0;
2937 SvLBoxTabFlags nFlags
= pTab
->nFlags
;
2938 Size
aSize(SvLBoxItem::GetSize(pViewDataEntry
, nCurItem
));
2939 long nTabPos
= GetTabPos(pEntry
, pTab
);
2943 nNextTabPos
= GetTabPos(pEntry
, pNextTab
);
2946 nNextTabPos
= nMaxRight
;
2947 if (nTabPos
> nMaxRight
)
2952 if( pTab
->nFlags
& SvLBoxTabFlags::ADJUST_RIGHT
)
2953 // avoid cutting the right edge off the tab separation
2954 nX
= nTabPos
+ pTab
->CalcOffset(aSize
.Width(), (nNextTabPos
- SV_TAB_BORDER
- 1) - nTabPos
);
2956 nX
= nTabPos
+ pTab
->CalcOffset(aSize
.Width(), nNextTabPos
- nTabPos
);
2958 if (nFlags
& nTabFlags
)
2960 if (!bHasClipRegion
&& nX
+ aSize
.Width() >= nMaxRight
)
2962 rRenderContext
.SetClipRegion(vcl::Region(pImp
->GetClipRegionRect()));
2963 bHasClipRegion
= true;
2966 aEntryPos
.Y() = nLine
;
2968 // set background pattern/color
2970 Wallpaper aWallpaper
= rRenderContext
.GetBackground();
2972 bool bSelTab
= bool(nFlags
& SvLBoxTabFlags::SHOW_SELECTION
);
2973 sal_uInt16 nItemType
= pItem
->GetType();
2975 if (pViewDataEntry
->IsHighlighted() && bSelTab
&& !pViewDataEntry
->IsCursored())
2977 Color aNewWallColor
= rSettings
.GetHighlightColor();
2978 if (!bInUse
|| nItemType
!= SV_ITEM_ID_LBOXCONTEXTBMP
)
2980 // if the face color is bright then the deactive color is also bright
2981 // -> so you can't see any deactive selection
2982 if (bHideSelection
&& !rSettings
.GetFaceColor().IsBright()
2983 && aWallpaper
.GetColor().IsBright() != rSettings
.GetDeactiveColor().IsBright())
2985 aNewWallColor
= rSettings
.GetDeactiveColor();
2987 // set font color to highlight
2990 rRenderContext
.SetTextColor(aHighlightTextColor
);
2991 rRenderContext
.SetFont(aHighlightFont
);
2992 bCurFontIsSel
= true;
2995 aWallpaper
.SetColor(aNewWallColor
);
2997 else // no selection
2999 if (bInUse
&& nItemType
== SV_ITEM_ID_LBOXCONTEXTBMP
)
3001 aWallpaper
.SetColor(rSettings
.GetFieldColor());
3003 else if (bCurFontIsSel
)
3005 bCurFontIsSel
= false;
3006 rRenderContext
.SetTextColor(aBackupTextColor
);
3007 rRenderContext
.SetFont(aBackupFont
);
3011 aWallpaper
.SetColor(pEntry
->GetBackColor());
3016 if (!(nTreeFlags
& SvTreeFlags::USESEL
))
3018 // only draw the area that is used by the item
3019 aRectSize
.Width() = aSize
.Width();
3020 aRect
.SetPos(aEntryPos
);
3021 aRect
.SetSize(aRectSize
);
3025 // draw from the current to the next tab
3027 aRect
.Left() = nTabPos
;
3029 // if we're in the 0th tab, always draw from column 0 --
3030 // else we get problems with centered tabs
3032 aRect
.Top() = nLine
;
3033 aRect
.Bottom() = nLine
+ nTempEntryHeight
- 1;
3037 nRight
= GetTabPos(pEntry
, pNextTab
) - 1;
3038 if (nRight
> nMaxRight
)
3040 aRect
.Right() = nRight
;
3044 aRect
.Right() = nMaxRight
;
3047 // A custom selection that starts at a tab position > 0, do not fill
3048 // the background of the 0th item, else e.g. we might not be able to
3049 // realize tab listboxes with lines.
3050 if (!(nCurTab
== 0 && (nTreeFlags
& SvTreeFlags::USESEL
) && nFirstSelTab
))
3052 Color aBackgroundColor
= aWallpaper
.GetColor();
3053 if (aBackgroundColor
!= Color(COL_TRANSPARENT
))
3055 rRenderContext
.SetFillColor(aBackgroundColor
);
3056 // this case may occur for smaller horizontal resizes
3057 if (aRect
.Left() < aRect
.Right())
3058 rRenderContext
.DrawRect(aRect
);
3062 // center vertically
3063 aEntryPos
.Y() += (nTempEntryHeight
- aSize
.Height()) / 2;
3064 pViewDataEntry
->SetPaintRectangle(aRect
);
3066 pItem
->Paint(aEntryPos
, *this, rRenderContext
, pViewDataEntry
, pEntry
);
3068 // division line between tabs
3069 if (pNextTab
&& pItem
->GetType() == SV_ITEM_ID_LBOXSTRING
&&
3070 // not at the right edge of the window!
3071 aRect
.Right() < nMaxRight
)
3073 aRect
.Left() = aRect
.Right() - SV_TAB_BORDER
;
3074 rRenderContext
.DrawRect(aRect
);
3077 rRenderContext
.SetFillColor(aBackupColor
);
3082 if (pViewDataEntry
->IsCursored() && !HasFocus())
3085 rRenderContext
.SetFillColor();
3086 Color aOldLineColor
= rRenderContext
.GetLineColor();
3087 rRenderContext
.SetLineColor(Color(COL_BLACK
));
3088 aRect
= GetFocusRect(pEntry
, nLine
);
3091 rRenderContext
.DrawRect(aRect
);
3092 rRenderContext
.SetLineColor(aOldLineColor
);
3093 rRenderContext
.SetFillColor(aBackupColor
);
3098 rRenderContext
.SetTextColor(aBackupTextColor
);
3099 rRenderContext
.SetFont(aBackupFont
);
3102 sal_uInt16 nFirstDynTabPos
;
3103 SvLBoxTab
* pFirstDynamicTab
= GetFirstDynamicTab(nFirstDynTabPos
);
3104 long nDynTabPos
= GetTabPos(pEntry
, pFirstDynamicTab
);
3105 nDynTabPos
+= pImp
->nNodeBmpTabDistance
;
3106 nDynTabPos
+= pImp
->nNodeBmpWidth
/ 2;
3107 nDynTabPos
+= 4; // 4 pixels of buffer, so the node bitmap is not too close
3110 if( (!(pEntry
->GetFlags() & SvTLEntryFlags::NO_NODEBMP
)) &&
3111 (nWindowStyle
& WB_HASBUTTONS
) && pFirstDynamicTab
&&
3112 (pEntry
->HasChildren() || pEntry
->HasChildrenOnDemand()))
3114 // find first tab and check if the node bitmap extends into it
3115 sal_uInt16 nNextTab
= nFirstDynTabPos
;
3116 SvLBoxTab
* pNextTab
;
3120 pNextTab
= nNextTab
< nTabCount
? aTabs
[nNextTab
] : 0;
3121 } while (pNextTab
&& pNextTab
->IsDynamic());
3123 if (!pNextTab
|| (GetTabPos( pEntry
, pNextTab
) > nDynTabPos
))
3125 if ((nWindowStyle
& WB_HASBUTTONSATROOT
) || pModel
->GetDepth(pEntry
) > 0)
3127 Point
aPos(GetTabPos(pEntry
, pFirstDynamicTab
), nLine
);
3128 aPos
.X() += pImp
->nNodeBmpTabDistance
;
3130 const Image
* pImg
= 0;
3132 if (IsExpanded(pEntry
))
3133 pImg
= &pImp
->GetExpandedNodeBmp();
3136 if ((!pEntry
->HasChildren()) && pEntry
->HasChildrenOnDemand() &&
3137 (!(pEntry
->GetFlags() & SvTLEntryFlags::HAD_CHILDREN
)) &&
3138 pImp
->GetDontKnowNodeBmp().GetSizePixel().Width())
3140 pImg
= &pImp
->GetDontKnowNodeBmp( );
3144 pImg
= &pImp
->GetCollapsedNodeBmp( );
3147 aPos
.Y() += (nTempEntryHeight
- pImg
->GetSizePixel().Height()) / 2;
3149 DrawImageFlags nStyle
= DrawImageFlags::NONE
;
3151 nStyle
|= DrawImageFlags::Disable
;
3154 bool bNativeOK
= false;
3155 if (rRenderContext
.IsNativeControlSupported(CTRL_LISTNODE
, PART_ENTIRE_CONTROL
))
3157 ImplControlValue aControlValue
;
3158 Rectangle
aCtrlRegion(aPos
, pImg
->GetSizePixel());
3159 ControlState nState
= ControlState::NONE
;
3162 nState
|= ControlState::ENABLED
;
3164 if (IsExpanded(pEntry
))
3165 aControlValue
.setTristateVal(BUTTONVALUE_ON
); //expanded node
3168 if ((!pEntry
->HasChildren()) && pEntry
->HasChildrenOnDemand() &&
3169 (!(pEntry
->GetFlags() & SvTLEntryFlags::HAD_CHILDREN
)) &&
3170 pImp
->GetDontKnowNodeBmp().GetSizePixel().Width())
3172 aControlValue
.setTristateVal( BUTTONVALUE_DONTKNOW
); //dont know
3176 aControlValue
.setTristateVal( BUTTONVALUE_OFF
); //collapsed node
3180 bNativeOK
= rRenderContext
.DrawNativeControl(CTRL_LISTNODE
, PART_ENTIRE_CONTROL
, aCtrlRegion
, nState
, aControlValue
, OUString());
3185 rRenderContext
.DrawImage(aPos
, *pImg
,nStyle
);
3191 if (bHasClipRegion
&& bResetClipRegion
)
3192 rRenderContext
.SetClipRegion();
3194 return 0; // nRowLen;
3197 void SvTreeListBox::PreparePaint(vcl::RenderContext
& /*rRenderContext*/, SvTreeListEntry
* /*pEntry*/)
3201 Rectangle
SvTreeListBox::GetFocusRect( SvTreeListEntry
* pEntry
, long nLine
)
3205 aRect
.Top() = nLine
;
3206 aSize
.Height() = GetEntryHeight();
3208 long nRealWidth
= pImp
->GetOutputSize().Width();
3209 nRealWidth
-= GetMapMode().GetOrigin().X();
3212 SvLBoxTab
* pTab
= GetFirstTab( SvLBoxTabFlags::SHOW_SELECTION
, nCurTab
);
3215 nTabPos
= GetTabPos( pEntry
, pTab
);
3217 if( pTab
&& nCurTab
< aTabs
.size() - 1 )
3219 SvLBoxTab
* pNextTab
= aTabs
[ nCurTab
+ 1 ];
3220 nNextTabPos
= GetTabPos( pEntry
, pNextTab
);
3224 nNextTabPos
= nRealWidth
;
3225 if( nTabPos
> nRealWidth
)
3229 bool bUserSelection
= bool( nTreeFlags
& SvTreeFlags::USESEL
);
3230 if( !bUserSelection
)
3232 if( pTab
&& nCurTab
< pEntry
->ItemCount() )
3234 SvLBoxItem
* pItem
= pEntry
->GetItem( nCurTab
);
3235 aSize
.Width() = pItem
->GetSize( this, pEntry
).Width();
3236 if( !aSize
.Width() )
3238 long nX
= nTabPos
; //GetTabPos( pEntry, pTab );
3240 nX
+= pTab
->CalcOffset( aSize
.Width(), nNextTabPos
- nTabPos
);
3242 // make sure that first and last letter aren't cut off slightly
3243 aRect
.SetSize( aSize
);
3244 if( aRect
.Left() > 0 )
3251 // if SelTab != 0, we have to calculate also
3252 if( nFocusWidth
== -1 || nFirstSelTab
)
3254 SvLBoxTab
* pLastTab
= NULL
; // default to select whole width
3256 sal_uInt16 nLastTab
;
3257 GetLastTab(SvLBoxTabFlags::SHOW_SELECTION
,nLastTab
);
3259 if( nLastTab
< aTabs
.size() ) // is there another one?
3260 pLastTab
= aTabs
[ nLastTab
];
3262 aSize
.Width() = pLastTab
? pLastTab
->GetPos() : 0x0fffffff;
3263 nFocusWidth
= (short)aSize
.Width();
3265 nFocusWidth
= nFocusWidth
- (short)nTabPos
; //pTab->GetPos();
3269 aSize
.Width() = nFocusWidth
;
3273 aSize
.Width() += nTabPos
;
3275 aSize
.Width() += pTab
->GetPos(); // Tab0 always from the leftmost position
3278 // if selection starts with 0th tab, draw from column 0 on
3281 aRect
.Left() = nTabPos
;
3282 aSize
.Width() -= nTabPos
;
3284 aRect
.SetSize( aSize
);
3286 // adjust right edge because of clipping
3287 if( aRect
.Right() >= nRealWidth
)
3289 aRect
.Right() = nRealWidth
-1;
3290 nFocusWidth
= (short)aRect
.GetWidth();
3296 sal_IntPtr
SvTreeListBox::GetTabPos( SvTreeListEntry
* pEntry
, SvLBoxTab
* pTab
)
3298 DBG_ASSERT(pTab
,"No Tab");
3299 sal_IntPtr nPos
= pTab
->GetPos();
3300 if( pTab
->IsDynamic() )
3302 sal_uInt16 nDepth
= pModel
->GetDepth( pEntry
);
3303 nDepth
= nDepth
* (sal_uInt16
)nIndent
;
3304 nPos
+= (sal_IntPtr
)nDepth
;
3309 SvLBoxItem
* SvTreeListBox::GetItem_Impl( SvTreeListEntry
* pEntry
, long nX
,
3310 SvLBoxTab
** ppTab
, sal_uInt16 nEmptyWidth
)
3312 SvLBoxItem
* pItemClicked
= 0;
3313 sal_uInt16 nTabCount
= aTabs
.size();
3314 sal_uInt16 nItemCount
= pEntry
->ItemCount();
3315 SvLBoxTab
* pTab
= aTabs
.front();
3316 SvLBoxItem
* pItem
= pEntry
->GetItem(0);
3317 sal_uInt16 nNextItem
= 1;
3318 nX
-= GetMapMode().GetOrigin().X();
3319 long nRealWidth
= pImp
->GetOutputSize().Width();
3320 nRealWidth
-= GetMapMode().GetOrigin().X();
3324 SvLBoxTab
* pNextTab
=nNextItem
<nTabCount
? aTabs
[nNextItem
] : 0;
3325 long nStart
= GetTabPos( pEntry
, pTab
);
3329 nNextTabPos
= GetTabPos( pEntry
, pNextTab
);
3332 nNextTabPos
= nRealWidth
;
3333 if( nStart
> nRealWidth
)
3337 Size
aItemSize( pItem
->GetSize(this, pEntry
));
3338 nStart
+= pTab
->CalcOffset( aItemSize
.Width(), nNextTabPos
- nStart
);
3339 long nLen
= aItemSize
.Width();
3342 long nTabWidth
= GetTabPos( pEntry
, pNextTab
) - nStart
;
3343 if( nTabWidth
< nLen
)
3350 if( nX
>= nStart
&& nX
< (nStart
+nLen
) )
3352 pItemClicked
= pItem
;
3359 if( nNextItem
>= nItemCount
|| nNextItem
>= nTabCount
)
3361 pTab
= aTabs
[ nNextItem
];
3362 pItem
= pEntry
->GetItem( nNextItem
);
3365 return pItemClicked
;
3368 long SvTreeListBox::getPreferredDimensions(std::vector
<long> &rWidths
) const
3372 SvTreeListEntry
* pEntry
= First();
3375 sal_uInt16 nCount
= pEntry
->ItemCount();
3376 sal_uInt16 nCurPos
= 0;
3377 if (nCount
> rWidths
.size())
3378 rWidths
.resize(nCount
);
3379 while (nCurPos
< nCount
)
3381 SvLBoxItem
* pItem
= pEntry
->GetItem( nCurPos
);
3382 long nWidth
= pItem
->GetSize(this, pEntry
).Width();
3385 nWidth
+= SV_TAB_BORDER
* 2;
3386 if (nWidth
> rWidths
[nCurPos
])
3387 rWidths
[nCurPos
] = nWidth
;
3391 pEntry
= Next( pEntry
);
3392 nHeight
+= GetEntryHeight();
3397 Size
SvTreeListBox::GetOptimalSize() const
3399 std::vector
<long> aWidths
;
3400 Size
aRet(0, getPreferredDimensions(aWidths
));
3401 for (size_t i
= 0; i
< aWidths
.size(); ++i
)
3402 aRet
.Width() += aWidths
[i
];
3403 if (GetStyle() & WB_BORDER
)
3405 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
3406 aRet
.Width() += rStyleSettings
.GetBorderSize() * 2;
3407 aRet
.Height() += rStyleSettings
.GetBorderSize() * 2;
3409 long nMinWidth
= nMinWidthInChars
* approximate_char_width();
3410 aRet
.Width() = std::max(aRet
.Width(), nMinWidth
);
3414 void SvTreeListBox::SetAlternatingRowColors( bool bEnable
)
3416 mbAlternatingRowColors
= bEnable
;
3417 if( mbAlternatingRowColors
)
3419 SvTreeListEntry
* pEntry
= pModel
->First();
3420 for(size_t i
= 0; pEntry
; ++i
)
3422 pEntry
->SetBackColor( i
% 2 == 0 ? GetBackground().GetColor() : GetSettings().GetStyleSettings().GetAlternatingRowColor());
3423 pEntry
= pModel
->Next(pEntry
);
3427 for(SvTreeListEntry
* pEntry
= pModel
->First(); pEntry
; pEntry
= pModel
->Next(pEntry
))
3428 pEntry
->SetBackColor( GetBackground().GetColor() );
3433 SvLBoxItem
* SvTreeListBox::GetItem(SvTreeListEntry
* pEntry
,long nX
,SvLBoxTab
** ppTab
)
3435 return GetItem_Impl( pEntry
, nX
, ppTab
, 0 );
3438 SvLBoxItem
* SvTreeListBox::GetItem(SvTreeListEntry
* pEntry
,long nX
)
3440 SvLBoxTab
* pDummyTab
;
3441 return GetItem_Impl( pEntry
, nX
, &pDummyTab
, 0 );
3444 void SvTreeListBox::AddTab(long nTabPos
, SvLBoxTabFlags nFlags
, void* pUserData
)
3447 SvLBoxTab
* pTab
= new SvLBoxTab( nTabPos
, nFlags
);
3448 pTab
->SetUserData( pUserData
);
3449 aTabs
.push_back( pTab
);
3450 if( nTreeFlags
& SvTreeFlags::USESEL
)
3452 sal_uInt16 nPos
= aTabs
.size() - 1;
3453 if( nPos
>= nFirstSelTab
&& nPos
<= nLastSelTab
)
3454 pTab
->nFlags
|= SvLBoxTabFlags::SHOW_SELECTION
;
3456 // string items usually have to be selected -- turn this off
3458 pTab
->nFlags
&= ~SvLBoxTabFlags::SHOW_SELECTION
;
3464 SvLBoxTab
* SvTreeListBox::GetFirstDynamicTab( sal_uInt16
& rPos
) const
3466 sal_uInt16 nCurTab
= 0;
3467 sal_uInt16 nTabCount
= aTabs
.size();
3468 while( nCurTab
< nTabCount
)
3470 SvLBoxTab
* pTab
= aTabs
[nCurTab
];
3471 if( pTab
->nFlags
& SvLBoxTabFlags::DYNAMIC
)
3481 SvLBoxTab
* SvTreeListBox::GetFirstDynamicTab() const
3484 return GetFirstDynamicTab( nDummy
);
3487 SvLBoxTab
* SvTreeListBox::GetTab( SvTreeListEntry
* pEntry
, SvLBoxItem
* pItem
) const
3489 sal_uInt16 nPos
= pEntry
->GetPos( pItem
);
3490 return aTabs
[ nPos
];
3493 void SvTreeListBox::ClearTabList()
3495 sal_uInt16 nTabCount
= aTabs
.size();
3499 SvLBoxTab
* pDelTab
= aTabs
[ nTabCount
];
3506 Size
SvTreeListBox::GetOutputSizePixel() const
3508 Size aSize
= pImp
->GetOutputSize();
3512 void SvTreeListBox::NotifyEndScroll()
3516 void SvTreeListBox::NotifyScrolled()
3518 aScrolledHdl
.Call( this );
3521 void SvTreeListBox::Invalidate( sal_uInt16 nInvalidateFlags
)
3525 if( nFocusWidth
== -1 )
3526 // to make sure that the control doesn't show the wrong focus rectangle
3528 pImp
->RecalcFocusRect();
3529 Control::Invalidate( nInvalidateFlags
);
3533 void SvTreeListBox::Invalidate( const Rectangle
& rRect
, sal_uInt16 nInvalidateFlags
)
3535 if( nFocusWidth
== -1 )
3536 // to make sure that the control doesn't show the wrong focus rectangle
3538 pImp
->RecalcFocusRect();
3539 Control::Invalidate( rRect
, nInvalidateFlags
);
3543 void SvTreeListBox::SetHighlightRange( sal_uInt16 nStart
, sal_uInt16 nEnd
)
3547 nTreeFlags
|= SvTreeFlags::USESEL
;
3554 // select all tabs that lie within the area
3555 nTreeFlags
|= SvTreeFlags::RECALCTABS
;
3556 nFirstSelTab
= nStart
;
3558 pImp
->RecalcFocusRect();
3561 void SvTreeListBox::Command( const CommandEvent
& rCEvt
)
3563 // FIXME gnumake2 resync to DEV300_m84
3564 pImp
->Command( rCEvt
);
3568 void SvTreeListBox::RemoveParentKeepChildren( SvTreeListEntry
* pParent
)
3570 DBG_ASSERT(pParent
,"RemoveParentKeepChildren:No Parent");
3571 SvTreeListEntry
* pNewParent
= GetParent( pParent
);
3572 if( pParent
->HasChildren())
3574 SvTreeListEntry
* pChild
= FirstChild( pParent
);
3577 pModel
->Move( pChild
, pNewParent
, TREELIST_APPEND
);
3578 pChild
= FirstChild( pParent
);
3581 pModel
->Remove( pParent
);
3584 SvLBoxTab
* SvTreeListBox::GetFirstTab( SvLBoxTabFlags nFlagMask
, sal_uInt16
& rPos
)
3586 sal_uInt16 nTabCount
= aTabs
.size();
3587 for( sal_uInt16 nPos
= 0; nPos
< nTabCount
; nPos
++ )
3589 SvLBoxTab
* pTab
= aTabs
[ nPos
];
3590 if( (pTab
->nFlags
& nFlagMask
) )
3600 SvLBoxTab
* SvTreeListBox::GetLastTab( SvLBoxTabFlags nFlagMask
, sal_uInt16
& rTabPos
)
3602 sal_uInt16 nPos
= (sal_uInt16
)aTabs
.size();
3606 SvLBoxTab
* pTab
= aTabs
[ nPos
];
3607 if( (pTab
->nFlags
& nFlagMask
) )
3617 void SvTreeListBox::RequestHelp( const HelpEvent
& rHEvt
)
3619 if( !pImp
->RequestHelp( rHEvt
) )
3620 Control::RequestHelp( rHEvt
);
3623 IMPL_LINK( SvTreeListBox
, DefaultCompare
, SvSortData
*, pData
)
3625 const SvTreeListEntry
* pLeft
= pData
->pLeft
;
3626 const SvTreeListEntry
* pRight
= pData
->pRight
;
3627 OUString
aLeft( static_cast<const SvLBoxString
*>(pLeft
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
))->GetText());
3628 OUString
aRight( static_cast<const SvLBoxString
*>(pRight
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
))->GetText());
3629 pImp
->UpdateStringSorter();
3630 return pImp
->m_pStringSorter
->compare(aLeft
, aRight
);
3633 void SvTreeListBox::ModelNotification( SvListAction nActionId
, SvTreeListEntry
* pEntry1
,
3634 SvTreeListEntry
* pEntry2
, sal_uLong nPos
)
3636 SolarMutexGuard aSolarGuard
;
3638 if( nActionId
== SvListAction::CLEARING
)
3639 CancelTextEditing();
3641 SvListView::ModelNotification( nActionId
, pEntry1
, pEntry2
, nPos
);
3644 case SvListAction::INSERTED
:
3646 SvTreeListEntry
* pEntry( dynamic_cast< SvTreeListEntry
* >( pEntry1
) );
3649 SAL_WARN( "svtools.contnr", "SvTreeListBox::ModelNotification: invalid entry!" );
3653 SvLBoxContextBmp
* pBmpItem
= static_cast< SvLBoxContextBmp
* >( pEntry
->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP
) );
3656 const Image
& rBitmap1( pBmpItem
->GetBitmap1() );
3657 const Image
& rBitmap2( pBmpItem
->GetBitmap2() );
3658 short nMaxWidth
= short( std::max( rBitmap1
.GetSizePixel().Width(), rBitmap2
.GetSizePixel().Width() ) );
3659 nMaxWidth
= pImp
->UpdateContextBmpWidthVector( pEntry
, nMaxWidth
);
3660 if( nMaxWidth
> nContextBmpWidthMax
)
3662 nContextBmpWidthMax
= nMaxWidth
;
3665 if (get_width_request() == -1)
3670 case SvListAction::RESORTING
:
3671 SetUpdateMode( false );
3674 case SvListAction::RESORTED
:
3675 // after a selection: show first entry and also keep the selection
3676 MakeVisible( pModel
->First(), true );
3677 SetUpdateMode( true );
3680 case SvListAction::CLEARED
:
3681 if( IsUpdateMode() )
3689 void SvTreeListBox::EndSelection()
3691 pImp
->EndSelection();
3694 ScrollBar
*SvTreeListBox::GetVScroll()
3696 return pImp
->aVerSBar
.get();
3699 ScrollBar
*SvTreeListBox::GetHScroll()
3701 return pImp
->aHorSBar
.get();
3704 void SvTreeListBox::EnableAsyncDrag( bool b
)
3706 pImp
->EnableAsyncDrag( b
);
3709 SvTreeListEntry
* SvTreeListBox::GetFirstEntryInView() const
3712 return GetEntry( aPos
);
3715 SvTreeListEntry
* SvTreeListBox::GetNextEntryInView(SvTreeListEntry
* pEntry
) const
3717 SvTreeListEntry
* pNext
= NextVisible( pEntry
);
3720 Point
aPos( GetEntryPosition(pNext
) );
3721 const Size
& rSize
= pImp
->GetOutputSize();
3722 if( aPos
.Y() < 0 || aPos
.Y() >= rSize
.Height() )
3728 SvTreeListEntry
* SvTreeListBox::GetLastEntryInView() const
3730 SvTreeListEntry
* pEntry
= GetFirstEntryInView();
3731 SvTreeListEntry
* pNext
= 0;
3734 pNext
= NextVisible( pEntry
);
3737 Point
aPos( GetEntryPosition(pNext
) );
3738 const Size
& rSize
= pImp
->GetOutputSize();
3739 if( aPos
.Y() < 0 || aPos
.Y() + GetEntryHeight() >= rSize
.Height() )
3750 void SvTreeListBox::ShowFocusRect( const SvTreeListEntry
* pEntry
)
3752 pImp
->ShowFocusRect( pEntry
);
3755 void SvTreeListBox::DataChanged( const DataChangedEvent
& rDCEvt
)
3757 if( (rDCEvt
.GetType()==DataChangedEventType::SETTINGS
) && (rDCEvt
.GetFlags() & AllSettingsFlags::STYLE
) )
3759 nEntryHeight
= 0; // _together_ with true of 1. par (bFont) of InitSettings() a zero-height
3760 // forces complete recalc of heights!
3761 InitSettings( true, true, true );
3765 Control::DataChanged( rDCEvt
);
3768 void SvTreeListBox::StateChanged( StateChangedType eType
)
3770 if( eType
== StateChangedType::Enable
)
3771 Invalidate( INVALIDATE_CHILDREN
);
3773 Control::StateChanged( eType
);
3775 if ( eType
== StateChangedType::Style
)
3779 void SvTreeListBox::ApplySettings(vcl::RenderContext
& rRenderContext
)
3781 const StyleSettings
& rStyleSettings
= rRenderContext
.GetSettings().GetStyleSettings();
3783 aFont
= rStyleSettings
.GetFieldFont();
3784 aFont
.SetColor(rStyleSettings
.GetWindowTextColor());
3785 SetPointFont(rRenderContext
, aFont
);
3786 AdjustEntryHeightAndRecalc(aFont
);
3788 rRenderContext
.SetTextColor(rStyleSettings
.GetFieldTextColor());
3789 rRenderContext
.SetTextFillColor();
3790 rRenderContext
.SetBackground(rStyleSettings
.GetFieldColor());
3792 // always try to re-create default-SvLBoxButtonData
3793 if (pCheckButtonData
&& pCheckButtonData
->HasDefaultImages())
3794 pCheckButtonData
->SetDefaultImages(this);
3797 void SvTreeListBox::InitSettings(bool bFont
, bool bForeground
, bool bBackground
)
3799 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
3803 aFont
= rStyleSettings
.GetFieldFont();
3804 aFont
.SetColor(rStyleSettings
.GetWindowTextColor());
3805 SetPointFont(*this, aFont
);
3806 AdjustEntryHeightAndRecalc(aFont
);
3809 if (bForeground
|| bFont
)
3811 SetTextColor(rStyleSettings
.GetFieldTextColor());
3816 SetBackground(rStyleSettings
.GetFieldColor());
3818 // always try to re-create default-SvLBoxButtonData
3819 if( pCheckButtonData
&& pCheckButtonData
->HasDefaultImages() )
3820 pCheckButtonData
->SetDefaultImages(this);
3823 bool SvTreeListBox::IsCellFocusEnabled() const
3825 return pImp
->IsCellFocusEnabled();
3828 bool SvTreeListBox::SetCurrentTabPos( sal_uInt16 _nNewPos
)
3830 return pImp
->SetCurrentTabPos( _nNewPos
);
3833 sal_uInt16
SvTreeListBox::GetCurrentTabPos() const
3835 return pImp
->GetCurrentTabPos();
3838 void SvTreeListBox::InitStartEntry()
3840 if( !pImp
->pStartEntry
)
3841 pImp
->pStartEntry
= GetModel()->First();
3844 PopupMenu
* SvTreeListBox::CreateContextMenu()
3849 void SvTreeListBox::ExcecuteContextMenuAction( sal_uInt16
)
3851 DBG_WARNING( "SvTreeListBox::ExcecuteContextMenuAction(): now there's happening nothing!" );
3854 void SvTreeListBox::EnableContextMenuHandling()
3856 assert(pImp
&& "-SvTreeListBox::EnableContextMenuHandling(): No implementation!");
3857 pImp
->bContextMenuHandling
= true;
3860 void SvTreeListBox::EnableList( bool _bEnable
)
3862 // call base class method
3863 Window::Enable(_bEnable
);
3865 Invalidate(Rectangle(Point(), GetSizePixel()));
3868 ::com::sun::star::uno::Reference
< XAccessible
> SvTreeListBox::CreateAccessible()
3870 vcl::Window
* pParent
= GetAccessibleParentWindow();
3871 DBG_ASSERT( pParent
, "SvTreeListBox::CreateAccessible - accessible parent not found" );
3873 ::com::sun::star::uno::Reference
< XAccessible
> xAccessible
;
3876 ::com::sun::star::uno::Reference
< XAccessible
> xAccParent
= pParent
->GetAccessible();
3877 if ( xAccParent
.is() )
3879 // need to be done here to get the vclxwindow later on in the accessbile
3880 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindowPeer
> xTemp(GetComponentInterface());
3881 xAccessible
= pImp
->m_aFactoryAccess
.getFactory().createAccessibleTreeListBox( *this, xAccParent
);
3887 void SvTreeListBox::FillAccessibleEntryStateSet( SvTreeListEntry
* pEntry
, ::utl::AccessibleStateSetHelper
& rStateSet
) const
3889 assert(pEntry
&& "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry");
3891 if ( pEntry
->HasChildrenOnDemand() || pEntry
->HasChildren() )
3893 rStateSet
.AddState( AccessibleStateType::EXPANDABLE
);
3894 if ( IsExpanded( pEntry
) )
3895 rStateSet
.AddState( (sal_Int16
)AccessibleStateType::EXPANDED
);
3898 if ( GetCheckButtonState( pEntry
) == SV_BUTTON_CHECKED
)
3899 rStateSet
.AddState( AccessibleStateType::CHECKED
);
3900 if ( IsEntryVisible( pEntry
) )
3901 rStateSet
.AddState( AccessibleStateType::VISIBLE
);
3902 if ( IsSelected( pEntry
) )
3903 rStateSet
.AddState( AccessibleStateType::SELECTED
);
3906 rStateSet
.AddState( AccessibleStateType::ENABLED
);
3907 rStateSet
.AddState( AccessibleStateType::FOCUSABLE
);
3908 rStateSet
.AddState( AccessibleStateType::SELECTABLE
);
3909 SvViewDataEntry
* pViewDataNewCur
= GetViewDataEntry(pEntry
);
3910 if (pViewDataNewCur
&& pViewDataNewCur
->HasFocus())
3911 rStateSet
.AddState( AccessibleStateType::FOCUSED
);
3915 Rectangle
SvTreeListBox::GetBoundingRect( SvTreeListEntry
* pEntry
)
3917 Point aPos
= GetEntryPosition( pEntry
);
3918 Rectangle aRect
= GetFocusRect( pEntry
, aPos
.Y() );
3922 void SvTreeListBox::EnableCellFocus()
3924 pImp
->EnableCellFocus();
3927 void SvTreeListBox::CallImplEventListeners(sal_uLong nEvent
, void* pData
)
3929 CallEventListeners(nEvent
, pData
);
3932 void SvTreeListBox::set_min_width_in_chars(sal_Int32 nChars
)
3934 nMinWidthInChars
= nChars
;
3938 bool SvTreeListBox::set_property(const OString
&rKey
, const OString
&rValue
)
3940 if (rKey
== "min-width-chars")
3942 set_min_width_in_chars(rValue
.toInt32());
3945 return Control::set_property(rKey
, rValue
);
3949 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */