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( sal_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/builder.hxx>
32 #include <sot/formats.hxx>
33 #include <unotools/accessiblestatesethelper.hxx>
34 #include <rtl/instance.hxx>
35 #include <comphelper/string.hxx>
37 #include <svtools/svmedit.hxx>
38 #include <svtools/svlbitm.hxx>
39 #include "svtools/treelistentry.hxx"
40 #include "svtools/viewdataentry.hxx"
41 #include "svimpbox.hxx"
47 using namespace ::com::sun::star::accessibility
;
50 static SvTreeListBox
* pDDSource
= NULL
;
51 static SvTreeListBox
* pDDTarget
= NULL
;
53 DBG_NAME(SvInplaceEdit2
)
55 #define SVLBOX_ACC_RETURN 1
56 #define SVLBOX_ACC_ESCAPE 2
58 // ***************************************************************
60 class MyEdit_Impl
: public Edit
62 SvInplaceEdit2
* pOwner
;
64 MyEdit_Impl( Window
* pParent
, SvInplaceEdit2
* pOwner
);
65 virtual void KeyInput( const KeyEvent
& rKEvt
);
66 virtual void LoseFocus();
69 class MyMultiEdit_Impl
: public MultiLineEdit
71 SvInplaceEdit2
* pOwner
;
73 MyMultiEdit_Impl( Window
* pParent
, SvInplaceEdit2
* pOwner
);
74 virtual void KeyInput( const KeyEvent
& rKEvt
);
75 virtual void LoseFocus();
78 MyEdit_Impl::MyEdit_Impl( Window
* pParent
, SvInplaceEdit2
* _pOwner
) :
80 Edit( pParent
, WB_LEFT
),
87 void MyEdit_Impl::KeyInput( const KeyEvent
& rKEvt
)
89 if( !pOwner
->KeyInput( rKEvt
))
90 Edit::KeyInput( rKEvt
);
93 void MyEdit_Impl::LoseFocus()
98 MyMultiEdit_Impl::MyMultiEdit_Impl( Window
* pParent
, SvInplaceEdit2
* _pOwner
)
99 : MultiLineEdit( pParent
,
105 void MyMultiEdit_Impl::KeyInput( const KeyEvent
& rKEvt
)
107 if( !pOwner
->KeyInput( rKEvt
))
108 MultiLineEdit::KeyInput( rKEvt
);
111 void MyMultiEdit_Impl::LoseFocus()
117 SvInplaceEdit2::SvInplaceEdit2
119 Window
* pParent
, const Point
& rPos
,
122 const Link
& rNotifyEditEnd
,
123 const Selection
& rSelection
,
127 aCallBackHdl ( rNotifyEditEnd
),
128 bCanceled ( sal_False
),
129 bAlreadyInCallBack ( sal_False
)
132 DBG_CTOR(SvInplaceEdit2
,0);
135 pEdit
= new MyMultiEdit_Impl( pParent
, this );
137 pEdit
= new MyEdit_Impl( pParent
, this );
139 Font
aFont( pParent
->GetFont() );
140 aFont
.SetTransparent( sal_False
);
141 Color
aColor( pParent
->GetBackground().GetColor() );
142 aFont
.SetFillColor(aColor
);
143 pEdit
->SetFont( aFont
);
144 pEdit
->SetBackground( pParent
->GetBackground() );
145 pEdit
->SetPosPixel( rPos
);
146 pEdit
->SetSizePixel( rSize
);
147 pEdit
->SetText( rData
);
148 pEdit
->SetSelection( rSelection
);
151 aAccReturn
.InsertItem( SVLBOX_ACC_RETURN
, KeyCode(KEY_RETURN
) );
152 aAccEscape
.InsertItem( SVLBOX_ACC_ESCAPE
, KeyCode(KEY_ESCAPE
) );
154 aAccReturn
.SetActivateHdl( LINK( this, SvInplaceEdit2
, ReturnHdl_Impl
) );
155 aAccEscape
.SetActivateHdl( LINK( this, SvInplaceEdit2
, EscapeHdl_Impl
) );
156 GetpApp()->InsertAccel( &aAccReturn
);
157 GetpApp()->InsertAccel( &aAccEscape
);
163 SvInplaceEdit2::~SvInplaceEdit2()
165 DBG_DTOR(SvInplaceEdit2
,0);
166 if( !bAlreadyInCallBack
)
168 GetpApp()->RemoveAccel( &aAccReturn
);
169 GetpApp()->RemoveAccel( &aAccEscape
);
174 String
SvInplaceEdit2::GetSavedValue() const
176 return pEdit
->GetSavedValue();
179 void SvInplaceEdit2::Hide()
185 IMPL_LINK_NOARG_INLINE_START(SvInplaceEdit2
, ReturnHdl_Impl
)
187 DBG_CHKTHIS(SvInplaceEdit2
,0);
188 bCanceled
= sal_False
;
189 CallCallBackHdl_Impl();
192 IMPL_LINK_NOARG_INLINE_END(SvInplaceEdit2
, ReturnHdl_Impl
)
194 IMPL_LINK_NOARG_INLINE_START(SvInplaceEdit2
, EscapeHdl_Impl
)
196 DBG_CHKTHIS(SvInplaceEdit2
,0);
197 bCanceled
= sal_True
;
198 CallCallBackHdl_Impl();
201 IMPL_LINK_NOARG_INLINE_END(SvInplaceEdit2
, EscapeHdl_Impl
)
204 sal_Bool
SvInplaceEdit2::KeyInput( const KeyEvent
& rKEvt
)
206 DBG_CHKTHIS(SvInplaceEdit2
,0);
207 KeyCode aCode
= rKEvt
.GetKeyCode();
208 sal_uInt16 nCode
= aCode
.GetCode();
213 bCanceled
= sal_True
;
214 CallCallBackHdl_Impl();
218 bCanceled
= sal_False
;
219 CallCallBackHdl_Impl();
225 void SvInplaceEdit2::StopEditing( sal_Bool bCancel
)
227 DBG_CHKTHIS(SvInplaceEdit2
,0);
228 if ( !bAlreadyInCallBack
)
231 CallCallBackHdl_Impl();
235 void SvInplaceEdit2::LoseFocus()
237 DBG_CHKTHIS(SvInplaceEdit2
,0);
238 if ( !bAlreadyInCallBack
239 && ((!Application::GetFocusWindow()) || !pEdit
->IsChild( Application::GetFocusWindow()) )
242 bCanceled
= sal_False
;
243 aTimer
.SetTimeout(10);
244 aTimer
.SetTimeoutHdl(LINK(this,SvInplaceEdit2
,Timeout_Impl
));
249 IMPL_LINK_NOARG_INLINE_START(SvInplaceEdit2
, Timeout_Impl
)
251 DBG_CHKTHIS(SvInplaceEdit2
,0);
252 CallCallBackHdl_Impl();
255 IMPL_LINK_NOARG_INLINE_END(SvInplaceEdit2
, Timeout_Impl
)
257 void SvInplaceEdit2::CallCallBackHdl_Impl()
259 DBG_CHKTHIS(SvInplaceEdit2
,0);
261 if ( !bAlreadyInCallBack
)
263 bAlreadyInCallBack
= sal_True
;
264 GetpApp()->RemoveAccel( &aAccReturn
);
265 GetpApp()->RemoveAccel( &aAccEscape
);
267 aCallBackHdl
.Call( this );
271 OUString
SvInplaceEdit2::GetText() const
273 return pEdit
->GetText();
276 // ***************************************************************
278 // ***************************************************************
282 SvLBoxTab::SvLBoxTab()
284 DBG_CTOR(SvLBoxTab
,0);
290 SvLBoxTab::SvLBoxTab( long nPosition
, sal_uInt16 nTabFlags
)
292 DBG_CTOR(SvLBoxTab
,0);
298 SvLBoxTab::SvLBoxTab( const SvLBoxTab
& rTab
)
300 DBG_CTOR(SvLBoxTab
,0);
302 pUserData
= rTab
.pUserData
;
303 nFlags
= rTab
.nFlags
;
306 SvLBoxTab::~SvLBoxTab()
308 DBG_DTOR(SvLBoxTab
,0);
312 long SvLBoxTab::CalcOffset( long nItemWidth
, long nTabWidth
)
314 DBG_CHKTHIS(SvLBoxTab
,0);
316 if ( nFlags
& SV_LBOXTAB_ADJUST_RIGHT
)
318 nOffset
= nTabWidth
- nItemWidth
;
322 else if ( nFlags
& SV_LBOXTAB_ADJUST_CENTER
)
324 if( nFlags
& SV_LBOXTAB_FORCE
)
326 // correct implementation of centering
327 nOffset
= ( nTabWidth
- nItemWidth
) / 2;
333 // historically grown, wrong calculation of tabs which is needed by
334 // Abo-Tabbox, Tools/Options/Customize etc.
336 nOffset
= -( nItemWidth
/ 2 );
342 // ***************************************************************
344 // ***************************************************************
346 DBG_NAME(SvLBoxItem
);
348 SvLBoxItem::SvLBoxItem( SvTreeListEntry
*, sal_uInt16
)
350 DBG_CTOR(SvLBoxItem
,0);
353 SvLBoxItem::SvLBoxItem()
355 DBG_CTOR(SvLBoxItem
,0);
358 SvLBoxItem::~SvLBoxItem()
360 DBG_DTOR(SvLBoxItem
,0);
363 const Size
& SvLBoxItem::GetSize(const SvTreeListBox
* pView
, const SvTreeListEntry
* pEntry
) const
365 DBG_CHKTHIS(SvLBoxItem
,0);
366 const SvViewDataItem
* pViewData
= pView
->GetViewDataItem( pEntry
, this );
367 return pViewData
->maSize
;
370 const Size
& SvLBoxItem::GetSize(const SvViewDataEntry
* pData
, sal_uInt16 nItemPos
) const
372 const SvViewDataItem
* pIData
= pData
->GetItem(nItemPos
);
373 return pIData
->maSize
;
376 struct SvTreeListBoxImpl
378 bool m_bIsEmptyTextAllowed
:1;
379 bool m_bEntryMnemonicsEnabled
:1;
380 bool m_bDoingQuickSelection
:1;
384 vcl::MnemonicEngine m_aMnemonicEngine
;
385 vcl::QuickSelectionEngine m_aQuickSelectionEngine
;
387 SvTreeListBoxImpl(SvTreeListBox
& _rBox
) :
388 m_bIsEmptyTextAllowed(true),
389 m_bEntryMnemonicsEnabled(false),
390 m_bDoingQuickSelection(false),
392 m_aMnemonicEngine(_rBox
),
393 m_aQuickSelectionEngine(_rBox
) {}
396 DBG_NAME(SvTreeListBox
);
398 SvTreeListBox::SvTreeListBox(Window
* pParent
, WinBits nWinStyle
) :
399 Control(pParent
, nWinStyle
| WB_CLIPCHILDREN
),
400 DropTargetHelper(this),
401 DragSourceHelper(this),
402 mpImpl(new SvTreeListBoxImpl(*this)),
403 mbContextBmpExpanded(false),
404 eSelMode(NO_SELECTION
)
406 DBG_CTOR(SvTreeListBox
,0);
407 nDragOptions
= DND_ACTION_COPYMOVE
| DND_ACTION_LINK
;
411 SvTreeList
* pTempModel
= new SvTreeList
;
412 pTempModel
->SetRefCount( 0 );
413 SetBaseModel(pTempModel
);
414 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
415 pModel
->InsertView( this );
418 eSelMode
= SINGLE_SELECTION
;
419 nDragDropMode
= SV_DRAGDROP_NONE
;
420 SetType(WINDOW_TREELISTBOX
);
424 SetSublistOpenWithLeftRight();
427 SvTreeListBox::SvTreeListBox(Window
* pParent
, const ResId
& rResId
) :
428 Control(pParent
, rResId
),
429 DropTargetHelper(this),
430 DragSourceHelper(this),
431 mpImpl(new SvTreeListBoxImpl(*this)),
432 mbContextBmpExpanded(false),
433 eSelMode(NO_SELECTION
)
435 DBG_CTOR(SvTreeListBox
,0);
438 nDragOptions
= DND_ACTION_COPYMOVE
| DND_ACTION_LINK
;
440 SvTreeList
* pTempModel
= new SvTreeList
;
441 pTempModel
->SetRefCount( 0 );
442 SetBaseModel(pTempModel
);
443 pModel
->InsertView( this );
446 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
447 SetType(WINDOW_TREELISTBOX
);
452 SetSublistOpenWithLeftRight();
455 extern "C" SAL_DLLPUBLIC_EXPORT Window
* SAL_CALL
makeSvTreeListBox(Window
*pParent
, VclBuilder::stringmap
&rMap
)
457 WinBits nWinStyle
= WB_TABSTOP
;
458 OString sBorder
= VclBuilder::extractCustomProperty(rMap
);
459 if (!sBorder
.isEmpty())
460 nWinStyle
|= WB_BORDER
;
461 return new SvTreeListBox(pParent
, nWinStyle
);
464 void SvTreeListBox::Clear()
466 DBG_CHKTHIS(SvTreeListBox
,0);
467 pModel
->Clear(); // Model calls SvTreeListBox::ModelHasCleared()
470 void SvTreeListBox::EnableEntryMnemonics( bool _bEnable
)
472 if ( _bEnable
== IsEntryMnemonicsEnabled() )
475 mpImpl
->m_bEntryMnemonicsEnabled
= _bEnable
;
479 bool SvTreeListBox::IsEntryMnemonicsEnabled() const
481 return mpImpl
->m_bEntryMnemonicsEnabled
;
484 IMPL_LINK_INLINE_START( SvTreeListBox
, CloneHdl_Impl
, SvTreeListEntry
*, pEntry
)
486 DBG_CHKTHIS(SvTreeListBox
,0);
487 return (long)(CloneEntry((SvTreeListEntry
*)pEntry
));
489 IMPL_LINK_INLINE_END( SvTreeListBox
, CloneHdl_Impl
, SvTreeListEntry
*, pEntry
)
491 sal_uLong
SvTreeListBox::Insert( SvTreeListEntry
* pEntry
, SvTreeListEntry
* pParent
, sal_uLong nPos
)
493 DBG_CHKTHIS(SvTreeListBox
,0);
494 sal_uLong nInsPos
= pModel
->Insert( pEntry
, pParent
, nPos
);
498 sal_uLong
SvTreeListBox::Insert( SvTreeListEntry
* pEntry
,sal_uLong nRootPos
)
500 DBG_CHKTHIS(SvTreeListBox
,0);
501 sal_uLong nInsPos
= pModel
->Insert( pEntry
, nRootPos
);
505 long SvTreeListBox::ExpandingHdl()
507 DBG_CHKTHIS(SvTreeListBox
,0);
508 return aExpandingHdl
.IsSet() ? aExpandingHdl
.Call( this ) : 1;
511 void SvTreeListBox::ExpandedHdl()
513 DBG_CHKTHIS(SvTreeListBox
,0);
514 aExpandedHdl
.Call( this );
517 void SvTreeListBox::SelectHdl()
519 DBG_CHKTHIS(SvTreeListBox
,0);
520 aSelectHdl
.Call( this );
523 void SvTreeListBox::DeselectHdl()
525 DBG_CHKTHIS(SvTreeListBox
,0);
526 aDeselectHdl
.Call( this );
529 sal_Bool
SvTreeListBox::DoubleClickHdl()
531 DBG_CHKTHIS(SvTreeListBox
,0);
532 aDoubleClickHdl
.Call( this );
537 sal_Bool
SvTreeListBox::CheckDragAndDropMode( SvTreeListBox
* pSource
, sal_Int8 nAction
)
539 DBG_CHKTHIS(SvTreeListBox
,0);
540 if ( pSource
== this )
542 if ( !(nDragDropMode
& (SV_DRAGDROP_CTRL_MOVE
| SV_DRAGDROP_CTRL_COPY
) ) )
543 return sal_False
; // D&D locked within list
544 if( DND_ACTION_MOVE
== nAction
)
546 if ( !(nDragDropMode
& SV_DRAGDROP_CTRL_MOVE
) )
547 return sal_False
; // no local move
551 if ( !(nDragDropMode
& SV_DRAGDROP_CTRL_COPY
))
552 return sal_False
; // no local copy
557 if ( !(nDragDropMode
& SV_DRAGDROP_APP_DROP
) )
558 return sal_False
; // no drop
559 if ( DND_ACTION_MOVE
== nAction
)
561 if ( !(nDragDropMode
& SV_DRAGDROP_APP_MOVE
) )
562 return sal_False
; // no global move
566 if ( !(nDragDropMode
& SV_DRAGDROP_APP_COPY
))
567 return sal_False
; // no global copy
576 void SvTreeListBox::NotifyRemoving( SvTreeListEntry
* )
578 DBG_CHKTHIS(SvTreeListBox
,0);
587 1. target doesn't have children
588 - entry becomes sibling of target. entry comes after target
589 (->Window: below the target)
590 2. target is an expanded parent
591 - entry inserted at the beginning of the target childlist
592 3. target is a collapsed parent
593 - entry is inserted at the end of the target childlist
596 sal_Bool
SvTreeListBox::NotifyMoving(
597 SvTreeListEntry
* pTarget
, // D&D dropping position in this->GetModel()
598 SvTreeListEntry
* pEntry
, // entry that we want to move, from
599 // GetSourceListBox()->GetModel()
600 SvTreeListEntry
*& rpNewParent
, // new target parent
601 sal_uLong
& rNewChildPos
) // position in childlist of target parent
603 sal_Bool
SvTreeListBox::NotifyMoving(
604 SvTreeListEntry
* pTarget
, // D&D dropping position in this->GetModel()
605 SvTreeListEntry
*, // entry that we want to move, from
606 // GetSourceListBox()->GetModel()
607 SvTreeListEntry
*& rpNewParent
, // new target parent
608 sal_uLong
& rNewChildPos
) // position in childlist of target parent
611 DBG_CHKTHIS(SvTreeListBox
,0);
612 DBG_ASSERT(pEntry
,"NotifyMoving:SoureEntry?");
619 if ( !pTarget
->HasChildren() && !pTarget
->HasChildrenOnDemand() )
622 rpNewParent
= GetParent( pTarget
);
623 rNewChildPos
= pModel
->GetRelPos( pTarget
) + 1;
624 rNewChildPos
+= nCurEntrySelPos
;
630 rpNewParent
= pTarget
;
631 if( IsExpanded(pTarget
))
634 rNewChildPos
= LIST_APPEND
;
639 sal_Bool
SvTreeListBox::NotifyCopying(
640 SvTreeListEntry
* pTarget
, // D&D dropping position in this->GetModel()
641 SvTreeListEntry
* pEntry
, // entry that we want to move, from
642 // GetSourceListBox()->GetModel()
643 SvTreeListEntry
*& rpNewParent
, // new target parent
644 sal_uLong
& rNewChildPos
) // position in childlist of target parent
646 DBG_CHKTHIS(SvTreeListBox
,0);
647 return NotifyMoving(pTarget
,pEntry
,rpNewParent
,rNewChildPos
);
650 SvTreeListEntry
* SvTreeListBox::FirstChild( SvTreeListEntry
* pParent
) const
652 return pModel
->FirstChild(pParent
);
655 SvTreeListEntry
* SvTreeListBox::NextSibling( SvTreeListEntry
* pEntry
) const
657 return pModel
->NextSibling(pEntry
);
660 SvTreeListEntry
* SvTreeListBox::PrevSibling( SvTreeListEntry
* pEntry
) const
662 return pModel
->PrevSibling(pEntry
);
665 // return: all entries copied
666 sal_Bool
SvTreeListBox::CopySelection( SvTreeListBox
* pSource
, SvTreeListEntry
* pTarget
)
668 DBG_CHKTHIS(SvTreeListBox
,0);
669 nCurEntrySelPos
= 0; // selection counter for NotifyMoving/Copying
670 sal_Bool bSuccess
= sal_True
;
671 std::vector
<SvTreeListEntry
*> aList
;
672 sal_Bool bClone
= (sal_Bool
)( (sal_uLong
)(pSource
->GetModel()) != (sal_uLong
)GetModel() );
673 Link
aCloneLink( pModel
->GetCloneLink() );
674 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
676 // cache selection to simplify iterating over the selection when doing a D&D
677 // exchange within the same listbox
678 SvTreeListEntry
* pSourceEntry
= pSource
->FirstSelected();
679 while ( pSourceEntry
)
681 // children are copied automatically
682 pSource
->SelectChildren( pSourceEntry
, sal_False
);
683 aList
.push_back( pSourceEntry
);
684 pSourceEntry
= pSource
->NextSelected( pSourceEntry
);
687 std::vector
<SvTreeListEntry
*>::const_iterator it
= aList
.begin(), itEnd
= aList
.end();
688 for (; it
!= itEnd
; ++it
)
691 SvTreeListEntry
* pNewParent
= 0;
692 sal_uLong nInsertionPos
= ULONG_MAX
;
693 sal_Bool bOk
=NotifyCopying(pTarget
,pSourceEntry
,pNewParent
,nInsertionPos
);
698 sal_uLong nCloneCount
= 0;
699 pSourceEntry
= pModel
->Clone(pSourceEntry
, nCloneCount
);
700 pModel
->InsertTree(pSourceEntry
, pNewParent
, nInsertionPos
);
704 sal_uLong nListPos
= pModel
->Copy(pSourceEntry
, pNewParent
, nInsertionPos
);
705 pSourceEntry
= GetEntry( pNewParent
, nListPos
);
709 bSuccess
= sal_False
;
711 if( bOk
== (sal_Bool
)2 ) // HACK: make visible moved entry?
712 MakeVisible( pSourceEntry
);
714 pModel
->SetCloneLink( aCloneLink
);
718 // return: all entries were moved
719 sal_Bool
SvTreeListBox::MoveSelection( SvTreeListBox
* pSource
, SvTreeListEntry
* pTarget
)
721 return MoveSelectionCopyFallbackPossible( pSource
, pTarget
, sal_False
);
724 sal_Bool
SvTreeListBox::MoveSelectionCopyFallbackPossible( SvTreeListBox
* pSource
, SvTreeListEntry
* pTarget
, sal_Bool bAllowCopyFallback
)
726 DBG_CHKTHIS(SvTreeListBox
,0);
727 nCurEntrySelPos
= 0; // selection counter for NotifyMoving/Copying
728 sal_Bool bSuccess
= sal_True
;
729 std::vector
<SvTreeListEntry
*> aList
;
730 sal_Bool bClone
= (sal_Bool
)( (sal_uLong
)(pSource
->GetModel()) != (sal_uLong
)GetModel() );
731 Link
aCloneLink( pModel
->GetCloneLink() );
733 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
735 SvTreeListEntry
* pSourceEntry
= pSource
->FirstSelected();
736 while ( pSourceEntry
)
738 // children are automatically moved
739 pSource
->SelectChildren( pSourceEntry
, sal_False
);
740 aList
.push_back( pSourceEntry
);
741 pSourceEntry
= pSource
->NextSelected( pSourceEntry
);
744 std::vector
<SvTreeListEntry
*>::const_iterator it
= aList
.begin(), itEnd
= aList
.end();
745 for (; it
!= itEnd
; ++it
)
749 SvTreeListEntry
* pNewParent
= 0;
750 sal_uLong nInsertionPos
= ULONG_MAX
;
751 sal_Bool bOk
= NotifyMoving(pTarget
,pSourceEntry
,pNewParent
,nInsertionPos
);
752 sal_Bool bCopyOk
= bOk
;
753 if ( !bOk
&& bAllowCopyFallback
)
755 nInsertionPos
= LIST_APPEND
;
756 bCopyOk
= NotifyCopying(pTarget
,pSourceEntry
,pNewParent
,nInsertionPos
);
759 if ( bOk
|| bCopyOk
)
763 sal_uLong nCloneCount
= 0;
764 pSourceEntry
= pModel
->Clone(pSourceEntry
, nCloneCount
);
765 pModel
->InsertTree(pSourceEntry
, pNewParent
, nInsertionPos
);
770 pModel
->Move(pSourceEntry
, pNewParent
, nInsertionPos
);
772 pModel
->Copy(pSourceEntry
, pNewParent
, nInsertionPos
);
776 bSuccess
= sal_False
;
778 if( bOk
== (sal_Bool
)2 ) // HACK: make moved entry visible?
779 MakeVisible( pSourceEntry
);
781 pModel
->SetCloneLink( aCloneLink
);
785 void SvTreeListBox::RemoveSelection()
787 DBG_CHKTHIS(SvTreeListBox
,0);
788 std::vector
<const SvTreeListEntry
*> aList
;
789 // cache selection, as the implementation deselects everything on the first
791 SvTreeListEntry
* pEntry
= FirstSelected();
794 aList
.push_back( pEntry
);
795 if ( pEntry
->HasChildren() )
796 // remove deletes all children automatically
797 SelectChildren(pEntry
, false);
798 pEntry
= NextSelected( pEntry
);
801 std::vector
<const SvTreeListEntry
*>::const_iterator it
= aList
.begin(), itEnd
= aList
.end();
802 for (; it
!= itEnd
; ++it
)
806 SvTreeListBox
* SvTreeListBox::GetSourceView() const
811 void SvTreeListBox::RecalcViewData()
813 DBG_CHKTHIS(SvTreeListBox
,0);
814 SvTreeListEntry
* pEntry
= First();
817 sal_uInt16 nCount
= pEntry
->ItemCount();
818 sal_uInt16 nCurPos
= 0;
819 while ( nCurPos
< nCount
)
821 SvLBoxItem
* pItem
= pEntry
->GetItem( nCurPos
);
822 pItem
->InitViewData( this, pEntry
);
825 ViewDataInitialized( pEntry
);
826 pEntry
= Next( pEntry
);
830 void SvTreeListBox::ViewDataInitialized( SvTreeListEntry
* )
832 DBG_CHKTHIS(SvTreeListBox
,0);
835 void SvTreeListBox::ImplShowTargetEmphasis( SvTreeListEntry
* pEntry
, sal_Bool bShow
)
837 DBG_CHKTHIS(SvTreeListBox
,0);
838 if ( bShow
&& (nImpFlags
& SVLBOX_TARGEMPH_VIS
) )
840 if ( !bShow
&& !(nImpFlags
& SVLBOX_TARGEMPH_VIS
) )
842 ShowTargetEmphasis( pEntry
, bShow
);
844 nImpFlags
|= SVLBOX_TARGEMPH_VIS
;
846 nImpFlags
&= ~SVLBOX_TARGEMPH_VIS
;
849 void SvTreeListBox::OnCurrentEntryChanged()
851 if ( !mpImpl
->m_bDoingQuickSelection
)
852 mpImpl
->m_aQuickSelectionEngine
.Reset();
855 SvTreeListEntry
* SvTreeListBox::GetEntry( SvTreeListEntry
* pParent
, sal_uLong nPos
) const
857 return pModel
->GetEntry(pParent
, nPos
);
860 SvTreeListEntry
* SvTreeListBox::GetEntry( sal_uLong nRootPos
) const
862 return pModel
->GetEntry(nRootPos
);
865 SvTreeListEntry
* SvTreeListBox::GetEntryFromPath( const ::std::deque
< sal_Int32
>& _rPath
) const
867 DBG_CHKTHIS(SvTreeListBox
,0);
869 SvTreeListEntry
* pEntry
= NULL
;
870 SvTreeListEntry
* pParent
= NULL
;
871 for( ::std::deque
< sal_Int32
>::const_iterator pItem
= _rPath
.begin(); pItem
!= _rPath
.end(); ++pItem
)
873 pEntry
= GetEntry( pParent
, *pItem
);
882 void SvTreeListBox::FillEntryPath( SvTreeListEntry
* pEntry
, ::std::deque
< sal_Int32
>& _rPath
) const
884 DBG_CHKTHIS(SvTreeListBox
,0);
888 SvTreeListEntry
* pParentEntry
= GetParent( pEntry
);
891 sal_uLong i
, nCount
= GetLevelChildCount( pParentEntry
);
892 for ( i
= 0; i
< nCount
; ++i
)
894 SvTreeListEntry
* pTemp
= GetEntry( pParentEntry
, i
);
895 DBG_ASSERT( pEntry
, "invalid entry" );
896 if ( pEntry
== pTemp
)
898 _rPath
.push_front( (sal_Int32
)i
);
905 pEntry
= pParentEntry
;
906 pParentEntry
= GetParent( pParentEntry
);
914 const SvTreeListEntry
* SvTreeListBox::GetParent( const SvTreeListEntry
* pEntry
) const
916 return pModel
->GetParent(pEntry
);
919 SvTreeListEntry
* SvTreeListBox::GetParent( SvTreeListEntry
* pEntry
) const
921 return pModel
->GetParent(pEntry
);
924 SvTreeListEntry
* SvTreeListBox::GetRootLevelParent( SvTreeListEntry
* pEntry
) const
926 return pModel
->GetRootLevelParent(pEntry
);
929 sal_uLong
SvTreeListBox::GetChildCount( SvTreeListEntry
* pParent
) const
931 return pModel
->GetChildCount(pParent
);
934 sal_uLong
SvTreeListBox::GetLevelChildCount( SvTreeListEntry
* _pParent
) const
936 DBG_CHKTHIS(SvTreeListBox
,0);
938 sal_uLong nCount
= 0;
939 SvTreeListEntry
* pEntry
= FirstChild( _pParent
);
943 pEntry
= NextSibling( pEntry
);
949 SvViewDataEntry
* SvTreeListBox::GetViewDataEntry( SvTreeListEntry
* pEntry
) const
951 return (SvViewDataEntry
*)SvListView::GetViewData(pEntry
);
954 SvViewDataItem
* SvTreeListBox::GetViewDataItem(SvTreeListEntry
* pEntry
, SvLBoxItem
* pItem
)
956 return const_cast<SvViewDataItem
*>(static_cast<const SvTreeListBox
*>(this)->GetViewDataItem(pEntry
, pItem
));
959 const SvViewDataItem
* SvTreeListBox::GetViewDataItem(const SvTreeListEntry
* pEntry
, const SvLBoxItem
* pItem
) const
961 const SvViewDataEntry
* pEntryData
= (const SvViewDataEntry
*)SvListView::GetViewData(pEntry
);
962 DBG_ASSERT(pEntryData
,"Entry not in View");
963 sal_uInt16 nItemPos
= pEntry
->GetPos(pItem
);
964 return pEntryData
->GetItem(nItemPos
);
967 SvViewDataEntry
* SvTreeListBox::CreateViewData( SvTreeListEntry
* )
969 DBG_CHKTHIS(SvTreeListBox
,0);
970 SvViewDataEntry
* pEntryData
= new SvViewDataEntry
;
971 return (SvViewDataEntry
*)pEntryData
;
974 void SvTreeListBox::InitViewData( SvViewDataEntry
* pData
, SvTreeListEntry
* pEntry
)
976 DBG_CHKTHIS(SvTreeListBox
,0);
977 SvTreeListEntry
* pInhEntry
= (SvTreeListEntry
*)pEntry
;
978 SvViewDataEntry
* pEntryData
= (SvViewDataEntry
*)pData
;
980 pEntryData
->Init(pInhEntry
->ItemCount());
981 sal_uInt16 nCount
= pInhEntry
->ItemCount();
982 sal_uInt16 nCurPos
= 0;
983 while( nCurPos
< nCount
)
985 SvLBoxItem
* pItem
= pInhEntry
->GetItem( nCurPos
);
986 SvViewDataItem
* pItemData
= pEntryData
->GetItem(nCurPos
);
987 pItem
->InitViewData( this, pInhEntry
, pItemData
);
995 void SvTreeListBox::EnableSelectionAsDropTarget( sal_Bool bEnable
, sal_Bool bWithChildren
)
997 DBG_CHKTHIS(SvTreeListBox
,0);
998 sal_uInt16 nRefDepth
;
999 SvTreeListEntry
* pTemp
;
1001 SvTreeListEntry
* pSelEntry
= FirstSelected();
1006 pSelEntry
->nEntryFlags
|= SV_ENTRYFLAG_DISABLE_DROP
;
1007 if ( bWithChildren
)
1009 nRefDepth
= pModel
->GetDepth( pSelEntry
);
1010 pTemp
= Next( pSelEntry
);
1011 while( pTemp
&& pModel
->GetDepth( pTemp
) > nRefDepth
)
1013 pTemp
->nEntryFlags
|= SV_ENTRYFLAG_DISABLE_DROP
;
1014 pTemp
= Next( pTemp
);
1020 pSelEntry
->nEntryFlags
&= (~SV_ENTRYFLAG_DISABLE_DROP
);
1021 if ( bWithChildren
)
1023 nRefDepth
= pModel
->GetDepth( pSelEntry
);
1024 pTemp
= Next( pSelEntry
);
1025 while( pTemp
&& pModel
->GetDepth( pTemp
) > nRefDepth
)
1027 pTemp
->nEntryFlags
&= (~SV_ENTRYFLAG_DISABLE_DROP
);
1028 pTemp
= Next( pTemp
);
1032 pSelEntry
= NextSelected( pSelEntry
);
1036 // ******************************************************************
1038 // ******************************************************************
1040 void SvTreeListBox::EditText( const String
& rStr
, const Rectangle
& rRect
,
1041 const Selection
& rSel
)
1043 EditText( rStr
, rRect
, rSel
, sal_False
);
1046 void SvTreeListBox::EditText( const String
& rStr
, const Rectangle
& rRect
,
1047 const Selection
& rSel
, sal_Bool bMulti
)
1049 DBG_CHKTHIS(SvTreeListBox
,0);
1052 nImpFlags
|= SVLBOX_IN_EDT
;
1053 nImpFlags
&= ~SVLBOX_EDTEND_CALLED
;
1055 pEdCtrl
= new SvInplaceEdit2(
1056 this, rRect
.TopLeft(), rRect
.GetSize(), rStr
,
1057 LINK( this, SvTreeListBox
, TextEditEndedHdl_Impl
),
1061 IMPL_LINK_NOARG(SvTreeListBox
, TextEditEndedHdl_Impl
)
1063 DBG_CHKTHIS(SvTreeListBox
,0);
1064 if ( nImpFlags
& SVLBOX_EDTEND_CALLED
) // avoid nesting
1066 nImpFlags
|= SVLBOX_EDTEND_CALLED
;
1068 if ( !pEdCtrl
->EditingCanceled() )
1069 aStr
= pEdCtrl
->GetText();
1071 aStr
= pEdCtrl
->GetSavedValue();
1072 if ( IsEmptyTextAllowed() || aStr
.Len() > 0 )
1074 // Hide may only be called after the new text was put into the entry, so
1075 // that we don't call the selection handler in the GetFocus of the listbox
1076 // with the old entry text.
1080 nImpFlags
&= (~SVLBOX_IN_EDT
);
1085 void SvTreeListBox::CancelTextEditing()
1087 DBG_CHKTHIS(SvTreeListBox
,0);
1089 pEdCtrl
->StopEditing( sal_True
);
1090 nImpFlags
&= (~SVLBOX_IN_EDT
);
1093 void SvTreeListBox::EndEditing( bool bCancel
)
1095 DBG_CHKTHIS(SvTreeListBox
,0);
1097 pEdCtrl
->StopEditing( bCancel
);
1098 nImpFlags
&= (~SVLBOX_IN_EDT
);
1102 bool SvTreeListBox::IsEmptyTextAllowed() const
1104 DBG_CHKTHIS(SvTreeListBox
,0);
1105 return mpImpl
->m_bIsEmptyTextAllowed
;
1108 void SvTreeListBox::ForbidEmptyText()
1110 DBG_CHKTHIS(SvTreeListBox
,0);
1111 mpImpl
->m_bIsEmptyTextAllowed
= false;
1114 SvTreeListEntry
* SvTreeListBox::CreateEntry() const
1116 DBG_CHKTHIS(SvTreeListBox
,0);
1117 return new SvTreeListEntry
;
1120 const void* SvTreeListBox::FirstSearchEntry( String
& _rEntryText
) const
1122 SvTreeListEntry
* pEntry
= GetCurEntry();
1124 pEntry
= const_cast< SvTreeListEntry
* >( static_cast< const SvTreeListEntry
* >( NextSearchEntry( pEntry
, _rEntryText
) ) );
1127 pEntry
= FirstSelected();
1133 _rEntryText
= GetEntryText( pEntry
);
1138 const void* SvTreeListBox::NextSearchEntry( const void* _pCurrentSearchEntry
, String
& _rEntryText
) const
1140 SvTreeListEntry
* pEntry
= const_cast< SvTreeListEntry
* >( static_cast< const SvTreeListEntry
* >( _pCurrentSearchEntry
) );
1142 if ( ( ( GetChildCount( pEntry
) > 0 )
1143 || ( pEntry
->HasChildrenOnDemand() )
1145 && !IsExpanded( pEntry
)
1148 pEntry
= NextSibling( pEntry
);
1152 pEntry
= Next( pEntry
);
1159 _rEntryText
= GetEntryText( pEntry
);
1164 void SvTreeListBox::SelectSearchEntry( const void* _pEntry
)
1166 SvTreeListEntry
* pEntry
= const_cast< SvTreeListEntry
* >( static_cast< const SvTreeListEntry
* >( _pEntry
) );
1167 DBG_ASSERT( pEntry
, "SvTreeListBox::SelectSearchEntry: invalid entry!" );
1171 SelectAll( sal_False
);
1172 SetCurEntry( pEntry
);
1176 void SvTreeListBox::ExecuteSearchEntry( const void* /*_pEntry*/ ) const
1178 // nothing to do here, we have no "execution"
1181 ::vcl::StringEntryIdentifier
SvTreeListBox::CurrentEntry( String
& _out_entryText
) const
1183 // always accept the current entry if there is one
1184 SvTreeListEntry
* pCurrentEntry( GetCurEntry() );
1185 if ( pCurrentEntry
)
1187 _out_entryText
= GetEntryText( pCurrentEntry
);
1188 return pCurrentEntry
;
1190 return FirstSearchEntry( _out_entryText
);
1193 ::vcl::StringEntryIdentifier
SvTreeListBox::NextEntry( ::vcl::StringEntryIdentifier _currentEntry
, String
& _out_entryText
) const
1195 return NextSearchEntry( _currentEntry
, _out_entryText
);
1198 void SvTreeListBox::SelectEntry( ::vcl::StringEntryIdentifier _entry
)
1200 SelectSearchEntry( _entry
);
1203 bool SvTreeListBox::HandleKeyInput( const KeyEvent
& _rKEvt
)
1205 if ( IsEntryMnemonicsEnabled()
1206 && mpImpl
->m_aMnemonicEngine
.HandleKeyEvent( _rKEvt
)
1210 if ( ( GetStyle() & WB_QUICK_SEARCH
) != 0 )
1212 mpImpl
->m_bDoingQuickSelection
= true;
1213 const bool bHandled
= mpImpl
->m_aQuickSelectionEngine
.HandleKeyEvent( _rKEvt
);
1214 mpImpl
->m_bDoingQuickSelection
= false;
1222 void SvTreeListBox::WriteDragServerInfo( const Point
&, SvLBoxDDInfo
* )
1224 DBG_CHKTHIS(SvTreeListBox
,0);
1227 void SvTreeListBox::ReadDragServerInfo(const Point
&, SvLBoxDDInfo
* )
1229 DBG_CHKTHIS(SvTreeListBox
,0);
1232 sal_Bool
SvTreeListBox::EditingCanceled() const
1234 if( pEdCtrl
&& pEdCtrl
->EditingCanceled() )
1240 //JP 28.3.2001: new Drag & Drop API
1241 sal_Int8
SvTreeListBox::AcceptDrop( const AcceptDropEvent
& rEvt
)
1243 DBG_CHKTHIS(SvTreeListBox
,0);
1244 sal_Int8 nRet
= DND_ACTION_NONE
;
1246 if( rEvt
.mbLeaving
|| !CheckDragAndDropMode( pDDSource
, rEvt
.mnAction
) )
1248 ImplShowTargetEmphasis( pTargetEntry
, sal_False
);
1250 else if( !nDragDropMode
)
1252 SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no target" );
1256 SvTreeListEntry
* pEntry
= GetDropTarget( rEvt
.maPosPixel
);
1257 if( !IsDropFormatSupported( SOT_FORMATSTR_ID_TREELISTBOX
) )
1259 SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no format" );
1263 DBG_ASSERT( pDDSource
, "SvTreeListBox::QueryDrop(): SourceBox == 0" );
1264 if( !( pEntry
&& pDDSource
->GetModel() == this->GetModel()
1265 && DND_ACTION_MOVE
== rEvt
.mnAction
1266 && ( pEntry
->nEntryFlags
& SV_ENTRYFLAG_DISABLE_DROP
) ))
1268 if( NotifyAcceptDrop( pEntry
))
1269 nRet
= rEvt
.mnAction
;
1273 // **** draw emphasis ****
1274 if( DND_ACTION_NONE
== nRet
)
1275 ImplShowTargetEmphasis( pTargetEntry
, sal_False
);
1276 else if( pEntry
!= pTargetEntry
|| !(nImpFlags
& SVLBOX_TARGEMPH_VIS
) )
1278 ImplShowTargetEmphasis( pTargetEntry
, sal_False
);
1279 pTargetEntry
= pEntry
;
1280 ImplShowTargetEmphasis( pTargetEntry
, sal_True
);
1286 sal_Int8
SvTreeListBox::ExecuteDrop( const ExecuteDropEvent
& rEvt
, SvTreeListBox
* pSourceView
)
1288 DBG_CHKTHIS(SvTreeListBox
,0);
1289 sal_Int8 nRet
= DND_ACTION_NONE
;
1291 DBG_ASSERT( pSourceView
, "SvTreeListBox::ExecuteDrop(): no source view" );
1292 pSourceView
->EnableSelectionAsDropTarget( sal_True
, sal_True
);
1294 ImplShowTargetEmphasis( pTargetEntry
, sal_False
);
1297 SvLBoxDDInfo aDDInfo
;
1299 TransferableDataHelper
aData( rEvt
.maDropEvent
.Transferable
);
1300 if( aData
.HasFormat( SOT_FORMATSTR_ID_TREELISTBOX
))
1302 ::com::sun::star::uno::Sequence
< sal_Int8
> aSeq
;
1303 if( aData
.GetSequence( SOT_FORMATSTR_ID_TREELISTBOX
, aSeq
) &&
1304 sizeof(SvLBoxDDInfo
) == aSeq
.getLength() )
1306 memcpy( &aDDInfo
, aSeq
.getConstArray(), sizeof(SvLBoxDDInfo
) );
1307 nRet
= rEvt
.mnAction
;
1311 if( DND_ACTION_NONE
!= nRet
)
1313 nRet
= DND_ACTION_NONE
;
1315 ReadDragServerInfo( rEvt
.maPosPixel
, &aDDInfo
);
1317 SvTreeListEntry
* pTarget
= pTargetEntry
; // may be 0!
1319 if( DND_ACTION_COPY
== rEvt
.mnAction
)
1321 if ( CopySelection( aDDInfo
.pSource
, pTarget
) )
1322 nRet
= rEvt
.mnAction
;
1324 else if( DND_ACTION_MOVE
== rEvt
.mnAction
)
1326 if ( MoveSelection( aDDInfo
.pSource
, pTarget
) )
1327 nRet
= rEvt
.mnAction
;
1329 else if( DND_ACTION_COPYMOVE
== rEvt
.mnAction
)
1331 if ( MoveSelectionCopyFallbackPossible( aDDInfo
.pSource
, pTarget
, sal_True
) )
1332 nRet
= rEvt
.mnAction
;
1338 sal_Int8
SvTreeListBox::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
1340 DBG_CHKTHIS(SvTreeListBox
,0);
1341 return ExecuteDrop( rEvt
, GetSourceView() );
1344 void SvTreeListBox::StartDrag( sal_Int8
, const Point
& rPosPixel
)
1346 DBG_CHKTHIS(SvTreeListBox
,0);
1348 Point
aEventPos( rPosPixel
);
1349 MouseEvent
aMouseEvt( aEventPos
, 1, MOUSE_SELECT
, MOUSE_LEFT
);
1350 MouseButtonUp( aMouseEvt
);
1352 nOldDragMode
= GetDragDropMode();
1353 if ( !nOldDragMode
)
1358 SvTreeListEntry
* pEntry
= GetEntry( rPosPixel
); // GetDropTarget( rPos );
1361 DragFinished( DND_ACTION_NONE
);
1365 TransferDataContainer
* pContainer
= new TransferDataContainer
;
1366 ::com::sun::star::uno::Reference
<
1367 ::com::sun::star::datatransfer::XTransferable
> xRef( pContainer
);
1369 nDragDropMode
= NotifyStartDrag( *pContainer
, pEntry
);
1370 if( !nDragDropMode
|| 0 == GetSelectionCount() )
1372 nDragDropMode
= nOldDragMode
;
1373 DragFinished( DND_ACTION_NONE
);
1377 SvLBoxDDInfo aDDInfo
;
1378 memset(&aDDInfo
,0,sizeof(SvLBoxDDInfo
));
1379 aDDInfo
.pApp
= GetpApp();
1380 aDDInfo
.pSource
= this;
1381 aDDInfo
.pDDStartEntry
= pEntry
;
1382 // let derived views do their thing
1383 WriteDragServerInfo( rPosPixel
, &aDDInfo
);
1385 pContainer
->CopyAnyData( SOT_FORMATSTR_ID_TREELISTBOX
,
1386 (sal_Char
*)&aDDInfo
, sizeof(SvLBoxDDInfo
) );
1390 sal_Bool bOldUpdateMode
= Control::IsUpdateMode();
1391 Control::SetUpdateMode( sal_True
);
1393 Control::SetUpdateMode( bOldUpdateMode
);
1395 // Disallow using the selection and its children as drop targets.
1396 // Important: If the selection of the SourceListBox is changed in the
1397 // DropHandler, the entries have to be allowed as drop targets again:
1398 // (GetSourceListBox()->EnableSelectionAsDropTarget( sal_True, sal_True );)
1399 EnableSelectionAsDropTarget( sal_False
, sal_True
/* with children */ );
1401 pContainer
->StartDrag( this, nDragOptions
, GetDragFinishedHdl() );
1404 void SvTreeListBox::DragFinished( sal_Int8
1410 EnableSelectionAsDropTarget( sal_True
, sal_True
);
1413 if( (nAction
== DND_ACTION_MOVE
) && ( (pDDTarget
&&
1414 ((sal_uLong
)(pDDTarget
->GetModel())!=(sal_uLong
)(this->GetModel()))) ||
1421 ImplShowTargetEmphasis( pTargetEntry
, sal_False
);
1425 nDragDropMode
= nOldDragMode
;
1428 DragDropMode
SvTreeListBox::NotifyStartDrag( TransferDataContainer
&, SvTreeListEntry
* )
1430 DBG_CHKTHIS(SvTreeListBox
,0);
1431 return (DragDropMode
)0xffff;
1434 sal_Bool
SvTreeListBox::NotifyAcceptDrop( SvTreeListEntry
* )
1436 DBG_CHKTHIS(SvTreeListBox
,0);
1440 // Handler and methods for Drag - finished handler.
1441 // The with get GetDragFinishedHdl() get link can set on the
1442 // TransferDataContainer. This link is a callback for the DragFinished
1443 // call. AddBox method is called from the GetDragFinishedHdl() and the
1444 // remove is called in link callback and in the destructor. So it can't
1445 // called to a deleted object.
1449 struct SortLBoxes
: public rtl::Static
<std::set
<sal_uLong
>, SortLBoxes
> {};
1452 void SvTreeListBox::AddBoxToDDList_Impl( const SvTreeListBox
& rB
)
1454 sal_uLong nVal
= (sal_uLong
)&rB
;
1455 SortLBoxes::get().insert( nVal
);
1458 void SvTreeListBox::RemoveBoxFromDDList_Impl( const SvTreeListBox
& rB
)
1460 sal_uLong nVal
= (sal_uLong
)&rB
;
1461 SortLBoxes::get().erase( nVal
);
1464 IMPL_STATIC_LINK( SvTreeListBox
, DragFinishHdl_Impl
, sal_Int8
*, pAction
)
1466 sal_uLong nVal
= (sal_uLong
)pThis
;
1467 std::set
<sal_uLong
> &rSortLBoxes
= SortLBoxes::get();
1468 std::set
<sal_uLong
>::const_iterator it
= rSortLBoxes
.find(nVal
);
1469 if( it
!= rSortLBoxes
.end() )
1471 pThis
->DragFinished( *pAction
);
1472 rSortLBoxes
.erase( it
);
1477 Link
SvTreeListBox::GetDragFinishedHdl() const
1479 AddBoxToDDList_Impl( *this );
1480 return STATIC_LINK( this, SvTreeListBox
, DragFinishHdl_Impl
);
1486 - calculate rectangle when editing in-place (bug with some fonts)
1487 - SetSpaceBetweenEntries: offset is not taken into account in SetEntryHeight
1490 #define TREEFLAG_FIXEDHEIGHT 0x0010
1492 #define SV_LBOX_DEFAULT_INDENT_PIXEL 20
1494 void SvTreeListBox::InitTreeView()
1496 DBG_CHKTHIS(SvTreeListBox
,0);
1497 pCheckButtonData
= NULL
;
1505 mnCheckboxItemWidth
= 0;
1507 Link
* pLink
= new Link( LINK(this,SvTreeListBox
, DefaultCompare
) );
1508 mpImpl
->m_pLink
= pLink
;
1510 nTreeFlags
= TREEFLAG_RECALCTABS
;
1511 nIndent
= SV_LBOX_DEFAULT_INDENT_PIXEL
;
1512 nEntryHeightOffs
= SV_ENTRYHEIGHTOFFS_PIXEL
;
1513 pImp
= new SvImpLBox( this, GetModel(), GetStyle() );
1515 mbContextBmpExpanded
= true;
1516 nContextBmpWidthMax
= 0;
1518 SetFont( GetFont() );
1519 AdjustEntryHeightAndRecalc( GetFont() );
1521 SetSpaceBetweenEntries( 0 );
1523 InitSettings( sal_True
, sal_True
, sal_True
);
1529 SvTreeListBox::~SvTreeListBox()
1531 DBG_DTOR(SvTreeListBox
,0);
1533 pImp
->CallEventListeners( VCLEVENT_OBJECT_DYING
);
1535 delete mpImpl
->m_pLink
;
1540 pModel
->RemoveView( this );
1541 if ( pModel
->GetRefCount() == 0 )
1548 SvTreeListBox::RemoveBoxFromDDList_Impl( *this );
1550 if( this == pDDSource
)
1552 if( this == pDDTarget
)
1557 void SvTreeListBox::SetExtendedWinBits( ExtendedWinBits _nBits
)
1559 pImp
->SetExtendedWindowBits( _nBits
);
1562 void SvTreeListBox::SetModel( SvTreeList
* pNewModel
)
1564 DBG_CHKTHIS(SvTreeListBox
,0);
1565 pImp
->SetModel( pNewModel
);
1566 SetBaseModel(pNewModel
);
1569 void SvTreeListBox::SetBaseModel( SvTreeList
* pNewModel
)
1572 SvListView::SetModel( pNewModel
);
1573 pModel
->SetCloneLink( LINK(this, SvTreeListBox
, CloneHdl_Impl
));
1574 SvTreeListEntry
* pEntry
= First();
1577 ModelHasInserted( pEntry
);
1578 pEntry
= Next( pEntry
);
1582 void SvTreeListBox::DisconnectFromModel()
1584 DBG_CHKTHIS(SvTreeListBox
,0);
1585 SvTreeList
* pNewModel
= new SvTreeList
;
1586 pNewModel
->SetRefCount( 0 ); // else this will never be deleted
1587 SvListView::SetModel( pNewModel
);
1589 pImp
->SetModel( GetModel() );
1592 void SvTreeListBox::SetSublistOpenWithReturn( sal_Bool b
)
1594 pImp
->bSubLstOpRet
= b
;
1597 void SvTreeListBox::SetSublistOpenWithLeftRight( sal_Bool b
)
1599 pImp
->bSubLstOpLR
= b
;
1602 void SvTreeListBox::Resize()
1604 DBG_CHKTHIS(SvTreeListBox
,0);
1605 if( IsEditingActive() )
1606 EndEditing( sal_True
);
1612 pImp
->ShowCursor( sal_False
);
1613 pImp
->ShowCursor( sal_True
);
1618 A) entries have bitmaps
1620 1. node buttons (can optionally also be on root items)
1621 2. node buttons (can optionally also be on root items) + CheckButton
1623 B) entries don't have bitmaps (=>via WindowBits because of D&D!)
1625 1. node buttons (can optionally also be on root items)
1626 2. node buttons (can optionally also be on root items) + CheckButton
1630 #define NO_BUTTONS 0
1631 #define NODE_BUTTONS 1
1632 #define NODE_AND_CHECK_BUTTONS 2
1633 #define CHECK_BUTTONS 3
1635 #define TABFLAGS_TEXT (SV_LBOXTAB_DYNAMIC | \
1636 SV_LBOXTAB_ADJUST_LEFT | \
1637 SV_LBOXTAB_EDITABLE | \
1638 SV_LBOXTAB_SHOW_SELECTION)
1640 #define TABFLAGS_CONTEXTBMP (SV_LBOXTAB_DYNAMIC | SV_LBOXTAB_ADJUST_CENTER)
1642 #define TABFLAGS_CHECKBTN (SV_LBOXTAB_DYNAMIC | \
1643 SV_LBOXTAB_ADJUST_CENTER | \
1644 SV_LBOXTAB_PUSHABLE)
1646 #define TAB_STARTPOS 2
1648 // take care of GetTextOffset when doing changes
1649 void SvTreeListBox::SetTabs()
1651 DBG_CHKTHIS(SvTreeListBox
,0);
1652 if( IsEditingActive() )
1653 EndEditing( sal_True
);
1654 nTreeFlags
&= (~TREEFLAG_RECALCTABS
);
1656 const WinBits
nStyle( GetStyle() );
1657 sal_Bool bHasButtons
= (nStyle
& WB_HASBUTTONS
)!=0;
1658 sal_Bool bHasButtonsAtRoot
= (nStyle
& (WB_HASLINESATROOT
|
1659 WB_HASBUTTONSATROOT
))!=0;
1660 long nStartPos
= TAB_STARTPOS
;
1661 long nNodeWidthPixel
= GetExpandedNodeBmp().GetSizePixel().Width();
1663 // pCheckButtonData->Width() knows nothing about the native checkbox width,
1664 // so we have mnCheckboxItemWidth which becomes valid when something is added.
1665 long nCheckWidth
= 0;
1666 if( nTreeFlags
& TREEFLAG_CHKBTN
)
1667 nCheckWidth
= mnCheckboxItemWidth
;
1668 long nCheckWidthDIV2
= nCheckWidth
/ 2;
1670 long nContextWidth
= nContextBmpWidthMax
;
1671 long nContextWidthDIV2
= nContextWidth
/ 2;
1675 int nCase
= NO_BUTTONS
;
1676 if( !(nTreeFlags
& TREEFLAG_CHKBTN
) )
1679 nCase
= NODE_BUTTONS
;
1684 nCase
= NODE_AND_CHECK_BUTTONS
;
1686 nCase
= CHECK_BUTTONS
;
1692 nStartPos
+= nContextWidthDIV2
; // because of centering
1693 AddTab( nStartPos
, TABFLAGS_CONTEXTBMP
);
1694 nStartPos
+= nContextWidthDIV2
; // right edge of context bitmap
1695 // only set a distance if there are bitmaps
1696 if( nContextBmpWidthMax
)
1697 nStartPos
+= 5; // distance context bitmap to text
1698 AddTab( nStartPos
, TABFLAGS_TEXT
);
1702 if( bHasButtonsAtRoot
)
1703 nStartPos
+= ( nIndent
+ (nNodeWidthPixel
/2) );
1705 nStartPos
+= nContextWidthDIV2
;
1706 AddTab( nStartPos
, TABFLAGS_CONTEXTBMP
);
1707 nStartPos
+= nContextWidthDIV2
; // right edge of context bitmap
1708 // only set a distance if there are bitmaps
1709 if( nContextBmpWidthMax
)
1710 nStartPos
+= 5; // distance context bitmap to text
1711 AddTab( nStartPos
, TABFLAGS_TEXT
);
1714 case NODE_AND_CHECK_BUTTONS
:
1715 if( bHasButtonsAtRoot
)
1716 nStartPos
+= ( nIndent
+ nNodeWidthPixel
);
1718 nStartPos
+= nCheckWidthDIV2
;
1719 AddTab( nStartPos
, TABFLAGS_CHECKBTN
);
1720 nStartPos
+= nCheckWidthDIV2
; // right edge of CheckButton
1721 nStartPos
+= 3; // distance CheckButton to context bitmap
1722 nStartPos
+= nContextWidthDIV2
; // center of context bitmap
1723 AddTab( nStartPos
, TABFLAGS_CONTEXTBMP
);
1724 nStartPos
+= nContextWidthDIV2
; // right edge of context bitmap
1725 // only set a distance if there are bitmaps
1726 if( nContextBmpWidthMax
)
1727 nStartPos
+= 5; // distance context bitmap to text
1728 AddTab( nStartPos
, TABFLAGS_TEXT
);
1731 case CHECK_BUTTONS
:
1732 nStartPos
+= nCheckWidthDIV2
;
1733 AddTab( nStartPos
, TABFLAGS_CHECKBTN
);
1734 nStartPos
+= nCheckWidthDIV2
; // right edge of CheckButton
1735 nStartPos
+= 3; // distance CheckButton to context bitmap
1736 nStartPos
+= nContextWidthDIV2
; // center of context bitmap
1737 AddTab( nStartPos
, TABFLAGS_CONTEXTBMP
);
1738 nStartPos
+= nContextWidthDIV2
; // right edge of context bitmap
1739 // only set a distance if there are bitmaps
1740 if( nContextBmpWidthMax
)
1741 nStartPos
+= 5; // distance context bitmap to text
1742 AddTab( nStartPos
, TABFLAGS_TEXT
);
1745 pImp
->NotifyTabsChanged();
1748 void SvTreeListBox::InitEntry(SvTreeListEntry
* pEntry
,
1749 const OUString
& aStr
, const Image
& aCollEntryBmp
, const Image
& aExpEntryBmp
,
1750 SvLBoxButtonKind eButtonKind
)
1752 DBG_CHKTHIS(SvTreeListBox
,0);
1753 SvLBoxButton
* pButton
;
1754 SvLBoxString
* pString
;
1755 SvLBoxContextBmp
* pContextBmp
;
1757 if( nTreeFlags
& TREEFLAG_CHKBTN
)
1759 pButton
= new SvLBoxButton( pEntry
,eButtonKind
,0,pCheckButtonData
);
1760 pEntry
->AddItem( pButton
);
1763 pContextBmp
= new SvLBoxContextBmp(
1764 pEntry
,0, aCollEntryBmp
,aExpEntryBmp
, mbContextBmpExpanded
);
1765 pEntry
->AddItem( pContextBmp
);
1767 pString
= new SvLBoxString( pEntry
, 0, aStr
);
1768 pEntry
->AddItem( pString
);
1771 String
SvTreeListBox::GetEntryText(SvTreeListEntry
* pEntry
) const
1773 DBG_CHKTHIS(SvTreeListBox
,0);
1774 DBG_ASSERT( pEntry
, "SvTreeListBox::GetEntryText(): no entry" );
1775 SvLBoxString
* pItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
1776 DBG_ASSERT( pEntry
, "SvTreeListBox::GetEntryText(): item not found" );
1777 return pItem
->GetText();
1780 String
SvTreeListBox::SearchEntryText( SvTreeListEntry
* pEntry
) const
1782 DBG_CHKTHIS(SvTreeListBox
,0);
1783 DBG_ASSERT( pEntry
, "SvTreeListBox::SearchEntryText(): no entry" );
1785 sal_uInt16 nCount
= pEntry
->ItemCount();
1786 sal_uInt16 nCur
= 0;
1788 while( nCur
< nCount
)
1790 pItem
= pEntry
->GetItem( nCur
);
1791 if (pItem
->GetType() == SV_ITEM_ID_LBOXSTRING
&& !static_cast<const SvLBoxString
*>(pItem
)->GetText().isEmpty())
1793 sRet
= static_cast<const SvLBoxString
*>(pItem
)->GetText();
1801 const Image
& SvTreeListBox::GetExpandedEntryBmp(const SvTreeListEntry
* pEntry
) const
1803 DBG_CHKTHIS(SvTreeListBox
,0);
1804 DBG_ASSERT(pEntry
,"Entry?");
1805 const SvLBoxContextBmp
* pItem
= static_cast<const SvLBoxContextBmp
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
1806 DBG_ASSERT(pItem
,"GetContextBmp:Item not found");
1807 return pItem
->GetBitmap2( );
1810 const Image
& SvTreeListBox::GetCollapsedEntryBmp( const SvTreeListEntry
* pEntry
) const
1812 DBG_CHKTHIS(SvTreeListBox
,0);
1813 DBG_ASSERT(pEntry
,"Entry?");
1814 const SvLBoxContextBmp
* pItem
= static_cast<const SvLBoxContextBmp
*>(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
1815 DBG_ASSERT(pItem
,"GetContextBmp:Item not found");
1816 return pItem
->GetBitmap1( );
1819 IMPL_LINK_INLINE_START( SvTreeListBox
, CheckButtonClick
, SvLBoxButtonData
*, pData
)
1821 DBG_CHKTHIS(SvTreeListBox
,0);
1822 pHdlEntry
= pData
->GetActEntry();
1826 IMPL_LINK_INLINE_END( SvTreeListBox
, CheckButtonClick
, SvLBoxButtonData
*, pData
)
1828 SvTreeListEntry
* SvTreeListBox::InsertEntry(
1829 const XubString
& aText
,
1830 SvTreeListEntry
* pParent
,
1831 sal_Bool bChildrenOnDemand
, sal_uLong nPos
,
1833 SvLBoxButtonKind eButtonKind
1836 DBG_CHKTHIS(SvTreeListBox
,0);
1837 nTreeFlags
|= TREEFLAG_MANINS
;
1839 const Image
& rDefExpBmp
= pImp
->GetDefaultEntryExpBmp( );
1840 const Image
& rDefColBmp
= pImp
->GetDefaultEntryColBmp( );
1842 aCurInsertedExpBmp
= rDefExpBmp
;
1843 aCurInsertedColBmp
= rDefColBmp
;
1845 SvTreeListEntry
* pEntry
= CreateEntry();
1846 pEntry
->SetUserData( pUser
);
1847 InitEntry( pEntry
, aText
, rDefColBmp
, rDefExpBmp
, eButtonKind
);
1848 pEntry
->EnableChildrenOnDemand( bChildrenOnDemand
);
1851 Insert( pEntry
, nPos
);
1853 Insert( pEntry
, pParent
, nPos
);
1855 aPrevInsertedExpBmp
= rDefExpBmp
;
1856 aPrevInsertedColBmp
= rDefColBmp
;
1858 nTreeFlags
&= (~TREEFLAG_MANINS
);
1863 SvTreeListEntry
* SvTreeListBox::InsertEntry( const XubString
& aText
,
1864 const Image
& aExpEntryBmp
, const Image
& aCollEntryBmp
,
1865 SvTreeListEntry
* pParent
, sal_Bool bChildrenOnDemand
, sal_uLong nPos
, void* pUser
,
1866 SvLBoxButtonKind eButtonKind
)
1868 DBG_CHKTHIS(SvTreeListBox
,0);
1869 nTreeFlags
|= TREEFLAG_MANINS
;
1871 aCurInsertedExpBmp
= aExpEntryBmp
;
1872 aCurInsertedColBmp
= aCollEntryBmp
;
1874 SvTreeListEntry
* pEntry
= CreateEntry();
1875 pEntry
->SetUserData( pUser
);
1876 InitEntry( pEntry
, aText
, aCollEntryBmp
, aExpEntryBmp
, eButtonKind
);
1878 pEntry
->EnableChildrenOnDemand( bChildrenOnDemand
);
1881 Insert( pEntry
, nPos
);
1883 Insert( pEntry
, pParent
, nPos
);
1885 aPrevInsertedExpBmp
= aExpEntryBmp
;
1886 aPrevInsertedColBmp
= aCollEntryBmp
;
1888 nTreeFlags
&= (~TREEFLAG_MANINS
);
1893 void SvTreeListBox::SetEntryText( SvTreeListEntry
* pEntry
, const XubString
& aStr
)
1895 DBG_CHKTHIS(SvTreeListBox
,0);
1896 SvLBoxString
* pItem
= (SvLBoxString
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
1897 DBG_ASSERT(pItem
,"SetText:Item not found");
1898 pItem
->SetText( aStr
);
1899 pItem
->InitViewData( this, pEntry
, 0 );
1900 GetModel()->InvalidateEntry( pEntry
);
1903 void SvTreeListBox::SetExpandedEntryBmp( SvTreeListEntry
* pEntry
, const Image
& aBmp
)
1905 DBG_CHKTHIS(SvTreeListBox
,0);
1906 SvLBoxContextBmp
* pItem
= (SvLBoxContextBmp
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
1908 DBG_ASSERT(pItem
,"SetExpBmp:Item not found");
1909 pItem
->SetBitmap2( aBmp
);
1911 GetModel()->InvalidateEntry( pEntry
);
1912 SetEntryHeight( pEntry
);
1913 Size aSize
= aBmp
.GetSizePixel();
1914 short nWidth
= pImp
->UpdateContextBmpWidthVector( pEntry
, (short)aSize
.Width() );
1915 if( nWidth
> nContextBmpWidthMax
)
1917 nContextBmpWidthMax
= nWidth
;
1922 void SvTreeListBox::SetCollapsedEntryBmp(SvTreeListEntry
* pEntry
,const Image
& aBmp
)
1924 DBG_CHKTHIS(SvTreeListBox
,0);
1925 SvLBoxContextBmp
* pItem
= (SvLBoxContextBmp
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
1927 DBG_ASSERT(pItem
,"SetExpBmp:Item not found");
1928 pItem
->SetBitmap1( aBmp
);
1930 GetModel()->InvalidateEntry( pEntry
);
1931 SetEntryHeight( pEntry
);
1932 Size aSize
= aBmp
.GetSizePixel();
1933 short nWidth
= pImp
->UpdateContextBmpWidthVector( pEntry
, (short)aSize
.Width() );
1934 if( nWidth
> nContextBmpWidthMax
)
1936 nContextBmpWidthMax
= nWidth
;
1941 void SvTreeListBox::ImpEntryInserted( SvTreeListEntry
* pEntry
)
1943 DBG_CHKTHIS(SvTreeListBox
,0);
1945 SvTreeListEntry
* pParent
= (SvTreeListEntry
*)pModel
->GetParent( pEntry
);
1948 sal_uInt16 nFlags
= pParent
->GetFlags();
1949 nFlags
&= ~SV_ENTRYFLAG_NO_NODEBMP
;
1950 pParent
->SetFlags( nFlags
);
1953 if(!((nTreeFlags
& TREEFLAG_MANINS
) &&
1954 (aPrevInsertedExpBmp
== aCurInsertedExpBmp
) &&
1955 (aPrevInsertedColBmp
== aCurInsertedColBmp
) ))
1957 Size aSize
= GetCollapsedEntryBmp( pEntry
).GetSizePixel();
1958 if( aSize
.Width() > nContextBmpWidthMax
)
1960 nContextBmpWidthMax
= (short)aSize
.Width();
1961 nTreeFlags
|= TREEFLAG_RECALCTABS
;
1963 aSize
= GetExpandedEntryBmp( pEntry
).GetSizePixel();
1964 if( aSize
.Width() > nContextBmpWidthMax
)
1966 nContextBmpWidthMax
= (short)aSize
.Width();
1967 nTreeFlags
|= TREEFLAG_RECALCTABS
;
1970 SetEntryHeight( (SvTreeListEntry
*)pEntry
);
1972 if( nTreeFlags
& TREEFLAG_CHKBTN
)
1974 SvLBoxButton
* pItem
= (SvLBoxButton
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
1977 long nWidth
= pItem
->GetSize(this, pEntry
).Width();
1978 if( mnCheckboxItemWidth
< nWidth
)
1980 mnCheckboxItemWidth
= nWidth
;
1981 nTreeFlags
|= TREEFLAG_RECALCTABS
;
1989 void SvTreeListBox::SetCheckButtonState( SvTreeListEntry
* pEntry
, SvButtonState eState
)
1991 DBG_CHKTHIS(SvTreeListBox
,0);
1992 if( nTreeFlags
& TREEFLAG_CHKBTN
)
1994 SvLBoxButton
* pItem
= (SvLBoxButton
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
1995 if(!(pItem
&& pItem
->CheckModification()))
1999 case SV_BUTTON_CHECKED
:
2000 pItem
->SetStateChecked();
2003 case SV_BUTTON_UNCHECKED
:
2004 pItem
->SetStateUnchecked();
2007 case SV_BUTTON_TRISTATE
:
2008 pItem
->SetStateTristate();
2011 InvalidateEntry( pEntry
);
2015 SvButtonState
SvTreeListBox::GetCheckButtonState( SvTreeListEntry
* pEntry
) const
2017 DBG_CHKTHIS(SvTreeListBox
,0);
2018 SvButtonState eState
= SV_BUTTON_UNCHECKED
;
2019 if( nTreeFlags
& TREEFLAG_CHKBTN
)
2021 SvLBoxButton
* pItem
= (SvLBoxButton
*)(pEntry
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
2023 return SV_BUTTON_TRISTATE
;
2024 sal_uInt16 nButtonFlags
= pItem
->GetButtonFlags();
2025 eState
= pCheckButtonData
->ConvertToButtonState( nButtonFlags
);
2030 void SvTreeListBox::CheckButtonHdl()
2032 DBG_CHKTHIS(SvTreeListBox
,0);
2033 aCheckButtonHdl
.Call( this );
2034 if ( pCheckButtonData
)
2035 pImp
->CallEventListeners( VCLEVENT_CHECKBOX_TOGGLE
, (void*)pCheckButtonData
->GetActEntry() );
2039 // TODO: Currently all data is cloned so that they conform to the default tree
2040 // view format. Actually, the model should be used as a reference here. This
2041 // leads to us _not_ calling SvTreeListEntry::Clone, but only its base class
2045 SvTreeListEntry
* SvTreeListBox::CloneEntry( SvTreeListEntry
* pSource
)
2047 DBG_CHKTHIS(SvTreeListBox
,0);
2049 Image aCollEntryBmp
;
2051 SvLBoxButtonKind eButtonKind
= SvLBoxButtonKind_enabledCheckbox
;
2053 SvLBoxString
* pStringItem
= (SvLBoxString
*)(pSource
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
));
2055 aStr
= pStringItem
->GetText();
2056 SvLBoxContextBmp
* pBmpItem
= (SvLBoxContextBmp
*)(pSource
->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP
));
2059 aCollEntryBmp
= pBmpItem
->GetBitmap1( );
2060 aExpEntryBmp
= pBmpItem
->GetBitmap2( );
2062 SvLBoxButton
* pButtonItem
= (SvLBoxButton
*)(pSource
->GetFirstItem(SV_ITEM_ID_LBOXBUTTON
));
2064 eButtonKind
= pButtonItem
->GetKind();
2065 SvTreeListEntry
* pClone
= CreateEntry();
2066 InitEntry( pClone
, aStr
, aCollEntryBmp
, aExpEntryBmp
, eButtonKind
);
2067 pClone
->SvTreeListEntry::Clone( pSource
);
2068 pClone
->EnableChildrenOnDemand( pSource
->HasChildrenOnDemand() );
2069 pClone
->SetUserData( pSource
->GetUserData() );
2074 void SvTreeListBox::SetIndent( short nNewIndent
)
2076 DBG_CHKTHIS(SvTreeListBox
,0);
2077 nIndent
= nNewIndent
;
2079 if( IsUpdateMode() )
2083 const Image
& SvTreeListBox::GetDefaultExpandedEntryBmp( ) const
2085 return pImp
->GetDefaultEntryExpBmp( );
2088 const Image
& SvTreeListBox::GetDefaultCollapsedEntryBmp( ) const
2090 return pImp
->GetDefaultEntryColBmp( );
2093 void SvTreeListBox::SetDefaultExpandedEntryBmp( const Image
& aBmp
)
2095 DBG_CHKTHIS(SvTreeListBox
,0);
2096 Size aSize
= aBmp
.GetSizePixel();
2097 if( aSize
.Width() > nContextBmpWidthMax
)
2098 nContextBmpWidthMax
= (short)aSize
.Width();
2101 pImp
->SetDefaultEntryExpBmp( aBmp
);
2104 void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image
& aBmp
)
2106 DBG_CHKTHIS(SvTreeListBox
,0);
2107 Size aSize
= aBmp
.GetSizePixel();
2108 if( aSize
.Width() > nContextBmpWidthMax
)
2109 nContextBmpWidthMax
= (short)aSize
.Width();
2112 pImp
->SetDefaultEntryColBmp( aBmp
);
2115 void SvTreeListBox::EnableCheckButton( SvLBoxButtonData
* pData
)
2117 DBG_CHKTHIS(SvTreeListBox
,0);
2118 DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0");
2120 nTreeFlags
&= (~TREEFLAG_CHKBTN
);
2123 SetCheckButtonData( pData
);
2124 nTreeFlags
|= TREEFLAG_CHKBTN
;
2125 pData
->SetLink( LINK(this, SvTreeListBox
, CheckButtonClick
));
2129 if( IsUpdateMode() )
2133 void SvTreeListBox::SetCheckButtonData( SvLBoxButtonData
* pData
)
2135 DBG_CHKTHIS(SvTreeListBox
,0);
2137 pCheckButtonData
= pData
;
2140 const Image
& SvTreeListBox::GetDefaultExpandedNodeImage( )
2142 return SvImpLBox::GetDefaultExpandedNodeImage( );
2145 const Image
& SvTreeListBox::GetDefaultCollapsedNodeImage( )
2147 return SvImpLBox::GetDefaultCollapsedNodeImage( );
2150 void SvTreeListBox::SetNodeBitmaps( const Image
& rCollapsedNodeBmp
, const Image
& rExpandedNodeBmp
)
2152 DBG_CHKTHIS(SvTreeListBox
,0);
2153 SetExpandedNodeBmp( rExpandedNodeBmp
);
2154 SetCollapsedNodeBmp( rCollapsedNodeBmp
);
2158 sal_Bool
SvTreeListBox::EditingEntry( SvTreeListEntry
*, Selection
& )
2160 DBG_CHKTHIS(SvTreeListBox
,0);
2164 sal_Bool
SvTreeListBox::EditedEntry( SvTreeListEntry
* /*pEntry*/,const OUString
& /*rNewText*/)
2166 DBG_CHKTHIS(SvTreeListBox
,0);
2170 void SvTreeListBox::EnableInplaceEditing( bool bOn
)
2172 DBG_CHKTHIS(SvTreeListBox
,0);
2174 nImpFlags
|= SVLBOX_EDT_ENABLED
;
2176 nImpFlags
&= ~SVLBOX_EDT_ENABLED
;
2179 void SvTreeListBox::KeyInput( const KeyEvent
& rKEvt
)
2181 DBG_CHKTHIS(SvTreeListBox
,0);
2182 // under OS/2, we get key up/down even while editing
2183 if( IsEditingActive() )
2186 nImpFlags
|= SVLBOX_IS_TRAVELSELECT
;
2189 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
2194 SvTreeListEntry
* pEntry
= First();
2195 pEntry
= NextVisible( pEntry
);
2196 SetEntryText( pEntry
, "SetEntryText" );
2202 if( !pImp
->KeyInput( rKEvt
) )
2204 bool bHandled
= HandleKeyInput( rKEvt
);
2206 Control::KeyInput( rKEvt
);
2209 nImpFlags
&= ~SVLBOX_IS_TRAVELSELECT
;
2212 void SvTreeListBox::RequestingChildren( SvTreeListEntry
* pParent
)
2214 DBG_CHKTHIS(SvTreeListBox
,0);
2215 if( !pParent
->HasChildren() )
2216 InsertEntry( OUString("<dummy>"), pParent
, sal_False
, LIST_APPEND
);
2219 void SvTreeListBox::GetFocus()
2221 DBG_CHKTHIS(SvTreeListBox
,0);
2223 Control::GetFocus();
2225 SvTreeListEntry
* pEntry
= FirstSelected();
2227 pImp
->CallEventListeners( VCLEVENT_LISTBOX_SELECT
, pEntry
);
2231 void SvTreeListBox::LoseFocus()
2233 DBG_CHKTHIS(SvTreeListBox
,0);
2235 Control::LoseFocus();
2238 void SvTreeListBox::ModelHasCleared()
2240 DBG_CHKTHIS(SvTreeListBox
,0);
2241 pImp
->pCursor
= 0; // else we crash in GetFocus when editing in-place
2247 nContextBmpWidthMax
= 0;
2248 SetDefaultExpandedEntryBmp( GetDefaultExpandedEntryBmp() );
2249 SetDefaultCollapsedEntryBmp( GetDefaultCollapsedEntryBmp() );
2251 if( !(nTreeFlags
& TREEFLAG_FIXEDHEIGHT
))
2253 AdjustEntryHeight( GetFont() );
2254 AdjustEntryHeight( GetDefaultExpandedEntryBmp() );
2255 AdjustEntryHeight( GetDefaultCollapsedEntryBmp() );
2257 SvListView::ModelHasCleared();
2260 void SvTreeListBox::ShowTargetEmphasis( SvTreeListEntry
* pEntry
, sal_Bool
/*bShow*/ )
2262 DBG_CHKTHIS(SvTreeListBox
,0);
2263 pImp
->PaintDDCursor( pEntry
);
2266 void SvTreeListBox::ScrollOutputArea( short nDeltaEntries
)
2268 DBG_CHKTHIS(SvTreeListBox
,0);
2269 if( !nDeltaEntries
|| !pImp
->aVerSBar
.IsVisible() )
2272 long nThumb
= pImp
->aVerSBar
.GetThumbPos();
2273 long nMax
= pImp
->aVerSBar
.GetRange().Max();
2275 NotifyBeginScroll();
2276 if( nDeltaEntries
< 0 )
2279 nDeltaEntries
*= -1;
2280 long nVis
= pImp
->aVerSBar
.GetVisibleSize();
2281 long nTemp
= nThumb
+ nVis
;
2282 if( nDeltaEntries
> (nMax
- nTemp
) )
2283 nDeltaEntries
= (short)(nMax
- nTemp
);
2284 pImp
->PageDown( (sal_uInt16
)nDeltaEntries
);
2288 if( nDeltaEntries
> nThumb
)
2289 nDeltaEntries
= (short)nThumb
;
2290 pImp
->PageUp( (sal_uInt16
)nDeltaEntries
);
2292 pImp
->SyncVerThumb();
2296 void SvTreeListBox::ScrollToAbsPos( long nPos
)
2298 pImp
->ScrollToAbsPos( nPos
);
2301 void SvTreeListBox::SetSelectionMode( SelectionMode eSelectMode
)
2303 DBG_CHKTHIS(SvTreeListBox
,0);
2304 eSelMode
= eSelectMode
;
2305 pImp
->SetSelectionMode( eSelectMode
);
2308 void SvTreeListBox::SetDragDropMode( DragDropMode nDDMode
)
2310 DBG_CHKTHIS(SvTreeListBox
,0);
2311 nDragDropMode
= nDDMode
;
2312 pImp
->SetDragDropMode( nDDMode
);
2315 short SvTreeListBox::GetHeightOffset(const Image
& rBmp
, Size
& aSizeLogic
)
2317 DBG_CHKTHIS(SvTreeListBox
,0);
2319 aSizeLogic
= rBmp
.GetSizePixel();
2320 if( GetEntryHeight() > aSizeLogic
.Height() )
2321 nOffset
= ( GetEntryHeight() - (short)aSizeLogic
.Height()) / 2;
2325 short SvTreeListBox::GetHeightOffset(const Font
& /* rFont */, Size
& aSizeLogic
)
2327 DBG_CHKTHIS(SvTreeListBox
,0);
2329 aSizeLogic
= Size(GetTextWidth(OUString('X')), GetTextHeight());
2330 if( GetEntryHeight() > aSizeLogic
.Height() )
2331 nOffset
= ( GetEntryHeight() - (short)aSizeLogic
.Height()) / 2;
2335 void SvTreeListBox::SetEntryHeight( SvTreeListEntry
* pEntry
)
2337 DBG_CHKTHIS(SvTreeListBox
,0);
2338 short nHeight
, nHeightMax
=0;
2339 sal_uInt16 nCount
= pEntry
->ItemCount();
2340 sal_uInt16 nCur
= 0;
2341 SvViewDataEntry
* pViewData
= GetViewDataEntry( pEntry
);
2342 while( nCur
< nCount
)
2344 SvLBoxItem
* pItem
= pEntry
->GetItem( nCur
);
2345 nHeight
= (short)(pItem
->GetSize( pViewData
, nCur
).Height());
2346 if( nHeight
> nHeightMax
)
2347 nHeightMax
= nHeight
;
2351 if( nHeightMax
> nEntryHeight
)
2353 nEntryHeight
= nHeightMax
;
2354 Control::SetFont( GetFont() );
2355 pImp
->SetEntryHeight( nHeightMax
);
2359 void SvTreeListBox::SetEntryHeight( short nHeight
, sal_Bool bAlways
)
2361 DBG_CHKTHIS(SvTreeListBox
,0);
2363 if( bAlways
|| nHeight
> nEntryHeight
)
2365 nEntryHeight
= nHeight
;
2367 nTreeFlags
|= TREEFLAG_FIXEDHEIGHT
;
2369 nTreeFlags
&= ~TREEFLAG_FIXEDHEIGHT
;
2370 Control::SetFont( GetFont() );
2371 pImp
->SetEntryHeight( nHeight
);
2376 void SvTreeListBox::AdjustEntryHeight( const Image
& rBmp
)
2378 DBG_CHKTHIS(SvTreeListBox
,0);
2380 GetHeightOffset( rBmp
, aSize
);
2381 if( aSize
.Height() > nEntryHeight
)
2383 nEntryHeight
= (short)aSize
.Height() + nEntryHeightOffs
;
2384 pImp
->SetEntryHeight( nEntryHeight
);
2388 void SvTreeListBox::AdjustEntryHeight( const Font
& rFont
)
2390 DBG_CHKTHIS(SvTreeListBox
,0);
2392 GetHeightOffset( rFont
, aSize
);
2393 if( aSize
.Height() > nEntryHeight
)
2395 nEntryHeight
= (short)aSize
.Height() + nEntryHeightOffs
;
2396 pImp
->SetEntryHeight( nEntryHeight
);
2400 sal_Bool
SvTreeListBox::Expand( SvTreeListEntry
* pParent
)
2402 DBG_CHKTHIS(SvTreeListBox
,0);
2403 pHdlEntry
= pParent
;
2404 sal_Bool bExpanded
= sal_False
;
2407 if( pParent
->HasChildrenOnDemand() )
2408 RequestingChildren( pParent
);
2409 if( pParent
->HasChildren() )
2411 nImpFlags
|= SVLBOX_IS_EXPANDING
;
2412 if( ExpandingHdl() )
2414 bExpanded
= sal_True
;
2415 SvListView::Expand( pParent
);
2416 pImp
->EntryExpanded( pParent
);
2417 pHdlEntry
= pParent
;
2420 nFlags
= pParent
->GetFlags();
2421 nFlags
&= ~SV_ENTRYFLAG_NO_NODEBMP
;
2422 nFlags
|= SV_ENTRYFLAG_HAD_CHILDREN
;
2423 pParent
->SetFlags( nFlags
);
2427 nFlags
= pParent
->GetFlags();
2428 nFlags
|= SV_ENTRYFLAG_NO_NODEBMP
;
2429 pParent
->SetFlags( nFlags
);
2430 GetModel()->InvalidateEntry( pParent
); // repaint
2436 pImp
->CallEventListeners( VCLEVENT_ITEM_EXPANDED
, pParent
);
2442 sal_Bool
SvTreeListBox::Collapse( SvTreeListEntry
* pParent
)
2444 DBG_CHKTHIS(SvTreeListBox
,0);
2445 nImpFlags
&= ~SVLBOX_IS_EXPANDING
;
2446 pHdlEntry
= pParent
;
2447 sal_Bool bCollapsed
= sal_False
;
2449 if( ExpandingHdl() )
2451 bCollapsed
= sal_True
;
2452 pImp
->CollapsingEntry( pParent
);
2453 SvListView::Collapse( pParent
);
2454 pImp
->EntryCollapsed( pParent
);
2455 pHdlEntry
= pParent
;
2462 pImp
->CallEventListeners( VCLEVENT_ITEM_COLLAPSED
, pParent
);
2468 sal_Bool
SvTreeListBox::Select( SvTreeListEntry
* pEntry
, sal_Bool bSelect
)
2470 DBG_CHKTHIS(SvTreeListBox
,0);
2471 DBG_ASSERT(pEntry
,"Select: Null-Ptr");
2472 sal_Bool bRetVal
= SvListView::Select( pEntry
, bSelect
);
2473 DBG_ASSERT(IsSelected(pEntry
)==bSelect
,"Select failed");
2476 pImp
->EntrySelected( pEntry
, bSelect
);
2481 pImp
->CallEventListeners( VCLEVENT_LISTBOX_SELECT
, pEntry
);
2489 sal_uLong
SvTreeListBox::SelectChildren( SvTreeListEntry
* pParent
, sal_Bool bSelect
)
2491 DBG_CHKTHIS(SvTreeListBox
,0);
2492 pImp
->DestroyAnchor();
2494 if( !pParent
->HasChildren() )
2496 sal_uInt16 nRefDepth
= pModel
->GetDepth( pParent
);
2497 SvTreeListEntry
* pChild
= FirstChild( pParent
);
2500 Select( pChild
, bSelect
);
2501 pChild
= Next( pChild
);
2502 } while( pChild
&& pModel
->GetDepth( pChild
) > nRefDepth
);
2506 void SvTreeListBox::SelectAll( sal_Bool bSelect
, sal_Bool
)
2508 DBG_CHKTHIS(SvTreeListBox
,0);
2509 pImp
->SelAllDestrAnch(
2511 sal_True
, // delete anchor,
2512 sal_True
); // even when using SINGLE_SELECTION, deselect the cursor
2515 void SvTreeListBox::ModelHasInsertedTree( SvTreeListEntry
* pEntry
)
2517 DBG_CHKTHIS(SvTreeListBox
,0);
2518 sal_uInt16 nRefDepth
= pModel
->GetDepth( (SvTreeListEntry
*)pEntry
);
2519 SvTreeListEntry
* pTmp
= (SvTreeListEntry
*)pEntry
;
2522 ImpEntryInserted( pTmp
);
2523 pTmp
= Next( pTmp
);
2524 } while( pTmp
&& nRefDepth
< pModel
->GetDepth( pTmp
) );
2525 pImp
->TreeInserted( (SvTreeListEntry
*)pEntry
);
2528 void SvTreeListBox::ModelHasInserted( SvTreeListEntry
* pEntry
)
2530 DBG_CHKTHIS(SvTreeListBox
,0);
2531 ImpEntryInserted( (SvTreeListEntry
*)pEntry
);
2532 pImp
->EntryInserted( (SvTreeListEntry
*)pEntry
);
2535 void SvTreeListBox::ModelIsMoving(SvTreeListEntry
* pSource
,
2536 SvTreeListEntry
* /* pTargetParent */,
2537 sal_uLong
/* nChildPos */ )
2539 DBG_CHKTHIS(SvTreeListBox
,0);
2540 pImp
->MovingEntry( (SvTreeListEntry
*)pSource
);
2543 void SvTreeListBox::ModelHasMoved( SvTreeListEntry
* pSource
)
2545 DBG_CHKTHIS(SvTreeListBox
,0);
2546 pImp
->EntryMoved( (SvTreeListEntry
*)pSource
);
2549 void SvTreeListBox::ModelIsRemoving( SvTreeListEntry
* pEntry
)
2551 DBG_CHKTHIS(SvTreeListBox
,0);
2552 if(pEdEntry
== pEntry
)
2555 pImp
->RemovingEntry( (SvTreeListEntry
*)pEntry
);
2556 NotifyRemoving( (SvTreeListEntry
*)pEntry
);
2559 void SvTreeListBox::ModelHasRemoved( SvTreeListEntry
* pEntry
)
2561 DBG_CHKTHIS(SvTreeListBox
,0);
2562 if ( pEntry
== pHdlEntry
)
2564 pImp
->EntryRemoved();
2567 void SvTreeListBox::SetCollapsedNodeBmp( const Image
& rBmp
)
2569 DBG_CHKTHIS(SvTreeListBox
,0);
2570 AdjustEntryHeight( rBmp
);
2571 pImp
->SetCollapsedNodeBmp( rBmp
);
2574 void SvTreeListBox::SetExpandedNodeBmp( const Image
& rBmp
)
2576 DBG_CHKTHIS(SvTreeListBox
,0);
2577 AdjustEntryHeight( rBmp
);
2578 pImp
->SetExpandedNodeBmp( rBmp
);
2582 void SvTreeListBox::SetFont( const Font
& rFont
)
2584 DBG_CHKTHIS(SvTreeListBox
,0);
2586 Font
aTempFont( rFont
);
2587 Font
aOrigFont( GetFont() );
2588 aTempFont
.SetTransparent( sal_True
);
2589 if (aTempFont
== aOrigFont
)
2591 Control::SetFont( aTempFont
);
2593 aTempFont
.SetColor(aOrigFont
.GetColor());
2594 aTempFont
.SetFillColor(aOrigFont
.GetFillColor());
2595 aTempFont
.SetTransparent(aOrigFont
.IsTransparent());
2597 if (aTempFont
== aOrigFont
)
2600 AdjustEntryHeightAndRecalc( GetFont() );
2603 void SvTreeListBox::AdjustEntryHeightAndRecalc( const Font
& rFont
)
2605 DBG_CHKTHIS(SvTreeListBox
,0);
2606 AdjustEntryHeight( rFont
);
2607 // always invalidate, else things go wrong in SetEntryHeight
2611 void SvTreeListBox::Paint( const Rectangle
& rRect
)
2613 DBG_CHKTHIS(SvTreeListBox
,0);
2614 Control::Paint( rRect
);
2615 if( nTreeFlags
& TREEFLAG_RECALCTABS
)
2617 pImp
->Paint( rRect
);
2620 void SvTreeListBox::MouseButtonDown( const MouseEvent
& rMEvt
)
2622 DBG_CHKTHIS(SvTreeListBox
,0);
2623 pImp
->MouseButtonDown( rMEvt
);
2626 void SvTreeListBox::MouseButtonUp( const MouseEvent
& rMEvt
)
2628 DBG_CHKTHIS(SvTreeListBox
,0);
2629 pImp
->MouseButtonUp( rMEvt
);
2632 void SvTreeListBox::MouseMove( const MouseEvent
& rMEvt
)
2634 DBG_CHKTHIS(SvTreeListBox
,0);
2635 pImp
->MouseMove( rMEvt
);
2639 void SvTreeListBox::SetUpdateMode( sal_Bool bUpdate
)
2641 DBG_CHKTHIS(SvTreeListBox
,0);
2642 pImp
->SetUpdateMode( bUpdate
);
2645 void SvTreeListBox::SetSpaceBetweenEntries( short nOffsLogic
)
2647 DBG_CHKTHIS(SvTreeListBox
,0);
2648 if( nOffsLogic
!= nEntryHeightOffs
)
2650 nEntryHeight
= nEntryHeight
- nEntryHeightOffs
;
2651 nEntryHeightOffs
= (short)nOffsLogic
;
2652 nEntryHeight
= nEntryHeight
+ nOffsLogic
;
2653 AdjustEntryHeightAndRecalc( GetFont() );
2654 pImp
->SetEntryHeight( nEntryHeight
);
2658 void SvTreeListBox::SetCursor( SvTreeListEntry
* pEntry
, sal_Bool bForceNoSelect
)
2660 DBG_CHKTHIS(SvTreeListBox
,0);
2661 pImp
->SetCursor(pEntry
, bForceNoSelect
);
2664 void SvTreeListBox::SetCurEntry( SvTreeListEntry
* pEntry
)
2666 DBG_CHKTHIS(SvTreeListBox
,0);
2667 pImp
->SetCurEntry( pEntry
);
2670 Image
SvTreeListBox::GetExpandedNodeBmp( ) const
2672 return pImp
->GetExpandedNodeBmp( );
2675 Point
SvTreeListBox::GetEntryPosition( SvTreeListEntry
* pEntry
) const
2677 return pImp
->GetEntryPosition( pEntry
);
2680 void SvTreeListBox::ShowEntry( SvTreeListEntry
* pEntry
)
2682 MakeVisible( pEntry
);
2685 void SvTreeListBox::MakeVisible( SvTreeListEntry
* pEntry
)
2687 pImp
->MakeVisible(pEntry
);
2690 void SvTreeListBox::MakeVisible( SvTreeListEntry
* pEntry
, sal_Bool bMoveToTop
)
2692 pImp
->MakeVisible( pEntry
, bMoveToTop
);
2695 void SvTreeListBox::ModelHasEntryInvalidated( SvTreeListEntry
* pEntry
)
2697 DBG_CHKTHIS(SvTreeListBox
,0);
2699 // reinitialize the separate items of the entries
2700 sal_uInt16 nCount
= ((SvTreeListEntry
*)pEntry
)->ItemCount();
2701 for( sal_uInt16 nIdx
= 0; nIdx
< nCount
; nIdx
++ )
2703 SvLBoxItem
* pItem
= ((SvTreeListEntry
*)pEntry
)->GetItem( nIdx
);
2704 pItem
->InitViewData( this, (SvTreeListEntry
*)pEntry
, 0 );
2708 pImp
->InvalidateEntry( (SvTreeListEntry
*)pEntry
);
2711 void SvTreeListBox::EditItemText( SvTreeListEntry
* pEntry
, SvLBoxString
* pItem
,
2712 const Selection
& rSelection
)
2714 DBG_CHKTHIS(SvTreeListBox
,0);
2715 DBG_ASSERT(pEntry
&&pItem
,"EditItemText: Bad params");
2716 if( IsSelected( pEntry
))
2718 pImp
->ShowCursor( sal_False
);
2719 SvListView::Select( pEntry
, sal_False
);
2720 PaintEntry( pEntry
);
2721 SvListView::Select( pEntry
, sal_True
);
2722 pImp
->ShowCursor( sal_True
);
2726 SvLBoxTab
* pTab
= GetTab( pEntry
, pItem
);
2727 DBG_ASSERT(pTab
,"EditItemText:Tab not found");
2729 Size
aItemSize( pItem
->GetSize(this, pEntry
) );
2730 Point aPos
= GetEntryPosition( pEntry
);
2731 aPos
.Y() += ( nEntryHeight
- aItemSize
.Height() ) / 2;
2732 aPos
.X() = GetTabPos( pEntry
, pTab
);
2733 long nOutputWidth
= pImp
->GetOutputSize().Width();
2734 Size
aSize( nOutputWidth
- aPos
.X(), aItemSize
.Height() );
2735 sal_uInt16 nPos
= std::find( aTabs
.begin(), aTabs
.end(), pTab
) - aTabs
.begin();
2736 if( nPos
+1 < (sal_uInt16
)aTabs
.size() )
2738 SvLBoxTab
* pRightTab
= aTabs
[ nPos
+ 1 ];
2739 long nRight
= GetTabPos( pEntry
, pRightTab
);
2740 if( nRight
<= nOutputWidth
)
2741 aSize
.Width() = nRight
- aPos
.X();
2743 Point
aOrigin( GetMapMode().GetOrigin() );
2744 aPos
+= aOrigin
; // convert to win coordinates
2745 aSize
.Width() -= aOrigin
.X();
2746 Rectangle
aRect( aPos
, aSize
);
2747 EditText( pItem
->GetText(), aRect
, rSelection
);
2750 void SvTreeListBox::EditEntry( SvTreeListEntry
* pEntry
)
2752 pImp
->aEditClickPos
= Point( -1, -1 );
2753 ImplEditEntry( pEntry
);
2756 void SvTreeListBox::ImplEditEntry( SvTreeListEntry
* pEntry
)
2758 DBG_CHKTHIS(SvTreeListBox
,0);
2759 if( IsEditingActive() )
2762 pEntry
= GetCurEntry();
2765 long nClickX
= pImp
->aEditClickPos
.X();
2766 bool bIsMouseTriggered
= nClickX
>= 0;
2768 SvLBoxString
* pItem
= NULL
;
2769 sal_uInt16 nCount
= pEntry
->ItemCount();
2770 long nTabPos
, nNextTabPos
= 0;
2771 for( sal_uInt16 i
= 0 ; i
< nCount
; i
++ )
2773 SvLBoxItem
* pTmpItem
= pEntry
->GetItem( i
);
2774 if (pTmpItem
->GetType() != SV_ITEM_ID_LBOXSTRING
)
2777 SvLBoxTab
* pTab
= GetTab( pEntry
, pTmpItem
);
2779 if( i
< nCount
- 1 )
2781 SvLBoxItem
* pNextItem
= pEntry
->GetItem( i
+ 1 );
2782 SvLBoxTab
* pNextTab
= GetTab( pEntry
, pNextItem
);
2783 nNextTabPos
= pNextTab
->GetPos();
2786 if( pTab
&& pTab
->IsEditable() )
2788 nTabPos
= pTab
->GetPos();
2789 if( !bIsMouseTriggered
|| (nClickX
> nTabPos
&& (nNextTabPos
== -1 || nClickX
< nNextTabPos
) ) )
2791 pItem
= static_cast<SvLBoxString
*>( pTmpItem
);
2797 Selection
aSel( SELECTION_MIN
, SELECTION_MAX
);
2798 if( pItem
&& EditingEntry( pEntry
, aSel
) )
2800 SelectAll( sal_False
);
2801 MakeVisible( pEntry
);
2802 EditItemText( pEntry
, pItem
, aSel
);
2807 sal_Bool
SvTreeListBox::AreChildrenTransient() const
2809 return pImp
->AreChildrenTransient();
2812 void SvTreeListBox::SetChildrenNotTransient()
2814 pImp
->SetChildrenNotTransient();
2817 void SvTreeListBox::EditedText( const XubString
& rStr
)
2820 DBG_CHKTHIS(SvTreeListBox
,0);
2821 if(pEdEntry
) // we have to check if this entry is null that means that it is removed while editing
2823 if( EditedEntry( pEdEntry
, rStr
) )
2825 ((SvLBoxString
*)pEdItem
)->SetText( rStr
);
2826 pModel
->InvalidateEntry( pEdEntry
);
2828 if( GetSelectionCount() == 0 )
2830 if( GetSelectionMode() == MULTIPLE_SELECTION
&& !GetCurEntry() )
2831 SetCurEntry( pEdEntry
);
2835 SvTreeListEntry
* SvTreeListBox::GetDropTarget( const Point
& rPos
)
2837 DBG_CHKTHIS(SvTreeListBox
,0);
2841 ImplShowTargetEmphasis(pTargetEntry
, false);
2842 ScrollOutputArea( +1 );
2846 Size
aSize( pImp
->GetOutputSize() );
2847 if( rPos
.Y() > aSize
.Height() - 12 )
2849 ImplShowTargetEmphasis(pTargetEntry
, false);
2850 ScrollOutputArea( -1 );
2854 SvTreeListEntry
* pTarget
= pImp
->GetEntry( rPos
);
2855 // when dropping in a vacant space, use the last entry
2857 return (SvTreeListEntry
*)LastVisible();
2858 else if( (GetDragDropMode() & SV_DRAGDROP_ENABLE_TOP
) &&
2859 pTarget
== First() && rPos
.Y() < 6 )
2866 SvTreeListEntry
* SvTreeListBox::GetEntry( const Point
& rPos
, sal_Bool bHit
) const
2868 DBG_CHKTHIS(SvTreeListBox
,0);
2869 SvTreeListEntry
* pEntry
= pImp
->GetEntry( rPos
);
2870 if( pEntry
&& bHit
)
2872 long nLine
= pImp
->GetEntryLine( pEntry
);
2873 if( !(pImp
->EntryReallyHit( pEntry
, rPos
, nLine
)) )
2879 SvTreeListEntry
* SvTreeListBox::GetCurEntry() const
2881 DBG_CHKTHIS(SvTreeListBox
,0);
2882 return pImp
->GetCurEntry();
2885 void SvTreeListBox::ImplInitStyle()
2887 DBG_CHKTHIS(SvTreeListBox
,0);
2889 const WinBits nWindowStyle
= GetStyle();
2891 nTreeFlags
|= TREEFLAG_RECALCTABS
;
2892 if( nWindowStyle
& WB_SORT
)
2894 GetModel()->SetSortMode( SortAscending
);
2895 GetModel()->SetCompareHdl( LINK(this,SvTreeListBox
,DefaultCompare
));
2899 GetModel()->SetSortMode( SortNone
);
2900 GetModel()->SetCompareHdl( Link() );
2902 pImp
->SetStyle( nWindowStyle
);
2907 void SvTreeListBox::PaintEntry( SvTreeListEntry
* pEntry
)
2909 DBG_CHKTHIS(SvTreeListBox
,0);
2910 DBG_ASSERT(pEntry
,"PaintEntry:No Entry");
2912 pImp
->PaintEntry( pEntry
);
2915 void SvTreeListBox::InvalidateEntry( SvTreeListEntry
* pEntry
)
2917 DBG_CHKTHIS(SvTreeListBox
,0);
2918 DBG_ASSERT(pEntry
,"InvalidateEntry:No Entry");
2921 GetModel()->InvalidateEntry( pEntry
);
2925 long SvTreeListBox::PaintEntry(SvTreeListEntry
* pEntry
,long nLine
,sal_uInt16 nTabFlags
)
2927 return PaintEntry1(pEntry
,nLine
,nTabFlags
);
2930 long SvTreeListBox::PaintEntry1(SvTreeListEntry
* pEntry
,long nLine
,sal_uInt16 nTabFlags
,
2931 sal_Bool bHasClipRegion
)
2933 DBG_CHKTHIS(SvTreeListBox
,0);
2935 Rectangle aRect
; // multi purpose
2937 sal_Bool bHorSBar
= pImp
->HasHorScrollBar();
2938 PreparePaint( pEntry
);
2940 pImp
->UpdateContextBmpWidthMax( pEntry
);
2942 if( nTreeFlags
& TREEFLAG_RECALCTABS
)
2945 short nTempEntryHeight
= GetEntryHeight();
2946 long nWidth
= pImp
->GetOutputSize().Width();
2948 // Did we turn on the scrollbar within PreparePaints? If yes, we have to set
2949 // the ClipRegion anew.
2950 if( !bHorSBar
&& pImp
->HasHorScrollBar() )
2951 SetClipRegion( Region(pImp
->GetClipRegionRect()) );
2953 Point
aEntryPos( GetMapMode().GetOrigin() );
2954 aEntryPos
.X() *= -1; // conversion document coordinates
2955 long nMaxRight
= nWidth
+ aEntryPos
.X() - 1;
2957 Color
aBackupTextColor( GetTextColor() );
2958 Font
aBackupFont( GetFont() );
2959 Color aBackupColor
= GetFillColor();
2961 bool bCurFontIsSel
= false;
2962 sal_Bool bInUse
= pEntry
->HasInUseEmphasis();
2963 // if a ClipRegion was set from outside, we don't have to reset it
2964 const WinBits nWindowStyle
= GetStyle();
2965 const sal_Bool bResetClipRegion
= !bHasClipRegion
;
2966 const sal_Bool bHideSelection
= ((nWindowStyle
& WB_HIDESELECTION
) && !HasFocus())!=0;
2967 const StyleSettings
& rSettings
= GetSettings().GetStyleSettings();
2969 Font
aHighlightFont( GetFont() );
2970 const Color
aHighlightTextColor( rSettings
.GetHighlightTextColor() );
2971 aHighlightFont
.SetColor( aHighlightTextColor
);
2973 Size
aRectSize( 0, nTempEntryHeight
);
2975 if( !bHasClipRegion
&& nWindowStyle
& WB_HSCROLL
)
2977 SetClipRegion( Region(pImp
->GetClipRegionRect()) );
2978 bHasClipRegion
= sal_True
;
2981 SvViewDataEntry
* pViewDataEntry
= GetViewDataEntry( pEntry
);
2983 sal_uInt16 nTabCount
= aTabs
.size();
2984 sal_uInt16 nItemCount
= pEntry
->ItemCount();
2985 sal_uInt16 nCurTab
= 0;
2986 sal_uInt16 nCurItem
= 0;
2988 while( nCurTab
< nTabCount
&& nCurItem
< nItemCount
)
2990 SvLBoxTab
* pTab
= aTabs
[ nCurTab
];
2991 sal_uInt16 nNextTab
= nCurTab
+ 1;
2992 SvLBoxTab
* pNextTab
= nNextTab
< nTabCount
? aTabs
[nNextTab
] : 0;
2993 SvLBoxItem
* pItem
= nCurItem
< nItemCount
? pEntry
->GetItem(nCurItem
) : 0;
2995 sal_uInt16 nFlags
= pTab
->nFlags
;
2996 Size
aSize( pItem
->GetSize( pViewDataEntry
, nCurItem
));
2997 long nTabPos
= GetTabPos( pEntry
, pTab
);
3001 nNextTabPos
= GetTabPos( pEntry
, pNextTab
);
3004 nNextTabPos
= nMaxRight
;
3005 if( nTabPos
> nMaxRight
)
3010 if( pTab
->nFlags
& SV_LBOXTAB_ADJUST_RIGHT
)
3011 // avoid cutting the right edge off the tab separation
3012 nX
= nTabPos
+ pTab
->CalcOffset(aSize
.Width(), (nNextTabPos
-SV_TAB_BORDER
-1) -nTabPos
);
3014 nX
= nTabPos
+ pTab
->CalcOffset(aSize
.Width(), nNextTabPos
-nTabPos
);
3016 if( nFlags
& nTabFlags
)
3018 if( !bHasClipRegion
&& nX
+ aSize
.Width() >= nMaxRight
)
3020 SetClipRegion( Region(pImp
->GetClipRegionRect()) );
3021 bHasClipRegion
= sal_True
;
3024 aEntryPos
.Y() = nLine
;
3026 // set background pattern/color
3028 Wallpaper aWallpaper
= GetBackground();
3030 int bSelTab
= nFlags
& SV_LBOXTAB_SHOW_SELECTION
;
3031 sal_uInt16 nItemType
= pItem
->GetType();
3033 if (pViewDataEntry
->IsHighlighted() && bSelTab
&& !pViewDataEntry
->IsCursored())
3035 Color aNewWallColor
= rSettings
.GetHighlightColor();
3036 if ( !bInUse
|| nItemType
!= SV_ITEM_ID_LBOXCONTEXTBMP
)
3038 // if the face color is bright then the deactive color is also bright
3039 // -> so you can't see any deactive selection
3040 if ( bHideSelection
&& !rSettings
.GetFaceColor().IsBright() &&
3041 aWallpaper
.GetColor().IsBright() != rSettings
.GetDeactiveColor().IsBright() )
3042 aNewWallColor
= rSettings
.GetDeactiveColor();
3043 // set font color to highlight
3044 if ( !bCurFontIsSel
)
3046 SetTextColor( aHighlightTextColor
);
3047 Control::SetFont( aHighlightFont
);
3048 bCurFontIsSel
= true;
3051 aWallpaper
.SetColor( aNewWallColor
);
3053 else // no selection
3055 if( bInUse
&& nItemType
== SV_ITEM_ID_LBOXCONTEXTBMP
)
3056 aWallpaper
.SetColor( rSettings
.GetFieldColor() );
3057 else if( bCurFontIsSel
)
3059 bCurFontIsSel
= false;
3060 SetTextColor( aBackupTextColor
);
3061 Control::SetFont( aBackupFont
);
3066 if( !(nTreeFlags
& TREEFLAG_USESEL
))
3068 // only draw the area that is used by the item
3069 aRectSize
.Width() = aSize
.Width();
3070 aRect
.SetPos( aEntryPos
);
3071 aRect
.SetSize( aRectSize
);
3075 // draw from the current to the next tab
3077 aRect
.Left() = nTabPos
;
3079 // if we're in the 0th tab, always draw from column 0 --
3080 // else we get problems with centered tabs
3082 aRect
.Top() = nLine
;
3083 aRect
.Bottom() = nLine
+ nTempEntryHeight
- 1;
3087 nRight
= GetTabPos(pEntry
,pNextTab
)-1;
3088 if( nRight
> nMaxRight
)
3090 aRect
.Right() = nRight
;
3093 aRect
.Right() = nMaxRight
;
3095 // A custom selection that starts at a tab position > 0, do not fill
3096 // the background of the 0th item, else e.g. we might not be able to
3097 // realize tab listboxes with lines.
3098 if( !(nCurTab
==0 && (nTreeFlags
& TREEFLAG_USESEL
) && nFirstSelTab
) )
3100 SetFillColor( aWallpaper
.GetColor() );
3101 // this case may occur for smaller horizontal resizes
3102 if( aRect
.Left() < aRect
.Right() )
3106 // center vertically
3107 aEntryPos
.Y() += ( nTempEntryHeight
- aSize
.Height() ) / 2;
3108 pItem
->Paint(aEntryPos
, *this, pViewDataEntry
, pEntry
);
3110 // division line between tabs
3111 if (pNextTab
&& pItem
->GetType() == SV_ITEM_ID_LBOXSTRING
&&
3112 // not at the right edge of the window!
3113 aRect
.Right() < nMaxRight
)
3115 aRect
.Left() = aRect
.Right() - SV_TAB_BORDER
;
3119 SetFillColor( aBackupColor
);
3124 if( pViewDataEntry
->IsCursored() && !HasFocus() )
3128 Color aOldLineColor
= GetLineColor();
3129 SetLineColor( Color( COL_BLACK
) );
3130 aRect
= GetFocusRect( pEntry
, nLine
);
3134 SetLineColor( aOldLineColor
);
3135 SetFillColor( aBackupColor
);
3140 SetTextColor( aBackupTextColor
);
3141 Control::SetFont( aBackupFont
);
3144 sal_uInt16 nFirstDynTabPos
;
3145 SvLBoxTab
* pFirstDynamicTab
= GetFirstDynamicTab( nFirstDynTabPos
);
3146 long nDynTabPos
= GetTabPos( pEntry
, pFirstDynamicTab
);
3147 nDynTabPos
+= pImp
->nNodeBmpTabDistance
;
3148 nDynTabPos
+= pImp
->nNodeBmpWidth
/ 2;
3149 nDynTabPos
+= 4; // 4 pixels of buffer, so the node bitmap is not too close
3152 if( (!(pEntry
->GetFlags() & SV_ENTRYFLAG_NO_NODEBMP
)) &&
3153 (nWindowStyle
& WB_HASBUTTONS
) && pFirstDynamicTab
&&
3154 ( pEntry
->HasChildren() || pEntry
->HasChildrenOnDemand() ) )
3156 // find first tab and check if the node bitmap extends into it
3157 sal_uInt16 nNextTab
= nFirstDynTabPos
;
3158 SvLBoxTab
* pNextTab
;
3162 pNextTab
= nNextTab
< nTabCount
? aTabs
[nNextTab
] : 0;
3163 } while( pNextTab
&& pNextTab
->IsDynamic() );
3165 if( !pNextTab
|| (GetTabPos( pEntry
, pNextTab
) > nDynTabPos
) )
3167 if((nWindowStyle
& WB_HASBUTTONSATROOT
) || pModel
->GetDepth(pEntry
) > 0)
3169 Point
aPos( GetTabPos(pEntry
,pFirstDynamicTab
), nLine
);
3170 aPos
.X() += pImp
->nNodeBmpTabDistance
;
3172 const Image
* pImg
= 0;
3174 if( IsExpanded(pEntry
) )
3175 pImg
= &pImp
->GetExpandedNodeBmp( );
3178 if( (!pEntry
->HasChildren()) && pEntry
->HasChildrenOnDemand() &&
3179 (!(pEntry
->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN
)) &&
3180 pImp
->GetDontKnowNodeBmp().GetSizePixel().Width() )
3181 pImg
= &pImp
->GetDontKnowNodeBmp( );
3183 pImg
= &pImp
->GetCollapsedNodeBmp( );
3185 aPos
.Y() += (nTempEntryHeight
- pImg
->GetSizePixel().Height()) / 2;
3187 sal_uInt16 nStyle
= 0;
3189 nStyle
|= IMAGE_DRAW_DISABLE
;
3192 sal_Bool bNativeOK
= sal_False
;
3193 if ( IsNativeControlSupported( CTRL_LISTNODE
, PART_ENTIRE_CONTROL
) )
3195 ImplControlValue aControlValue
;
3196 Rectangle
aCtrlRegion( aPos
, pImg
->GetSizePixel() );
3197 ControlState nState
= 0;
3199 if ( IsEnabled() ) nState
|= CTRL_STATE_ENABLED
;
3201 if ( IsExpanded(pEntry
) )
3202 aControlValue
.setTristateVal( BUTTONVALUE_ON
);//expanded node
3205 if( (!pEntry
->HasChildren() ) &&
3206 pEntry
->HasChildrenOnDemand() &&
3207 (!(pEntry
->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN
)) &&
3208 pImp
->GetDontKnowNodeBmp().GetSizePixel().Width()
3210 aControlValue
.setTristateVal( BUTTONVALUE_DONTKNOW
); //dont know
3212 aControlValue
.setTristateVal( BUTTONVALUE_OFF
); //collapsed node
3215 bNativeOK
= DrawNativeControl( CTRL_LISTNODE
, PART_ENTIRE_CONTROL
,
3216 aCtrlRegion
, nState
, aControlValue
, OUString() );
3220 DrawImage( aPos
, *pImg
,nStyle
);
3227 if( bHasClipRegion
&& bResetClipRegion
)
3229 return 0; // nRowLen;
3232 void SvTreeListBox::PreparePaint( SvTreeListEntry
* )
3236 Rectangle
SvTreeListBox::GetFocusRect( SvTreeListEntry
* pEntry
, long nLine
)
3238 DBG_CHKTHIS(SvTreeListBox
,0);
3241 aRect
.Top() = nLine
;
3242 aSize
.Height() = GetEntryHeight();
3244 long nRealWidth
= pImp
->GetOutputSize().Width();
3245 nRealWidth
-= GetMapMode().GetOrigin().X();
3248 SvLBoxTab
* pTab
= GetFirstTab( SV_LBOXTAB_SHOW_SELECTION
, nCurTab
);
3251 nTabPos
= GetTabPos( pEntry
, pTab
);
3253 if( pTab
&& nCurTab
< aTabs
.size() - 1 )
3255 SvLBoxTab
* pNextTab
= aTabs
[ nCurTab
+ 1 ];
3256 nNextTabPos
= GetTabPos( pEntry
, pNextTab
);
3260 nNextTabPos
= nRealWidth
;
3261 if( nTabPos
> nRealWidth
)
3265 sal_Bool bUserSelection
= (sal_Bool
)( nTreeFlags
& TREEFLAG_USESEL
) != 0;
3266 if( !bUserSelection
)
3268 if( pTab
&& nCurTab
< pEntry
->ItemCount() )
3270 SvLBoxItem
* pItem
= pEntry
->GetItem( nCurTab
);
3271 aSize
.Width() = pItem
->GetSize( this, pEntry
).Width();
3272 if( !aSize
.Width() )
3274 long nX
= nTabPos
; //GetTabPos( pEntry, pTab );
3276 nX
+= pTab
->CalcOffset( aSize
.Width(), nNextTabPos
- nTabPos
);
3278 // make sure that first and last letter aren't cut off slightly
3279 aRect
.SetSize( aSize
);
3280 if( aRect
.Left() > 0 )
3287 // if SelTab != 0, we have to calculate also
3288 if( nFocusWidth
== -1 || nFirstSelTab
)
3290 sal_uInt16 nLastTab
;
3291 SvLBoxTab
* pLastTab
= GetLastTab(SV_LBOXTAB_SHOW_SELECTION
,nLastTab
);
3293 if( nLastTab
< aTabs
.size() ) // is there another one?
3294 pLastTab
= aTabs
[ nLastTab
];
3296 pLastTab
= 0; // select whole width
3297 aSize
.Width() = pLastTab
? pLastTab
->GetPos() : 0x0fffffff;
3298 nFocusWidth
= (short)aSize
.Width();
3300 nFocusWidth
= nFocusWidth
- (short)nTabPos
; //pTab->GetPos();
3304 aSize
.Width() = nFocusWidth
;
3308 aSize
.Width() += nTabPos
;
3310 aSize
.Width() += pTab
->GetPos(); // Tab0 always from the leftmost position
3313 // if selection starts with 0th tab, draw from column 0 on
3316 aRect
.Left() = nTabPos
;
3317 aSize
.Width() -= nTabPos
;
3319 aRect
.SetSize( aSize
);
3321 // adjust right edge because of clipping
3322 if( aRect
.Right() >= nRealWidth
)
3324 aRect
.Right() = nRealWidth
-1;
3325 nFocusWidth
= (short)aRect
.GetWidth();
3331 long SvTreeListBox::GetTabPos( SvTreeListEntry
* pEntry
, SvLBoxTab
* pTab
)
3333 DBG_CHKTHIS(SvTreeListBox
,0);
3334 DBG_ASSERT(pTab
,"No Tab");
3335 long nPos
= pTab
->GetPos();
3336 if( pTab
->IsDynamic() )
3338 sal_uInt16 nDepth
= pModel
->GetDepth( pEntry
);
3339 nDepth
= nDepth
* (sal_uInt16
)nIndent
;
3340 nPos
+= (long)nDepth
;
3345 SvLBoxItem
* SvTreeListBox::GetItem_Impl( SvTreeListEntry
* pEntry
, long nX
,
3346 SvLBoxTab
** ppTab
, sal_uInt16 nEmptyWidth
)
3348 DBG_CHKTHIS(SvTreeListBox
,0);
3349 SvLBoxItem
* pItemClicked
= 0;
3350 sal_uInt16 nTabCount
= aTabs
.size();
3351 sal_uInt16 nItemCount
= pEntry
->ItemCount();
3352 SvLBoxTab
* pTab
= aTabs
.front();
3353 SvLBoxItem
* pItem
= pEntry
->GetItem(0);
3354 sal_uInt16 nNextItem
= 1;
3355 nX
-= GetMapMode().GetOrigin().X();
3356 long nRealWidth
= pImp
->GetOutputSize().Width();
3357 nRealWidth
-= GetMapMode().GetOrigin().X();
3361 SvLBoxTab
* pNextTab
=nNextItem
<nTabCount
? aTabs
[nNextItem
] : 0;
3362 long nStart
= GetTabPos( pEntry
, pTab
);
3366 nNextTabPos
= GetTabPos( pEntry
, pNextTab
);
3369 nNextTabPos
= nRealWidth
;
3370 if( nStart
> nRealWidth
)
3374 Size
aItemSize( pItem
->GetSize(this, pEntry
));
3375 nStart
+= pTab
->CalcOffset( aItemSize
.Width(), nNextTabPos
- nStart
);
3376 long nLen
= aItemSize
.Width();
3379 long nTabWidth
= GetTabPos( pEntry
, pNextTab
) - nStart
;
3380 if( nTabWidth
< nLen
)
3387 if( nX
>= nStart
&& nX
< (nStart
+nLen
) )
3389 pItemClicked
= pItem
;
3396 if( nNextItem
>= nItemCount
|| nNextItem
>= nTabCount
)
3398 pTab
= aTabs
[ nNextItem
];
3399 pItem
= pEntry
->GetItem( nNextItem
);
3402 return pItemClicked
;
3405 long SvTreeListBox::getPreferredDimensions(std::vector
<long> &rWidths
) const
3409 SvTreeListEntry
* pEntry
= First();
3412 sal_uInt16 nCount
= pEntry
->ItemCount();
3413 sal_uInt16 nCurPos
= 0;
3414 if (nCount
> rWidths
.size())
3415 rWidths
.resize(nCount
);
3416 while (nCurPos
< nCount
)
3418 SvLBoxItem
* pItem
= pEntry
->GetItem( nCurPos
);
3419 long nWidth
= pItem
->GetSize(this, pEntry
).Width();
3422 nWidth
+= SV_TAB_BORDER
* 2;
3423 if (nWidth
> rWidths
[nCurPos
])
3424 rWidths
[nCurPos
] = nWidth
;
3428 pEntry
= Next( pEntry
);
3429 nHeight
+= GetEntryHeight();
3434 Size
SvTreeListBox::GetOptimalSize() const
3436 std::vector
<long> aWidths
;
3437 Size
aRet(0, getPreferredDimensions(aWidths
));
3438 for (size_t i
= 0; i
< aWidths
.size(); ++i
)
3439 aRet
.Width() += aWidths
[i
];
3440 if (GetStyle() & WB_BORDER
)
3442 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
3443 aRet
.Width() += rStyleSettings
.GetBorderSize() * 2;
3444 aRet
.Height() += rStyleSettings
.GetBorderSize() * 2;
3449 SvLBoxItem
* SvTreeListBox::GetItem(SvTreeListEntry
* pEntry
,long nX
,SvLBoxTab
** ppTab
)
3451 return GetItem_Impl( pEntry
, nX
, ppTab
, 0 );
3454 SvLBoxItem
* SvTreeListBox::GetItem(SvTreeListEntry
* pEntry
,long nX
)
3456 DBG_CHKTHIS(SvTreeListBox
,0);
3457 SvLBoxTab
* pDummyTab
;
3458 return GetItem_Impl( pEntry
, nX
, &pDummyTab
, 0 );
3461 void SvTreeListBox::AddTab(long nTabPos
,sal_uInt16 nFlags
,void* pUserData
)
3463 DBG_CHKTHIS(SvTreeListBox
,0);
3465 SvLBoxTab
* pTab
= new SvLBoxTab( nTabPos
, nFlags
);
3466 pTab
->SetUserData( pUserData
);
3467 aTabs
.push_back( pTab
);
3468 if( nTreeFlags
& TREEFLAG_USESEL
)
3470 sal_uInt16 nPos
= aTabs
.size() - 1;
3471 if( nPos
>= nFirstSelTab
&& nPos
<= nLastSelTab
)
3472 pTab
->nFlags
|= SV_LBOXTAB_SHOW_SELECTION
;
3474 // string items usually have to be selected -- turn this off
3476 pTab
->nFlags
&= ~SV_LBOXTAB_SHOW_SELECTION
;
3482 SvLBoxTab
* SvTreeListBox::GetFirstDynamicTab( sal_uInt16
& rPos
) const
3484 DBG_CHKTHIS(SvTreeListBox
,0);
3485 sal_uInt16 nCurTab
= 0;
3486 sal_uInt16 nTabCount
= aTabs
.size();
3487 while( nCurTab
< nTabCount
)
3489 SvLBoxTab
* pTab
= aTabs
[nCurTab
];
3490 if( pTab
->nFlags
& SV_LBOXTAB_DYNAMIC
)
3500 SvLBoxTab
* SvTreeListBox::GetFirstDynamicTab() const
3503 return GetFirstDynamicTab( nDummy
);
3506 SvLBoxTab
* SvTreeListBox::GetTab( SvTreeListEntry
* pEntry
, SvLBoxItem
* pItem
) const
3508 DBG_CHKTHIS(SvTreeListBox
,0);
3509 sal_uInt16 nPos
= pEntry
->GetPos( pItem
);
3510 return aTabs
[ nPos
];
3513 void SvTreeListBox::ClearTabList()
3515 DBG_CHKTHIS(SvTreeListBox
,0);
3516 sal_uInt16 nTabCount
= aTabs
.size();
3520 SvLBoxTab
* pDelTab
= aTabs
[ nTabCount
];
3527 Size
SvTreeListBox::GetOutputSizePixel() const
3529 DBG_CHKTHIS(SvTreeListBox
,0);
3530 Size aSize
= pImp
->GetOutputSize();
3534 void SvTreeListBox::NotifyBeginScroll()
3536 DBG_CHKTHIS(SvTreeListBox
,0);
3539 void SvTreeListBox::NotifyEndScroll()
3541 DBG_CHKTHIS(SvTreeListBox
,0);
3544 void SvTreeListBox::NotifyScrolling( long )
3546 DBG_CHKTHIS(SvTreeListBox
,0);
3549 void SvTreeListBox::NotifyScrolled()
3551 DBG_CHKTHIS(SvTreeListBox
,0);
3552 aScrolledHdl
.Call( this );
3555 void SvTreeListBox::NotifyInvalidating()
3557 DBG_CHKTHIS(SvTreeListBox
,0);
3560 void SvTreeListBox::Invalidate( sal_uInt16 nInvalidateFlags
)
3562 DBG_CHKTHIS(SvTreeListBox
,0);
3563 if( nFocusWidth
== -1 )
3564 // to make sure that the control doesn't show the wrong focus rectangle
3566 pImp
->RecalcFocusRect();
3567 NotifyInvalidating();
3568 Control::Invalidate( nInvalidateFlags
);
3572 void SvTreeListBox::Invalidate( const Rectangle
& rRect
, sal_uInt16 nInvalidateFlags
)
3574 DBG_CHKTHIS(SvTreeListBox
,0);
3575 if( nFocusWidth
== -1 )
3576 // to make sure that the control doesn't show the wrong focus rectangle
3578 pImp
->RecalcFocusRect();
3579 NotifyInvalidating();
3580 Control::Invalidate( rRect
, nInvalidateFlags
);
3584 void SvTreeListBox::SetHighlightRange( sal_uInt16 nStart
, sal_uInt16 nEnd
)
3586 DBG_CHKTHIS(SvTreeListBox
,0);
3589 nTreeFlags
|= TREEFLAG_USESEL
;
3596 // select all tabs that lie within the area
3597 nTreeFlags
|= TREEFLAG_RECALCTABS
;
3598 nFirstSelTab
= nStart
;
3600 pImp
->RecalcFocusRect();
3603 void SvTreeListBox::Command( const CommandEvent
& rCEvt
)
3605 DBG_CHKTHIS(SvTreeListBox
,0);
3606 // FIXME gnumake2 resync to DEV300_m84
3607 pImp
->Command( rCEvt
);
3611 void SvTreeListBox::RemoveParentKeepChildren( SvTreeListEntry
* pParent
)
3613 DBG_CHKTHIS(SvTreeListBox
,0);
3614 DBG_ASSERT(pParent
,"RemoveParentKeepChildren:No Parent");
3615 SvTreeListEntry
* pNewParent
= GetParent( pParent
);
3616 if( pParent
->HasChildren())
3618 SvTreeListEntry
* pChild
= FirstChild( pParent
);
3621 pModel
->Move( pChild
, pNewParent
, LIST_APPEND
);
3622 pChild
= FirstChild( pParent
);
3625 pModel
->Remove( pParent
);
3628 SvLBoxTab
* SvTreeListBox::GetFirstTab( sal_uInt16 nFlagMask
, sal_uInt16
& rPos
)
3630 sal_uInt16 nTabCount
= aTabs
.size();
3631 for( sal_uInt16 nPos
= 0; nPos
< nTabCount
; nPos
++ )
3633 SvLBoxTab
* pTab
= aTabs
[ nPos
];
3634 if( (pTab
->nFlags
& nFlagMask
) )
3644 SvLBoxTab
* SvTreeListBox::GetLastTab( sal_uInt16 nFlagMask
, sal_uInt16
& rTabPos
)
3646 sal_uInt16 nPos
= (sal_uInt16
)aTabs
.size();
3650 SvLBoxTab
* pTab
= aTabs
[ nPos
];
3651 if( (pTab
->nFlags
& nFlagMask
) )
3661 void SvTreeListBox::RequestHelp( const HelpEvent
& rHEvt
)
3663 if( !pImp
->RequestHelp( rHEvt
) )
3664 Control::RequestHelp( rHEvt
);
3667 void SvTreeListBox::CursorMoved( SvTreeListEntry
* )
3671 IMPL_LINK( SvTreeListBox
, DefaultCompare
, SvSortData
*, pData
)
3673 const SvTreeListEntry
* pLeft
= pData
->pLeft
;
3674 const SvTreeListEntry
* pRight
= pData
->pRight
;
3675 String
aLeft( ((SvLBoxString
*)(pLeft
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
)))->GetText());
3676 String
aRight( ((SvLBoxString
*)(pRight
->GetFirstItem(SV_ITEM_ID_LBOXSTRING
)))->GetText());
3677 pImp
->UpdateStringSorter();
3678 return pImp
->m_pStringSorter
->compare(aLeft
, aRight
);
3681 void SvTreeListBox::ModelNotification( sal_uInt16 nActionId
, SvTreeListEntry
* pEntry1
,
3682 SvTreeListEntry
* pEntry2
, sal_uLong nPos
)
3684 if( nActionId
== LISTACTION_CLEARING
)
3685 CancelTextEditing();
3687 SvListView::ModelNotification( nActionId
, pEntry1
, pEntry2
, nPos
);
3690 case LISTACTION_INSERTED
:
3692 SvTreeListEntry
* pEntry( dynamic_cast< SvTreeListEntry
* >( pEntry1
) );
3695 SAL_WARN( "svtools.contnr", "SvTreeListBox::ModelNotification: invalid entry!" );
3699 SvLBoxContextBmp
* pBmpItem
= static_cast< SvLBoxContextBmp
* >( pEntry
->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP
) );
3702 const Image
& rBitmap1( pBmpItem
->GetBitmap1() );
3703 const Image
& rBitmap2( pBmpItem
->GetBitmap2() );
3704 short nMaxWidth
= short( std::max( rBitmap1
.GetSizePixel().Width(), rBitmap2
.GetSizePixel().Width() ) );
3705 nMaxWidth
= pImp
->UpdateContextBmpWidthVector( pEntry
, nMaxWidth
);
3706 if( nMaxWidth
> nContextBmpWidthMax
)
3708 nContextBmpWidthMax
= nMaxWidth
;
3711 if (get_width_request() == -1)
3716 case LISTACTION_RESORTING
:
3717 SetUpdateMode( sal_False
);
3720 case LISTACTION_RESORTED
:
3721 // after a selection: show first entry and also keep the selection
3722 MakeVisible( (SvTreeListEntry
*)pModel
->First(), sal_True
);
3723 SetUpdateMode( sal_True
);
3726 case LISTACTION_CLEARED
:
3727 if( IsUpdateMode() )
3733 void SvTreeListBox::EndSelection()
3735 pImp
->EndSelection();
3738 void SvTreeListBox::RepaintScrollBars() const
3740 ((SvTreeListBox
*)this)->pImp
->RepaintScrollBars();
3743 ScrollBar
*SvTreeListBox::GetVScroll()
3745 return &((SvTreeListBox
*)this)->pImp
->aVerSBar
;
3748 ScrollBar
*SvTreeListBox::GetHScroll()
3750 return &((SvTreeListBox
*)this)->pImp
->aHorSBar
;
3753 void SvTreeListBox::EnableAsyncDrag( sal_Bool b
)
3755 pImp
->EnableAsyncDrag( b
);
3758 SvTreeListEntry
* SvTreeListBox::GetFirstEntryInView() const
3761 return GetEntry( aPos
);
3764 SvTreeListEntry
* SvTreeListBox::GetNextEntryInView(SvTreeListEntry
* pEntry
) const
3766 SvTreeListEntry
* pNext
= (SvTreeListEntry
*)NextVisible( pEntry
);
3769 Point
aPos( GetEntryPosition(pNext
) );
3770 const Size
& rSize
= pImp
->GetOutputSize();
3771 if( aPos
.Y() < 0 || aPos
.Y() >= rSize
.Height() )
3777 SvTreeListEntry
* SvTreeListBox::GetLastEntryInView() const
3779 SvTreeListEntry
* pEntry
= GetFirstEntryInView();
3780 SvTreeListEntry
* pNext
= 0;
3783 pNext
= (SvTreeListEntry
*)NextVisible( pEntry
);
3786 Point
aPos( GetEntryPosition(pNext
) );
3787 const Size
& rSize
= pImp
->GetOutputSize();
3788 if( aPos
.Y() < 0 || aPos
.Y() + GetEntryHeight() >= rSize
.Height() )
3799 void SvTreeListBox::ShowFocusRect( const SvTreeListEntry
* pEntry
)
3801 pImp
->ShowFocusRect( pEntry
);
3804 void SvTreeListBox::DataChanged( const DataChangedEvent
& rDCEvt
)
3806 if( (rDCEvt
.GetType()==DATACHANGED_SETTINGS
) && (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
3808 nEntryHeight
= 0; // _together_ with sal_True of 1. par (bFont) of InitSettings() a zero-height
3809 // forces complete recalc of heights!
3810 InitSettings( sal_True
, sal_True
, sal_True
);
3814 Control::DataChanged( rDCEvt
);
3817 void SvTreeListBox::StateChanged( StateChangedType eType
)
3819 if( eType
== STATE_CHANGE_ENABLE
)
3820 Invalidate( INVALIDATE_CHILDREN
);
3822 Control::StateChanged( eType
);
3824 if ( eType
== STATE_CHANGE_STYLE
)
3828 void SvTreeListBox::InitSettings(sal_Bool bFont
,sal_Bool bForeground
,sal_Bool bBackground
)
3830 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
3834 aFont
= rStyleSettings
.GetFieldFont();
3835 aFont
.SetColor( rStyleSettings
.GetWindowTextColor() );
3836 SetPointFont( aFont
);
3837 AdjustEntryHeightAndRecalc( aFont
);
3840 if( bForeground
|| bFont
)
3842 SetTextColor( rStyleSettings
.GetFieldTextColor() );
3847 SetBackground( rStyleSettings
.GetFieldColor() );
3849 // always try to re-create default-SvLBoxButtonData
3850 if( pCheckButtonData
&& pCheckButtonData
->HasDefaultImages() )
3851 pCheckButtonData
->SetDefaultImages( this );
3854 sal_Bool
SvTreeListBox::IsCellFocusEnabled() const
3856 return pImp
->IsCellFocusEnabled();
3859 bool SvTreeListBox::SetCurrentTabPos( sal_uInt16 _nNewPos
)
3861 return pImp
->SetCurrentTabPos( _nNewPos
);
3864 sal_uInt16
SvTreeListBox::GetCurrentTabPos() const
3866 return pImp
->GetCurrentTabPos();
3869 void SvTreeListBox::InitStartEntry()
3871 if( !pImp
->pStartEntry
)
3872 pImp
->pStartEntry
= GetModel()->First();
3875 PopupMenu
* SvTreeListBox::CreateContextMenu( void )
3880 void SvTreeListBox::ExcecuteContextMenuAction( sal_uInt16
)
3882 DBG_WARNING( "SvTreeListBox::ExcecuteContextMenuAction(): now there's happening nothing!" );
3885 void SvTreeListBox::EnableContextMenuHandling( void )
3887 DBG_ASSERT( pImp
, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );
3889 pImp
->bContextMenuHandling
= sal_True
;
3892 void SvTreeListBox::EnableContextMenuHandling( sal_Bool b
)
3894 DBG_ASSERT( pImp
, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );
3896 pImp
->bContextMenuHandling
= b
;
3899 sal_Bool
SvTreeListBox::IsContextMenuHandlingEnabled( void ) const
3901 DBG_ASSERT( pImp
, "-SvTreeListBox::IsContextMenuHandlingEnabled(): No implementation!" );
3903 return pImp
->bContextMenuHandling
;
3906 void SvTreeListBox::EnableList( bool _bEnable
)
3908 // call base class method
3909 Window::Enable( _bEnable
!= false );
3910 // then paint immediately
3911 Paint( Rectangle( Point(), GetSizePixel() ) );
3914 ::com::sun::star::uno::Reference
< XAccessible
> SvTreeListBox::CreateAccessible()
3916 Window
* pParent
= GetAccessibleParentWindow();
3917 DBG_ASSERT( pParent
, "SvTreeListBox::CreateAccessible - accessible parent not found" );
3919 ::com::sun::star::uno::Reference
< XAccessible
> xAccessible
;
3922 ::com::sun::star::uno::Reference
< XAccessible
> xAccParent
= pParent
->GetAccessible();
3923 if ( xAccParent
.is() )
3925 // need to be done here to get the vclxwindow later on in the accessbile
3926 ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindowPeer
> xTemp(GetComponentInterface());
3927 xAccessible
= pImp
->m_aFactoryAccess
.getFactory().createAccessibleTreeListBox( *this, xAccParent
);
3933 void SvTreeListBox::FillAccessibleEntryStateSet( SvTreeListEntry
* pEntry
, ::utl::AccessibleStateSetHelper
& rStateSet
) const
3935 DBG_ASSERT( pEntry
, "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry" );
3937 if ( pEntry
->HasChildrenOnDemand() || pEntry
->HasChildren() )
3939 rStateSet
.AddState( AccessibleStateType::EXPANDABLE
);
3940 if ( IsExpanded( pEntry
) )
3941 rStateSet
.AddState( (sal_Int16
)AccessibleStateType::EXPANDED
);
3944 if ( GetCheckButtonState( pEntry
) == SV_BUTTON_CHECKED
)
3945 rStateSet
.AddState( AccessibleStateType::CHECKED
);
3946 if ( IsEntryVisible( pEntry
) )
3947 rStateSet
.AddState( AccessibleStateType::VISIBLE
);
3948 if ( IsSelected( pEntry
) )
3949 rStateSet
.AddState( AccessibleStateType::SELECTED
);
3952 Rectangle
SvTreeListBox::GetBoundingRect( SvTreeListEntry
* pEntry
)
3954 Point aPos
= GetEntryPosition( pEntry
);
3955 Rectangle aRect
= GetFocusRect( pEntry
, aPos
.Y() );
3959 void SvTreeListBox::EnableCellFocus()
3961 pImp
->EnableCellFocus();
3964 void SvTreeListBox::CallImplEventListeners(sal_uLong nEvent
, void* pData
)
3966 CallEventListeners(nEvent
, pData
);
3969 void SvTreeListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper
& /*rStateSet*/ ) const
3973 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */