1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svlbox.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
36 - Anker loeschen in SelectionEngine bei manuellem Selektieren
37 - SelectAll( FALSE ), nur die deselektierten Entries repainten
41 #include <svtools/svlbox.hxx>
42 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
43 #include <vcl/svapp.hxx>
44 #include <vcl/accel.hxx>
45 #include <vcl/i18nhelp.hxx>
46 #include <sot/formats.hxx>
47 #include <unotools/accessiblestatesethelper.hxx>
48 #include <rtl/instance.hxx>
50 #define _SVSTDARR_ULONGSSORT
51 #include <svtools/svstdarr.hxx>
54 #include <svtools/svmedit.hxx>
56 #include <svtools/svlbitm.hxx>
58 using namespace ::com::sun::star::accessibility
;
61 static SvLBox
* pDDSource
= NULL
;
62 static SvLBox
* pDDTarget
= NULL
;
64 DBG_NAME(SvInplaceEdit
)
65 DBG_NAME(SvInplaceEdit2
)
67 #define SVLBOX_ACC_RETURN 1
68 #define SVLBOX_ACC_ESCAPE 2
70 SvInplaceEdit::SvInplaceEdit
76 const Link
& rNotifyEditEnd
,
77 const Selection
& rSelection
80 Edit( pParent
, WB_LEFT
),
82 aCallBackHdl ( rNotifyEditEnd
),
84 bAlreadyInCallBack ( FALSE
)
87 DBG_CTOR(SvInplaceEdit
,0);
89 Font
aFont( pParent
->GetFont() );
90 aFont
.SetTransparent( FALSE
);
91 Color
aColor( pParent
->GetBackground().GetColor() );
92 aFont
.SetFillColor(aColor
);
94 SetBackground( pParent
->GetBackground() );
96 SetSizePixel( rSize
);
98 SetSelection( rSelection
);
101 aAccReturn
.InsertItem( SVLBOX_ACC_RETURN
, KeyCode(KEY_RETURN
) );
102 aAccEscape
.InsertItem( SVLBOX_ACC_ESCAPE
, KeyCode(KEY_ESCAPE
) );
104 aAccReturn
.SetActivateHdl( LINK( this, SvInplaceEdit
, ReturnHdl_Impl
) );
105 aAccEscape
.SetActivateHdl( LINK( this, SvInplaceEdit
, EscapeHdl_Impl
) );
106 GetpApp()->InsertAccel( &aAccReturn
);
107 GetpApp()->InsertAccel( &aAccEscape
);
113 SvInplaceEdit::~SvInplaceEdit()
115 DBG_DTOR(SvInplaceEdit
,0);
116 if( !bAlreadyInCallBack
)
118 GetpApp()->RemoveAccel( &aAccReturn
);
119 GetpApp()->RemoveAccel( &aAccEscape
);
123 IMPL_LINK_INLINE_START( SvInplaceEdit
, ReturnHdl_Impl
, Accelerator
*, EMPTYARG
)
125 DBG_CHKTHIS(SvInplaceEdit
,0);
127 CallCallBackHdl_Impl();
130 IMPL_LINK_INLINE_END( SvInplaceEdit
, ReturnHdl_Impl
, Accelerator
*, EMPTYARG
)
132 IMPL_LINK_INLINE_START( SvInplaceEdit
, EscapeHdl_Impl
, Accelerator
*, EMPTYARG
)
134 DBG_CHKTHIS(SvInplaceEdit
,0);
136 CallCallBackHdl_Impl();
139 IMPL_LINK_INLINE_END( SvInplaceEdit
, EscapeHdl_Impl
, Accelerator
*, EMPTYARG
)
141 void SvInplaceEdit::KeyInput( const KeyEvent
& rKEvt
)
143 DBG_CHKTHIS(SvInplaceEdit
,0);
144 USHORT nCode
= rKEvt
.GetKeyCode().GetCode();
149 CallCallBackHdl_Impl();
154 CallCallBackHdl_Impl();
158 Edit::KeyInput( rKEvt
);
162 void SvInplaceEdit::StopEditing( BOOL bCancel
)
164 DBG_CHKTHIS(SvInplaceEdit
,0);
165 if ( !bAlreadyInCallBack
)
168 CallCallBackHdl_Impl();
172 void SvInplaceEdit::LoseFocus()
174 DBG_CHKTHIS(SvInplaceEdit
,0);
175 if ( !bAlreadyInCallBack
)
178 aTimer
.SetTimeout(10);
179 aTimer
.SetTimeoutHdl(LINK(this,SvInplaceEdit
,Timeout_Impl
));
184 IMPL_LINK_INLINE_START( SvInplaceEdit
, Timeout_Impl
, Timer
*, EMPTYARG
)
186 DBG_CHKTHIS(SvInplaceEdit
,0);
187 CallCallBackHdl_Impl();
190 IMPL_LINK_INLINE_END( SvInplaceEdit
, Timeout_Impl
, Timer
*, EMPTYARG
)
192 void SvInplaceEdit::CallCallBackHdl_Impl()
194 DBG_CHKTHIS(SvInplaceEdit
,0);
196 if ( !bAlreadyInCallBack
)
198 bAlreadyInCallBack
= TRUE
;
199 GetpApp()->RemoveAccel( &aAccReturn
);
200 GetpApp()->RemoveAccel( &aAccEscape
);
202 aCallBackHdl
.Call( this );
203 // bAlreadyInCallBack = FALSE;
208 // ***************************************************************
210 class MyEdit_Impl
: public Edit
212 SvInplaceEdit2
* pOwner
;
214 MyEdit_Impl( Window
* pParent
, SvInplaceEdit2
* pOwner
);
215 virtual void KeyInput( const KeyEvent
& rKEvt
);
216 virtual void LoseFocus();
219 class MyMultiEdit_Impl
: public MultiLineEdit
221 SvInplaceEdit2
* pOwner
;
223 MyMultiEdit_Impl( Window
* pParent
, SvInplaceEdit2
* pOwner
);
224 virtual void KeyInput( const KeyEvent
& rKEvt
);
225 virtual void LoseFocus();
228 MyEdit_Impl::MyEdit_Impl( Window
* pParent
, SvInplaceEdit2
* _pOwner
) :
230 Edit( pParent
, WB_LEFT
),
237 void MyEdit_Impl::KeyInput( const KeyEvent
& rKEvt
)
239 if( !pOwner
->KeyInput( rKEvt
))
240 Edit::KeyInput( rKEvt
);
243 void MyEdit_Impl::LoseFocus()
248 MyMultiEdit_Impl::MyMultiEdit_Impl( Window
* pParent
, SvInplaceEdit2
* _pOwner
)
249 : MultiLineEdit( pParent
,
255 void MyMultiEdit_Impl::KeyInput( const KeyEvent
& rKEvt
)
257 if( !pOwner
->KeyInput( rKEvt
))
258 MultiLineEdit::KeyInput( rKEvt
);
261 void MyMultiEdit_Impl::LoseFocus()
267 SvInplaceEdit2::SvInplaceEdit2
269 Window
* pParent
, const Point
& rPos
,
272 const Link
& rNotifyEditEnd
,
273 const Selection
& rSelection
,
277 aCallBackHdl ( rNotifyEditEnd
),
279 bAlreadyInCallBack ( FALSE
),
280 bMultiLine ( bMulti
)
283 DBG_CTOR(SvInplaceEdit2
,0);
286 pEdit
= new MyMultiEdit_Impl( pParent
, this );
288 pEdit
= new MyEdit_Impl( pParent
, this );
290 Font
aFont( pParent
->GetFont() );
291 aFont
.SetTransparent( FALSE
);
292 Color
aColor( pParent
->GetBackground().GetColor() );
293 aFont
.SetFillColor(aColor
);
294 pEdit
->SetFont( aFont
);
295 pEdit
->SetBackground( pParent
->GetBackground() );
296 pEdit
->SetPosPixel( rPos
);
297 pEdit
->SetSizePixel( rSize
);
298 pEdit
->SetText( rData
);
299 pEdit
->SetSelection( rSelection
);
302 aAccReturn
.InsertItem( SVLBOX_ACC_RETURN
, KeyCode(KEY_RETURN
) );
303 aAccEscape
.InsertItem( SVLBOX_ACC_ESCAPE
, KeyCode(KEY_ESCAPE
) );
305 aAccReturn
.SetActivateHdl( LINK( this, SvInplaceEdit2
, ReturnHdl_Impl
) );
306 aAccEscape
.SetActivateHdl( LINK( this, SvInplaceEdit2
, EscapeHdl_Impl
) );
307 GetpApp()->InsertAccel( &aAccReturn
);
308 GetpApp()->InsertAccel( &aAccEscape
);
314 SvInplaceEdit2::~SvInplaceEdit2()
316 DBG_DTOR(SvInplaceEdit2
,0);
317 if( !bAlreadyInCallBack
)
319 GetpApp()->RemoveAccel( &aAccReturn
);
320 GetpApp()->RemoveAccel( &aAccEscape
);
325 String
SvInplaceEdit2::GetSavedValue() const
327 return pEdit
->GetSavedValue();
330 void SvInplaceEdit2::Hide()
336 IMPL_LINK_INLINE_START( SvInplaceEdit2
, ReturnHdl_Impl
, Accelerator
*, EMPTYARG
)
338 DBG_CHKTHIS(SvInplaceEdit2
,0);
340 CallCallBackHdl_Impl();
343 IMPL_LINK_INLINE_END( SvInplaceEdit2
, ReturnHdl_Impl
, Accelerator
*, EMPTYARG
)
345 IMPL_LINK_INLINE_START( SvInplaceEdit2
, EscapeHdl_Impl
, Accelerator
*, EMPTYARG
)
347 DBG_CHKTHIS(SvInplaceEdit2
,0);
349 CallCallBackHdl_Impl();
352 IMPL_LINK_INLINE_END( SvInplaceEdit2
, EscapeHdl_Impl
, Accelerator
*, EMPTYARG
)
355 BOOL
SvInplaceEdit2::KeyInput( const KeyEvent
& rKEvt
)
357 DBG_CHKTHIS(SvInplaceEdit2
,0);
358 KeyCode aCode
= rKEvt
.GetKeyCode();
359 USHORT nCode
= aCode
.GetCode();
365 CallCallBackHdl_Impl();
370 CallCallBackHdl_Impl();
376 void SvInplaceEdit2::StopEditing( BOOL bCancel
)
378 DBG_CHKTHIS(SvInplaceEdit2
,0);
379 if ( !bAlreadyInCallBack
)
382 CallCallBackHdl_Impl();
386 void SvInplaceEdit2::LoseFocus()
388 DBG_CHKTHIS(SvInplaceEdit2
,0);
389 if ( !bAlreadyInCallBack
390 && ((!Application::GetFocusWindow()) || !pEdit
->IsChild( Application::GetFocusWindow()) )
394 aTimer
.SetTimeout(10);
395 aTimer
.SetTimeoutHdl(LINK(this,SvInplaceEdit2
,Timeout_Impl
));
400 IMPL_LINK_INLINE_START( SvInplaceEdit2
, Timeout_Impl
, Timer
*, EMPTYARG
)
402 DBG_CHKTHIS(SvInplaceEdit2
,0);
403 CallCallBackHdl_Impl();
406 IMPL_LINK_INLINE_END( SvInplaceEdit2
, Timeout_Impl
, Timer
*, EMPTYARG
)
408 void SvInplaceEdit2::CallCallBackHdl_Impl()
410 DBG_CHKTHIS(SvInplaceEdit2
,0);
412 if ( !bAlreadyInCallBack
)
414 bAlreadyInCallBack
= TRUE
;
415 GetpApp()->RemoveAccel( &aAccReturn
);
416 GetpApp()->RemoveAccel( &aAccEscape
);
418 aCallBackHdl
.Call( this );
422 String
SvInplaceEdit2::GetText() const
424 return pEdit
->GetText();
427 // ***************************************************************
429 // ***************************************************************
433 SvLBoxTab::SvLBoxTab()
435 DBG_CTOR(SvLBoxTab
,0);
441 SvLBoxTab::SvLBoxTab( long nPosition
, USHORT nTabFlags
)
443 DBG_CTOR(SvLBoxTab
,0);
449 SvLBoxTab::SvLBoxTab( const SvLBoxTab
& rTab
)
451 DBG_CTOR(SvLBoxTab
,0);
453 pUserData
= rTab
.pUserData
;
454 nFlags
= rTab
.nFlags
;
457 SvLBoxTab::~SvLBoxTab()
459 DBG_DTOR(SvLBoxTab
,0);
463 long SvLBoxTab::CalcOffset( long nItemWidth
, long nTabWidth
)
465 DBG_CHKTHIS(SvLBoxTab
,0);
467 if ( nFlags
& SV_LBOXTAB_ADJUST_RIGHT
)
469 nOffset
= nTabWidth
- nItemWidth
;
473 else if ( nFlags
& SV_LBOXTAB_ADJUST_CENTER
)
475 if( nFlags
& SV_LBOXTAB_FORCE
)
477 //richtige Implementierung der Zentrierung
478 nOffset
= ( nTabWidth
- nItemWidth
) / 2;
484 // historisch gewachsene falsche Berechnung des Tabs, auf die sich
485 // Abo-Tabbox, Extras/Optionen/Anpassen etc. verlassen
487 nOffset
= -( nItemWidth
/ 2 );
494 long SvLBoxTab::CalcOffset( const String& rStr, const OutputDevice& rOutDev )
496 DBG_CHKTHIS(SvLBoxTab,0);
498 if ( nFlags & SV_LBOXTAB_ADJUST_NUMERIC )
500 USHORT nPos = rStr.Search( '.' );
501 if ( nPos == STRING_NOTFOUND )
502 nPos = rStr.Search( ',' );
503 if ( nPos == STRING_NOTFOUND )
506 nWidth = rOutDev.GetTextSize( rStr, 0, nPos ).Width();
511 nWidth = rOutDev.GetTextSize( rStr ).Width();
512 nWidth = CalcOffset( nWidth );
518 // ***************************************************************
520 // ***************************************************************
522 DBG_NAME(SvLBoxItem
);
524 SvLBoxItem::SvLBoxItem( SvLBoxEntry
*, USHORT
)
526 DBG_CTOR(SvLBoxItem
,0);
529 SvLBoxItem::SvLBoxItem()
531 DBG_CTOR(SvLBoxItem
,0);
534 SvLBoxItem::~SvLBoxItem()
536 DBG_DTOR(SvLBoxItem
,0);
539 const Size
& SvLBoxItem::GetSize( SvLBox
* pView
,SvLBoxEntry
* pEntry
)
541 DBG_CHKTHIS(SvLBoxItem
,0);
542 SvViewDataItem
* pViewData
= pView
->GetViewDataItem( pEntry
, this );
543 return pViewData
->aSize
;
546 const Size
& SvLBoxItem::GetSize( SvLBoxEntry
* pEntry
, SvViewDataEntry
* pViewData
)
548 DBG_CHKTHIS(SvLBoxItem
,0);
549 USHORT nItemPos
= pEntry
->GetPos( this );
550 SvViewDataItem
* pItemData
= pViewData
->pItemData
+nItemPos
;
551 return pItemData
->aSize
;
554 DBG_NAME(SvViewDataItem
);
556 SvViewDataItem::SvViewDataItem()
558 DBG_CTOR(SvViewDataItem
,0);
561 SvViewDataItem::~SvViewDataItem()
563 DBG_DTOR(SvViewDataItem
,0);
568 // ***************************************************************
570 // ***************************************************************
572 DBG_NAME(SvLBoxEntry
);
574 SvLBoxEntry::SvLBoxEntry() : aItems()
576 DBG_CTOR(SvLBoxEntry
,0);
581 SvLBoxEntry::~SvLBoxEntry()
583 DBG_DTOR(SvLBoxEntry
,0);
587 void SvLBoxEntry::DeleteItems_Impl()
589 DBG_CHKTHIS(SvLBoxEntry
,0);
590 USHORT nCount
= aItems
.Count();
594 SvLBoxItem
* pItem
= (SvLBoxItem
*)aItems
.GetObject( nCount
);
597 aItems
.Remove(0, aItems
.Count() );
601 void SvLBoxEntry::AddItem( SvLBoxItem
* pItem
)
603 DBG_CHKTHIS(SvLBoxEntry
,0);
604 aItems
.Insert( pItem
, aItems
.Count() );
607 void SvLBoxEntry::Clone( SvListEntry
* pSource
)
609 DBG_CHKTHIS(SvLBoxEntry
,0);
610 SvListEntry::Clone( pSource
);
611 SvLBoxItem
* pNewItem
;
613 USHORT nCount
= ((SvLBoxEntry
*)pSource
)->ItemCount();
615 while( nCurPos
< nCount
)
617 SvLBoxItem
* pItem
= ((SvLBoxEntry
*)pSource
)->GetItem( nCurPos
);
618 pNewItem
= pItem
->Create();
619 pNewItem
->Clone( pItem
);
623 pUserData
= ((SvLBoxEntry
*)pSource
)->GetUserData();
624 nEntryFlags
= ((SvLBoxEntry
*)pSource
)->nEntryFlags
;
627 void SvLBoxEntry::EnableChildsOnDemand( BOOL bEnable
)
629 DBG_CHKTHIS(SvLBoxEntry
,0);
631 nEntryFlags
|= SV_ENTRYFLAG_CHILDS_ON_DEMAND
;
633 nEntryFlags
&= (~SV_ENTRYFLAG_CHILDS_ON_DEMAND
);
636 void SvLBoxEntry::ReplaceItem( SvLBoxItem
* pNewItem
, USHORT nPos
)
638 DBG_CHKTHIS(SvLBoxEntry
,0);
639 DBG_ASSERT(pNewItem
,"ReplaceItem:No Item");
640 SvLBoxItem
* pOld
= GetItem( nPos
);
643 aItems
.Remove( nPos
);
644 aItems
.Insert( pNewItem
, nPos
);
649 SvLBoxItem
* SvLBoxEntry::GetFirstItem( USHORT nId
)
651 USHORT nCount
= aItems
.Count();
654 while( nCur
< nCount
)
656 pItem
= GetItem( nCur
);
657 if( pItem
->IsA() == nId
)
664 // ***************************************************************
665 // class SvLBoxViewData
666 // ***************************************************************
668 DBG_NAME(SvViewDataEntry
);
670 SvViewDataEntry::SvViewDataEntry()
673 DBG_CTOR(SvViewDataEntry
,0);
677 SvViewDataEntry::~SvViewDataEntry()
679 DBG_DTOR(SvViewDataEntry
,0);
683 // ***************************************************************
684 // struct SvLBox_Impl
685 // ***************************************************************
686 SvLBox_Impl::SvLBox_Impl( SvLBox
& _rBox
)
687 :m_bIsEmptyTextAllowed( true )
688 ,m_bEntryMnemonicsEnabled( false )
690 ,m_aMnemonicEngine( _rBox
)
694 // ***************************************************************
696 // ***************************************************************
700 SvLBox::SvLBox( Window
* pParent
, WinBits nWinStyle
) :
701 Control( pParent
, nWinStyle
| WB_CLIPCHILDREN
),
702 DropTargetHelper( this ), DragSourceHelper( this ), eSelMode( NO_SELECTION
)
705 nWindowStyle
= nWinStyle
;
706 nDragOptions
= DND_ACTION_COPYMOVE
| DND_ACTION_LINK
;
710 pLBoxImpl
= new SvLBox_Impl( *this );
711 SvLBoxTreeList
* pTempModel
= new SvLBoxTreeList
;
712 pTempModel
->SetRefCount( 0 );
713 SetModel( pTempModel
);
714 pModel
->SetCloneLink( LINK(this, SvLBox
, CloneHdl_Impl
));
715 pModel
->InsertView( this );
718 SetSelectionMode( SINGLE_SELECTION
); // pruefen ob TreeListBox gecallt wird
719 SetDragDropMode( SV_DRAGDROP_NONE
);
720 SetType(WINDOW_TREELISTBOX
);
723 SvLBox::SvLBox( Window
* pParent
, const ResId
& rResId
) :
724 Control( pParent
, rResId
),
725 DropTargetHelper( this ), DragSourceHelper( this ), eSelMode( NO_SELECTION
)
731 pLBoxImpl
= new SvLBox_Impl( *this );
732 nDragOptions
= DND_ACTION_COPYMOVE
| DND_ACTION_LINK
;
734 SvLBoxTreeList
* pTempModel
= new SvLBoxTreeList
;
735 pTempModel
->SetRefCount( 0 );
736 SetModel( pTempModel
);
737 pModel
->InsertView( this );
740 pModel
->SetCloneLink( LINK(this, SvLBox
, CloneHdl_Impl
));
741 SetType(WINDOW_TREELISTBOX
);
744 __EXPORT
SvLBox::~SvLBox()
749 pModel
->RemoveView( this );
750 if ( pModel
->GetRefCount() == 0 )
757 SvLBox::RemoveBoxFromDDList_Impl( *this );
759 if( this == pDDSource
)
761 if( this == pDDTarget
)
766 void SvLBox::SetModel( SvLBoxTreeList
* pNewModel
)
768 DBG_CHKTHIS(SvLBox
,0);
769 // erledigt das ganz CleanUp
770 SvListView::SetModel( pNewModel
);
771 pModel
->SetCloneLink( LINK(this, SvLBox
, CloneHdl_Impl
));
772 SvLBoxEntry
* pEntry
= First();
775 ModelHasInserted( pEntry
);
776 pEntry
= Next( pEntry
);
780 void SvLBox::DisconnectFromModel()
782 DBG_CHKTHIS(SvLBox
,0);
783 SvLBoxTreeList
* pNewModel
= new SvLBoxTreeList
;
784 pNewModel
->SetRefCount( 0 ); // else this will never be deleted
785 SvListView::SetModel( pNewModel
);
790 DBG_CHKTHIS(SvLBox
,0);
791 pModel
->Clear(); // Model ruft SvLBox::ModelHasCleared() auf
794 void SvLBox::EnableEntryMnemonics( bool _bEnable
)
796 if ( _bEnable
== IsEntryMnemonicsEnabled() )
799 pLBoxImpl
->m_bEntryMnemonicsEnabled
= _bEnable
;
803 bool SvLBox::IsEntryMnemonicsEnabled() const
805 return pLBoxImpl
->m_bEntryMnemonicsEnabled
;
810 DBG_CHKTHIS(SvLBox
,0);
811 return SVLISTBOX_ID_LBOX
;
814 IMPL_LINK_INLINE_START( SvLBox
, CloneHdl_Impl
, SvListEntry
*, pEntry
)
816 DBG_CHKTHIS(SvLBox
,0);
817 return (long)(CloneEntry((SvLBoxEntry
*)pEntry
));
819 IMPL_LINK_INLINE_END( SvLBox
, CloneHdl_Impl
, SvListEntry
*, pEntry
)
821 ULONG
SvLBox::Insert( SvLBoxEntry
* pEntry
, SvLBoxEntry
* pParent
, ULONG nPos
)
823 DBG_CHKTHIS(SvLBox
,0);
824 ULONG nInsPos
= pModel
->Insert( pEntry
, pParent
, nPos
);
828 ULONG
SvLBox::Insert( SvLBoxEntry
* pEntry
,ULONG nRootPos
)
830 DBG_CHKTHIS(SvLBox
,0);
831 ULONG nInsPos
= pModel
->Insert( pEntry
, nRootPos
);
835 long SvLBox::ExpandingHdl()
837 DBG_CHKTHIS(SvLBox
,0);
838 return aExpandingHdl
.IsSet() ? aExpandingHdl
.Call( this ) : 1;
841 void SvLBox::ExpandedHdl()
843 DBG_CHKTHIS(SvLBox
,0);
844 aExpandedHdl
.Call( this );
847 void SvLBox::SelectHdl()
849 DBG_CHKTHIS(SvLBox
,0);
850 aSelectHdl
.Call( this );
853 void SvLBox::DeselectHdl()
855 DBG_CHKTHIS(SvLBox
,0);
856 aDeselectHdl
.Call( this );
859 BOOL
SvLBox::DoubleClickHdl()
861 DBG_CHKTHIS(SvLBox
,0);
862 aDoubleClickHdl
.Call( this );
867 BOOL
SvLBox::CheckDragAndDropMode( SvLBox
* pSource
, sal_Int8 nAction
)
869 DBG_CHKTHIS(SvLBox
,0);
870 if ( pSource
== this )
872 if ( !(nDragDropMode
& (SV_DRAGDROP_CTRL_MOVE
| SV_DRAGDROP_CTRL_COPY
) ) )
873 return FALSE
; // D&D innerhalb der Liste gesperrt
874 if( DND_ACTION_MOVE
== nAction
)
876 if ( !(nDragDropMode
& SV_DRAGDROP_CTRL_MOVE
) )
877 return FALSE
; // kein lokales Move
881 if ( !(nDragDropMode
& SV_DRAGDROP_CTRL_COPY
))
882 return FALSE
; // kein lokales Copy
887 if ( !(nDragDropMode
& SV_DRAGDROP_APP_DROP
) )
888 return FALSE
; // kein Drop
889 if ( DND_ACTION_MOVE
== nAction
)
891 if ( !(nDragDropMode
& SV_DRAGDROP_APP_MOVE
) )
892 return FALSE
; // kein globales Move
896 if ( !(nDragDropMode
& SV_DRAGDROP_APP_COPY
))
897 return FALSE
; // kein globales Copy
906 void SvLBox::NotifyRemoving( SvLBoxEntry
* )
908 DBG_CHKTHIS(SvLBox
,0);
917 1. Target hat keine Childs
918 - Entry wird Sibling des Targets. Entry steht hinter dem
919 Target (->Fenster: Unter dem Target)
920 2. Target ist ein aufgeklappter Parent
921 - Entry wird an den Anfang der Target-Childlist gehaengt
922 3. Target ist ein zugeklappter Parent
923 - Entry wird an das Ende der Target-Childlist gehaengt
926 BOOL
SvLBox::NotifyMoving(
927 SvLBoxEntry
* pTarget
, // D&D-Drop-Position in this->GetModel()
928 SvLBoxEntry
* pEntry
, // Zu verschiebender Entry aus
929 // GetSourceListBox()->GetModel()
930 SvLBoxEntry
*& rpNewParent
, // Neuer Target-Parent
931 ULONG
& rNewChildPos
) // Position in Childlist des Target-Parents
933 BOOL
SvLBox::NotifyMoving(
934 SvLBoxEntry
* pTarget
, // D&D-Drop-Position in this->GetModel()
935 SvLBoxEntry
*, // Zu verschiebender Entry aus
936 // GetSourceListBox()->GetModel()
937 SvLBoxEntry
*& rpNewParent
, // Neuer Target-Parent
938 ULONG
& rNewChildPos
) // Position in Childlist des Target-Parents
941 DBG_CHKTHIS(SvLBox
,0);
942 DBG_ASSERT(pEntry
,"NotifyMoving:SoureEntry?");
949 if ( !pTarget
->HasChilds() && !pTarget
->HasChildsOnDemand() )
952 rpNewParent
= GetParent( pTarget
);
953 rNewChildPos
= pModel
->GetRelPos( pTarget
) + 1;
954 rNewChildPos
+= nCurEntrySelPos
;
960 rpNewParent
= pTarget
;
961 if( IsExpanded(pTarget
))
964 rNewChildPos
= LIST_APPEND
;
969 BOOL
SvLBox::NotifyCopying(
970 SvLBoxEntry
* pTarget
, // D&D-Drop-Position in this->GetModel()
971 SvLBoxEntry
* pEntry
, // Zu kopierender Entry aus
972 // GetSourceListBox()->GetModel()
973 SvLBoxEntry
*& rpNewParent
, // Neuer Target-Parent
974 ULONG
& rNewChildPos
) // Position in Childlist des Target-Parents
976 DBG_CHKTHIS(SvLBox
,0);
977 return NotifyMoving(pTarget
,pEntry
,rpNewParent
,rNewChildPos
);
979 DBG_ASSERT(pEntry,"NotifyCopying:SourceEntry?");
986 if ( !pTarget->HasChilds() && !pTarget->HasChildsOnDemand() )
989 rpNewParent = GetParent( pTarget );
990 rNewChildPos = GetRelPos( pTarget ) + 1;
995 rpNewParent = pTarget;
996 if( IsExpanded(pTarget))
999 rNewChildPos = LIST_APPEND;
1005 SvLBoxEntry
* SvLBox::CloneEntry( SvLBoxEntry
* pSource
)
1007 DBG_CHKTHIS(SvLBox
,0);
1008 SvLBoxEntry
* pEntry
= (SvLBoxEntry
*)CreateEntry(); // new SvLBoxEntry;
1009 pEntry
->Clone( (SvListEntry
*)pSource
);
1014 // Rueckgabe: Alle Entries wurden kopiert
1015 BOOL
SvLBox::CopySelection( SvLBox
* pSource
, SvLBoxEntry
* pTarget
)
1017 DBG_CHKTHIS(SvLBox
,0);
1018 nCurEntrySelPos
= 0; // Selektionszaehler fuer NotifyMoving/Copying
1019 BOOL bSuccess
= TRUE
;
1020 SvTreeEntryList aList
;
1021 BOOL bClone
= (BOOL
)( (ULONG
)(pSource
->GetModel()) != (ULONG
)GetModel() );
1022 Link
aCloneLink( pModel
->GetCloneLink() );
1023 pModel
->SetCloneLink( LINK(this, SvLBox
, CloneHdl_Impl
));
1025 // Selektion zwischenspeichern, um bei D&D-Austausch
1026 // innerhalb der gleichen Listbox das Iterieren ueber
1027 // die Selektion zu vereinfachen
1028 SvLBoxEntry
* pSourceEntry
= pSource
->FirstSelected();
1029 while ( pSourceEntry
)
1031 // Childs werden automatisch mitkopiert
1032 pSource
->SelectChilds( pSourceEntry
, FALSE
);
1033 aList
.Insert( pSourceEntry
, LIST_APPEND
);
1034 pSourceEntry
= pSource
->NextSelected( pSourceEntry
);
1037 pSourceEntry
= (SvLBoxEntry
*)aList
.First();
1038 while ( pSourceEntry
)
1040 SvLBoxEntry
* pNewParent
= 0;
1041 ULONG nInsertionPos
= LIST_APPEND
;
1042 BOOL bOk
=NotifyCopying(pTarget
,pSourceEntry
,pNewParent
,nInsertionPos
);
1047 ULONG nCloneCount
= 0;
1048 pSourceEntry
= (SvLBoxEntry
*)
1049 pModel
->Clone( (SvListEntry
*)pSourceEntry
, nCloneCount
);
1050 pModel
->InsertTree( (SvListEntry
*)pSourceEntry
,
1051 (SvListEntry
*)pNewParent
, nInsertionPos
);
1055 ULONG nListPos
= pModel
->Copy( (SvListEntry
*)pSourceEntry
,
1056 (SvListEntry
*)pNewParent
, nInsertionPos
);
1057 pSourceEntry
= GetEntry( pNewParent
, nListPos
);
1063 if( bOk
== (BOOL
)2 ) // !!!HACK verschobenen Entry sichtbar machen?
1064 MakeVisible( pSourceEntry
);
1066 pSourceEntry
= (SvLBoxEntry
*)aList
.Next();
1068 pModel
->SetCloneLink( aCloneLink
);
1072 // Rueckgabe: Alle Entries wurden verschoben
1073 BOOL
SvLBox::MoveSelection( SvLBox
* pSource
, SvLBoxEntry
* pTarget
)
1075 return MoveSelectionCopyFallbackPossible( pSource
, pTarget
, sal_False
);
1078 BOOL
SvLBox::MoveSelectionCopyFallbackPossible( SvLBox
* pSource
, SvLBoxEntry
* pTarget
, sal_Bool bAllowCopyFallback
)
1080 DBG_CHKTHIS(SvLBox
,0);
1081 nCurEntrySelPos
= 0; // Selektionszaehler fuer NotifyMoving/Copying
1082 BOOL bSuccess
= TRUE
;
1083 SvTreeEntryList aList
;
1084 BOOL bClone
= (BOOL
)( (ULONG
)(pSource
->GetModel()) != (ULONG
)GetModel() );
1085 Link
aCloneLink( pModel
->GetCloneLink() );
1087 pModel
->SetCloneLink( LINK(this, SvLBox
, CloneHdl_Impl
));
1089 SvLBoxEntry
* pSourceEntry
= pSource
->FirstSelected();
1090 while ( pSourceEntry
)
1092 // Childs werden automatisch mitbewegt
1093 pSource
->SelectChilds( pSourceEntry
, FALSE
);
1094 aList
.Insert( pSourceEntry
, LIST_APPEND
);
1095 pSourceEntry
= pSource
->NextSelected( pSourceEntry
);
1098 pSourceEntry
= (SvLBoxEntry
*)aList
.First();
1099 while ( pSourceEntry
)
1101 SvLBoxEntry
* pNewParent
= 0;
1102 ULONG nInsertionPos
= LIST_APPEND
;
1103 sal_Bool bOk
= NotifyMoving(pTarget
,pSourceEntry
,pNewParent
,nInsertionPos
);
1104 sal_Bool bCopyOk
= bOk
;
1105 if ( !bOk
&& bAllowCopyFallback
)
1107 nInsertionPos
= LIST_APPEND
;
1108 bCopyOk
= NotifyCopying(pTarget
,pSourceEntry
,pNewParent
,nInsertionPos
);
1111 if ( bOk
|| bCopyOk
)
1115 ULONG nCloneCount
= 0;
1116 pSourceEntry
= (SvLBoxEntry
*)
1117 pModel
->Clone( (SvListEntry
*)pSourceEntry
, nCloneCount
);
1118 pModel
->InsertTree( (SvListEntry
*)pSourceEntry
,
1119 (SvListEntry
*)pNewParent
, nInsertionPos
);
1124 pModel
->Move( (SvListEntry
*)pSourceEntry
,
1125 (SvListEntry
*)pNewParent
, nInsertionPos
);
1127 pModel
->Copy( (SvListEntry
*)pSourceEntry
,
1128 (SvListEntry
*)pNewParent
, nInsertionPos
);
1134 if( bOk
== (BOOL
)2 ) // !!!HACK verschobenen Entry sichtbar machen?
1135 MakeVisible( pSourceEntry
);
1137 pSourceEntry
= (SvLBoxEntry
*)aList
.Next();
1139 pModel
->SetCloneLink( aCloneLink
);
1143 void SvLBox::RemoveSelection()
1145 DBG_CHKTHIS(SvLBox
,0);
1146 SvTreeEntryList aList
;
1147 // Selektion zwischenspeichern, da die Impl bei
1148 // dem ersten Remove alles deselektiert!
1149 SvLBoxEntry
* pEntry
= FirstSelected();
1152 aList
.Insert( pEntry
);
1153 if ( pEntry
->HasChilds() )
1154 // Remove loescht Childs automatisch
1155 SelectChilds( pEntry
, FALSE
);
1156 pEntry
= NextSelected( pEntry
);
1158 pEntry
= (SvLBoxEntry
*)aList
.First();
1161 pModel
->Remove( pEntry
);
1162 pEntry
= (SvLBoxEntry
*)aList
.Next();
1166 SvLBox
* SvLBox::GetSourceView() const
1171 SvLBox
* SvLBox::GetTargetView() const
1176 void SvLBox::RequestingChilds( SvLBoxEntry
* )
1178 DBG_CHKTHIS(SvLBox
,0);
1179 DBG_ERROR("Child-Request-Hdl not implemented!");
1182 void SvLBox::RecalcViewData()
1184 DBG_CHKTHIS(SvLBox
,0);
1185 SvLBoxEntry
* pEntry
= First();
1188 USHORT nCount
= pEntry
->ItemCount();
1190 while ( nCurPos
< nCount
)
1192 SvLBoxItem
* pItem
= pEntry
->GetItem( nCurPos
);
1193 pItem
->InitViewData( this, pEntry
);
1196 ViewDataInitialized( pEntry
);
1197 pEntry
= Next( pEntry
);
1201 void SvLBox::ViewDataInitialized( SvLBoxEntry
* )
1203 DBG_CHKTHIS(SvLBox
,0);
1206 void SvLBox::StateChanged( StateChangedType eType
)
1208 if( eType
== STATE_CHANGE_ENABLE
)
1209 Invalidate( INVALIDATE_CHILDREN
);
1210 Control::StateChanged( eType
);
1213 void SvLBox::ImplShowTargetEmphasis( SvLBoxEntry
* pEntry
, BOOL bShow
)
1215 DBG_CHKTHIS(SvLBox
,0);
1216 if ( bShow
&& (nImpFlags
& SVLBOX_TARGEMPH_VIS
) )
1218 if ( !bShow
&& !(nImpFlags
& SVLBOX_TARGEMPH_VIS
) )
1220 ShowTargetEmphasis( pEntry
, bShow
);
1222 nImpFlags
|= SVLBOX_TARGEMPH_VIS
;
1224 nImpFlags
&= ~SVLBOX_TARGEMPH_VIS
;
1227 void SvLBox::ShowTargetEmphasis( SvLBoxEntry
*, BOOL
/* bShow */ )
1229 DBG_CHKTHIS(SvLBox
,0);
1233 BOOL
SvLBox::Expand( SvLBoxEntry
* )
1235 DBG_CHKTHIS(SvLBox
,0);
1239 BOOL
SvLBox::Collapse( SvLBoxEntry
* )
1241 DBG_CHKTHIS(SvLBox
,0);
1245 BOOL
SvLBox::Select( SvLBoxEntry
*, BOOL
)
1247 DBG_CHKTHIS(SvLBox
,0);
1251 ULONG
SvLBox::SelectChilds( SvLBoxEntry
* , BOOL
)
1253 DBG_CHKTHIS(SvLBox
,0);
1257 void SvLBox::SelectAll( BOOL
/* bSelect */ , BOOL
/* bPaint */ )
1259 DBG_CHKTHIS(SvLBox
,0);
1262 SvLBoxEntry
* SvLBox::GetEntryFromPath( const ::std::deque
< sal_Int32
>& _rPath
) const
1264 DBG_CHKTHIS(SvLBox
,0);
1266 SvLBoxEntry
* pEntry
= NULL
;
1267 SvLBoxEntry
* pParent
= NULL
;
1268 for( ::std::deque
< sal_Int32
>::const_iterator pItem
= _rPath
.begin(); pItem
!= _rPath
.end(); ++pItem
)
1270 pEntry
= GetEntry( pParent
, *pItem
);
1279 void SvLBox::FillEntryPath( SvLBoxEntry
* pEntry
, ::std::deque
< sal_Int32
>& _rPath
) const
1281 DBG_CHKTHIS(SvLBox
,0);
1285 SvLBoxEntry
* pParentEntry
= GetParent( pEntry
);
1288 ULONG i
, nCount
= GetLevelChildCount( pParentEntry
);
1289 for ( i
= 0; i
< nCount
; ++i
)
1291 SvLBoxEntry
* pTemp
= GetEntry( pParentEntry
, i
);
1292 DBG_ASSERT( pEntry
, "invalid entry" );
1293 if ( pEntry
== pTemp
)
1295 _rPath
.push_front( (sal_Int32
)i
);
1302 pEntry
= pParentEntry
;
1303 pParentEntry
= GetParent( pParentEntry
);
1311 String
SvLBox::GetEntryText( SvLBoxEntry
* ) const
1313 DBG_CHKTHIS(SvLBox
,0);
1318 ULONG
SvLBox::GetLevelChildCount( SvLBoxEntry
* _pParent
) const
1320 DBG_CHKTHIS(SvLBox
,0);
1323 SvLBoxEntry
* pEntry
= FirstChild( _pParent
);
1327 pEntry
= NextSibling( pEntry
);
1333 void SvLBox::SetSelectionMode( SelectionMode eSelectMode
)
1335 DBG_CHKTHIS(SvLBox
,0);
1336 eSelMode
= eSelectMode
;
1339 void SvLBox::SetDragDropMode( DragDropMode nDDMode
)
1341 DBG_CHKTHIS(SvLBox
,0);
1342 nDragDropMode
= nDDMode
;
1345 SvViewData
* SvLBox::CreateViewData( SvListEntry
* )
1347 DBG_CHKTHIS(SvLBox
,0);
1348 SvViewDataEntry
* pEntryData
= new SvViewDataEntry
;
1349 return (SvViewData
*)pEntryData
;
1352 void SvLBox::InitViewData( SvViewData
* pData
, SvListEntry
* pEntry
)
1354 DBG_CHKTHIS(SvLBox
,0);
1355 SvLBoxEntry
* pInhEntry
= (SvLBoxEntry
*)pEntry
;
1356 SvViewDataEntry
* pEntryData
= (SvViewDataEntry
*)pData
;
1358 pEntryData
->pItemData
= new SvViewDataItem
[ pInhEntry
->ItemCount() ];
1359 SvViewDataItem
* pItemData
= pEntryData
->pItemData
;
1360 pEntryData
->nItmCnt
= pInhEntry
->ItemCount(); // Anzahl Items fuer delete
1361 USHORT nCount
= pInhEntry
->ItemCount();
1363 while( nCurPos
< nCount
)
1365 SvLBoxItem
* pItem
= pInhEntry
->GetItem( nCurPos
);
1366 pItem
->InitViewData( this, pInhEntry
, pItemData
);
1374 void SvLBox::EnableSelectionAsDropTarget( BOOL bEnable
, BOOL bWithChilds
)
1376 DBG_CHKTHIS(SvLBox
,0);
1380 SvLBoxEntry
* pSelEntry
= FirstSelected();
1385 pSelEntry
->nEntryFlags
|= SV_ENTRYFLAG_DISABLE_DROP
;
1388 nRefDepth
= pModel
->GetDepth( pSelEntry
);
1389 pTemp
= Next( pSelEntry
);
1390 while( pTemp
&& pModel
->GetDepth( pTemp
) > nRefDepth
)
1392 pTemp
->nEntryFlags
|= SV_ENTRYFLAG_DISABLE_DROP
;
1393 pTemp
= Next( pTemp
);
1399 pSelEntry
->nEntryFlags
&= (~SV_ENTRYFLAG_DISABLE_DROP
);
1402 nRefDepth
= pModel
->GetDepth( pSelEntry
);
1403 pTemp
= Next( pSelEntry
);
1404 while( pTemp
&& pModel
->GetDepth( pTemp
) > nRefDepth
)
1406 pTemp
->nEntryFlags
&= (~SV_ENTRYFLAG_DISABLE_DROP
);
1407 pTemp
= Next( pTemp
);
1411 pSelEntry
= NextSelected( pSelEntry
);
1415 SvLBoxEntry
* SvLBox::GetDropTarget( const Point
& )
1417 DBG_CHKTHIS(SvLBox
,0);
1421 // ******************************************************************
1423 // ******************************************************************
1425 void SvLBox::EditText( const String
& rStr
, const Rectangle
& rRect
,
1426 const Selection
& rSel
)
1428 EditText( rStr
, rRect
, rSel
, FALSE
);
1431 void SvLBox::EditText( const String
& rStr
, const Rectangle
& rRect
,
1432 const Selection
& rSel
, BOOL bMulti
)
1434 DBG_CHKTHIS(SvLBox
,0);
1437 nImpFlags
|= SVLBOX_IN_EDT
;
1438 nImpFlags
&= ~SVLBOX_EDTEND_CALLED
;
1440 pEdCtrl
= new SvInplaceEdit2(
1441 this, rRect
.TopLeft(), rRect
.GetSize(), rStr
,
1442 LINK( this, SvLBox
, TextEditEndedHdl_Impl
),
1446 IMPL_LINK( SvLBox
, TextEditEndedHdl_Impl
, SvInplaceEdit2
*, EMPTYARG
)
1448 DBG_CHKTHIS(SvLBox
,0);
1449 if ( nImpFlags
& SVLBOX_EDTEND_CALLED
) // Nesting verhindern
1451 nImpFlags
|= SVLBOX_EDTEND_CALLED
;
1453 if ( !pEdCtrl
->EditingCanceled() )
1454 aStr
= pEdCtrl
->GetText();
1456 aStr
= pEdCtrl
->GetSavedValue();
1457 if ( IsEmptyTextAllowed() || aStr
.Len() > 0 )
1459 // Hide darf erst gerufen werden, nachdem der neue Text in den
1460 // Entry gesetzt wurde, damit im GetFocus der ListBox nicht
1461 // der Selecthandler mit dem alten EntryText gerufen wird.
1465 nImpFlags
&= (~SVLBOX_IN_EDT
);
1470 void SvLBox::CancelTextEditing()
1472 DBG_CHKTHIS(SvLBox
,0);
1474 pEdCtrl
->StopEditing( TRUE
);
1475 nImpFlags
&= (~SVLBOX_IN_EDT
);
1478 void SvLBox::EndEditing( BOOL bCancel
)
1480 DBG_CHKTHIS(SvLBox
,0);
1482 pEdCtrl
->StopEditing( bCancel
);
1483 nImpFlags
&= (~SVLBOX_IN_EDT
);
1487 bool SvLBox::IsEmptyTextAllowed() const
1489 DBG_CHKTHIS(SvLBox
,0);
1490 return pLBoxImpl
->m_bIsEmptyTextAllowed
;
1493 void SvLBox::ForbidEmptyText()
1495 DBG_CHKTHIS(SvLBox
,0);
1496 pLBoxImpl
->m_bIsEmptyTextAllowed
= false;
1499 void SvLBox::EditedText( const String
& )
1501 DBG_CHKTHIS(SvLBox
,0);
1504 void SvLBox::EditingRequest( SvLBoxEntry
*, SvLBoxItem
*,const Point
& )
1506 DBG_CHKTHIS(SvLBox
,0);
1510 SvLBoxEntry
* SvLBox::CreateEntry() const
1512 DBG_CHKTHIS(SvLBox
,0);
1513 return new SvLBoxEntry
;
1516 void SvLBox::MakeVisible( SvLBoxEntry
* )
1518 DBG_CHKTHIS(SvLBox
,0);
1521 void SvLBox::Command( const CommandEvent
& )
1523 DBG_CHKTHIS(SvLBox
,0);
1526 void SvLBox::KeyInput( const KeyEvent
& rKEvt
)
1528 bool bHandled
= HandleKeyInput( rKEvt
);
1530 Control::KeyInput( rKEvt
);
1533 const void* SvLBox::FirstSearchEntry( String
& _rEntryText
)
1535 SvLBoxEntry
* pEntry
= GetCurEntry();
1537 pEntry
= const_cast< SvLBoxEntry
* >( static_cast< const SvLBoxEntry
* >( NextSearchEntry( pEntry
, _rEntryText
) ) );
1541 pEntry
= FirstSelected();
1547 _rEntryText
= GetEntryText( pEntry
);
1552 const void* SvLBox::NextSearchEntry( const void* _pCurrentSearchEntry
, String
& _rEntryText
)
1554 SvLBoxEntry
* pEntry
= const_cast< SvLBoxEntry
* >( static_cast< const SvLBoxEntry
* >( _pCurrentSearchEntry
) );
1556 pEntry
= Next( pEntry
);
1561 _rEntryText
= GetEntryText( pEntry
);
1566 void SvLBox::SelectSearchEntry( const void* _pEntry
)
1568 SvLBoxEntry
* pEntry
= const_cast< SvLBoxEntry
* >( static_cast< const SvLBoxEntry
* >( _pEntry
) );
1569 DBG_ASSERT( pEntry
, "SvLBox::SelectSearchEntry: invalid entry!" );
1574 SetCurEntry( pEntry
);
1578 void SvLBox::ExecuteSearchEntry( const void* /*_pEntry*/ )
1580 // nothing to do here, we have no "execution"
1583 bool SvLBox::HandleKeyInput( const KeyEvent
& _rKEvt
)
1585 if ( !IsEntryMnemonicsEnabled() )
1588 return pLBoxImpl
->m_aMnemonicEngine
.HandleKeyEvent( _rKEvt
);
1591 SvLBoxEntry
* SvLBox::GetEntry( const Point
&, BOOL
) const
1593 DBG_CHKTHIS(SvLBox
,0);
1597 void SvLBox::ModelHasEntryInvalidated( SvListEntry
* pEntry
)
1599 DBG_CHKTHIS(SvLBox
,0);
1600 USHORT nCount
= ((SvLBoxEntry
*)pEntry
)->ItemCount();
1601 for( USHORT nIdx
= 0; nIdx
< nCount
; nIdx
++ )
1603 SvLBoxItem
* pItem
= ((SvLBoxEntry
*)pEntry
)->GetItem( nIdx
);
1604 pItem
->InitViewData( this, (SvLBoxEntry
*)pEntry
, 0 );
1608 void SvLBox::SetInUseEmphasis( SvLBoxEntry
* pEntry
, BOOL bInUse
)
1610 DBG_CHKTHIS(SvLBox
,0);
1611 DBG_ASSERT(pEntry
,"SetInUseEmphasis:No Entry");
1614 if( !pEntry
->HasInUseEmphasis() )
1616 pEntry
->nEntryFlags
|= SV_ENTRYFLAG_IN_USE
;
1617 pModel
->InvalidateEntry( pEntry
);
1622 if( pEntry
->HasInUseEmphasis() )
1624 pEntry
->nEntryFlags
&= (~SV_ENTRYFLAG_IN_USE
);
1625 pModel
->InvalidateEntry( pEntry
);
1630 void SvLBox::SetCursorEmphasis( SvLBoxEntry
* pEntry
, BOOL bCursored
)
1632 DBG_CHKTHIS(SvLBox
,0);
1633 DBG_ASSERT(pEntry
,"SetInUseEmphasis:No Entry");
1634 SvViewDataEntry
* pViewData
= GetViewDataEntry( pEntry
);
1635 if( pViewData
&& (bCursored
!= pViewData
->IsCursored()) )
1637 pViewData
->SetCursored( bCursored
);
1638 // paintet in allen Views
1639 // pModel->InvalidateEntry( pEntry );
1640 // invalidiert nur in dieser View
1641 ModelHasEntryInvalidated( pEntry
);
1645 BOOL
SvLBox::HasCursorEmphasis( SvLBoxEntry
* pEntry
) const
1647 DBG_CHKTHIS(SvLBox
,0);
1648 DBG_ASSERT(pEntry
,"SetInUseEmphasis:No Entry");
1649 SvViewDataEntry
* pViewData
= GetViewDataEntry( pEntry
);
1650 DBG_ASSERT(pViewData
,"Entry not in View");
1651 return pViewData
->IsCursored();
1654 void SvLBox::WriteDragServerInfo( const Point
&, SvLBoxDDInfo
* )
1656 DBG_CHKTHIS(SvLBox
,0);
1659 void SvLBox::ReadDragServerInfo(const Point
&, SvLBoxDDInfo
* )
1661 DBG_CHKTHIS(SvLBox
,0);
1664 BOOL
SvLBox::EditingCanceled() const
1666 if( pEdCtrl
&& pEdCtrl
->EditingCanceled() )
1672 //JP 28.3.2001: new Drag & Drop API
1673 sal_Int8
SvLBox::AcceptDrop( const AcceptDropEvent
& rEvt
)
1675 DBG_CHKTHIS(SvLBox
,0);
1676 sal_Int8 nRet
= DND_ACTION_NONE
;
1678 if( rEvt
.mbLeaving
|| !CheckDragAndDropMode( pDDSource
, rEvt
.mnAction
) )
1680 ImplShowTargetEmphasis( pTargetEntry
, FALSE
);
1682 else if( !nDragDropMode
)
1684 DBG_ERRORFILE( "SvLBox::QueryDrop(): no target" );
1688 SvLBoxEntry
* pEntry
= GetDropTarget( rEvt
.maPosPixel
);
1689 if( !IsDropFormatSupported( SOT_FORMATSTR_ID_TREELISTBOX
) )
1691 DBG_ERRORFILE( "SvLBox::QueryDrop(): no format" );
1695 DBG_ASSERT( pDDSource
, "SvLBox::QueryDrop(): SourceBox == 0 (__EXPORT?)" );
1696 if( !( pEntry
&& pDDSource
->GetModel() == this->GetModel()
1697 && DND_ACTION_MOVE
== rEvt
.mnAction
1698 && ( pEntry
->nEntryFlags
& SV_ENTRYFLAG_DISABLE_DROP
) ))
1700 if( NotifyAcceptDrop( pEntry
))
1701 nRet
= rEvt
.mnAction
;
1705 // **** Emphasis zeichnen ****
1706 if( DND_ACTION_NONE
== nRet
)
1707 ImplShowTargetEmphasis( pTargetEntry
, FALSE
);
1708 else if( pEntry
!= pTargetEntry
|| !(nImpFlags
& SVLBOX_TARGEMPH_VIS
) )
1710 ImplShowTargetEmphasis( pTargetEntry
, FALSE
);
1711 pTargetEntry
= pEntry
;
1712 ImplShowTargetEmphasis( pTargetEntry
, TRUE
);
1718 sal_Int8
SvLBox::ExecuteDrop( const ExecuteDropEvent
& rEvt
, SvLBox
* pSourceView
)
1720 DBG_CHKTHIS(SvLBox
,0);
1721 sal_Int8 nRet
= DND_ACTION_NONE
;
1723 DBG_ASSERT( pSourceView
, "SvLBox::ExecuteDrop(): no source view" );
1724 pSourceView
->EnableSelectionAsDropTarget( TRUE
, TRUE
);
1726 ImplShowTargetEmphasis( pTargetEntry
, FALSE
);
1729 SvLBoxDDInfo aDDInfo
;
1731 TransferableDataHelper
aData( rEvt
.maDropEvent
.Transferable
);
1732 if( aData
.HasFormat( SOT_FORMATSTR_ID_TREELISTBOX
))
1734 ::com::sun::star::uno::Sequence
< sal_Int8
> aSeq
;
1735 if( aData
.GetSequence( SOT_FORMATSTR_ID_TREELISTBOX
, aSeq
) &&
1736 sizeof(SvLBoxDDInfo
) == aSeq
.getLength() )
1738 memcpy( &aDDInfo
, aSeq
.getConstArray(), sizeof(SvLBoxDDInfo
) );
1739 nRet
= rEvt
.mnAction
;
1743 if( DND_ACTION_NONE
!= nRet
)
1745 nRet
= DND_ACTION_NONE
;
1747 ReadDragServerInfo( rEvt
.maPosPixel
, &aDDInfo
);
1749 SvLBoxEntry
* pTarget
= pTargetEntry
; // !!! kann 0 sein !!!
1751 if( DND_ACTION_COPY
== rEvt
.mnAction
)
1753 if ( CopySelection( aDDInfo
.pSource
, pTarget
) )
1754 nRet
= rEvt
.mnAction
;
1756 else if( DND_ACTION_MOVE
== rEvt
.mnAction
)
1758 if ( MoveSelection( aDDInfo
.pSource
, pTarget
) )
1759 nRet
= rEvt
.mnAction
;
1761 else if( DND_ACTION_COPYMOVE
== rEvt
.mnAction
)
1763 if ( MoveSelectionCopyFallbackPossible( aDDInfo
.pSource
, pTarget
, sal_True
) )
1764 nRet
= rEvt
.mnAction
;
1770 sal_Int8
SvLBox::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
1772 DBG_CHKTHIS(SvLBox
,0);
1773 return ExecuteDrop( rEvt
, GetSourceView() );
1776 void SvLBox::StartDrag( sal_Int8
, const Point
& rPosPixel
)
1778 DBG_CHKTHIS(SvLBox
,0);
1781 SvLBoxEntry
* pEntry
= GetEntry( rPosPixel
); // GetDropTarget( rPos );
1782 nOldDragMode
= GetDragDropMode();
1783 if( !pEntry
|| !nOldDragMode
)
1785 DragFinished( DND_ACTION_NONE
);
1789 TransferDataContainer
* pContainer
= new TransferDataContainer
;
1790 ::com::sun::star::uno::Reference
<
1791 ::com::sun::star::datatransfer::XTransferable
> xRef( pContainer
);
1793 nDragDropMode
= NotifyStartDrag( *pContainer
, pEntry
);
1794 if( !nDragDropMode
|| 0 == GetSelectionCount() )
1796 nDragDropMode
= nOldDragMode
;
1797 DragFinished( DND_ACTION_NONE
);
1801 SvLBoxDDInfo aDDInfo
;
1802 memset(&aDDInfo
,0,sizeof(SvLBoxDDInfo
));
1803 aDDInfo
.pApp
= GetpApp();
1804 aDDInfo
.pSource
= this;
1805 aDDInfo
.pDDStartEntry
= pEntry
;
1806 // abgeleitete Views zum Zuge kommen lassen
1807 WriteDragServerInfo( rPosPixel
, &aDDInfo
);
1809 pContainer
->CopyAnyData( SOT_FORMATSTR_ID_TREELISTBOX
,
1810 (sal_Char
*)&aDDInfo
, sizeof(SvLBoxDDInfo
) );
1814 BOOL bOldUpdateMode
= Control::IsUpdateMode();
1815 Control::SetUpdateMode( TRUE
);
1817 Control::SetUpdateMode( bOldUpdateMode
);
1819 // Selektion & deren Childs im Model als DropTargets sperren
1820 // Wichtig: Wenn im DropHandler die Selektion der
1821 // SourceListBox veraendert wird, muessen vorher die Eintraege
1822 // als DropTargets wieder freigeschaltet werden:
1823 // (GetSourceListBox()->EnableSelectionAsDropTarget( TRUE, TRUE );)
1824 EnableSelectionAsDropTarget( FALSE
, TRUE
/* with Childs */ );
1826 pContainer
->StartDrag( this, nDragOptions
, GetDragFinishedHdl() );
1829 void SvLBox::DragFinished( sal_Int8
1835 EnableSelectionAsDropTarget( TRUE
, TRUE
);
1838 if( (nAction
== DND_ACTION_MOVE
) && ( (pDDTarget
&&
1839 ((ULONG
)(pDDTarget
->GetModel())!=(ULONG
)(this->GetModel()))) ||
1846 ImplShowTargetEmphasis( pTargetEntry
, FALSE
);
1850 nDragDropMode
= nOldDragMode
;
1853 DragDropMode
SvLBox::NotifyStartDrag( TransferDataContainer
&, SvLBoxEntry
* )
1855 DBG_CHKTHIS(SvLBox
,0);
1856 return (DragDropMode
)0xffff;
1859 BOOL
SvLBox::NotifyAcceptDrop( SvLBoxEntry
* )
1861 DBG_CHKTHIS(SvLBox
,0);
1865 // handler and methods for Drag - finished handler.
1866 // The with get GetDragFinishedHdl() get link can set on the
1867 // TransferDataContainer. This link is a callback for the DragFinished
1868 // call. AddBox method is called from the GetDragFinishedHdl() and the
1869 // remove is called in link callback and in the destructor. So it can't
1870 // called to a deleted object.
1874 struct SortLBoxes
: public rtl::Static
<SvULongsSort
, SortLBoxes
> {};
1877 void SvLBox::AddBoxToDDList_Impl( const SvLBox
& rB
)
1879 ULONG nVal
= (ULONG
)&rB
;
1880 SortLBoxes::get().Insert( nVal
);
1883 void SvLBox::RemoveBoxFromDDList_Impl( const SvLBox
& rB
)
1885 ULONG nVal
= (ULONG
)&rB
;
1886 SortLBoxes::get().Remove( nVal
);
1889 IMPL_STATIC_LINK( SvLBox
, DragFinishHdl_Impl
, sal_Int8
*, pAction
)
1891 ULONG nVal
= (ULONG
)pThis
;
1893 SvULongsSort
&rSortLBoxes
= SortLBoxes::get();
1894 if( rSortLBoxes
.Seek_Entry( nVal
, &nFnd
) )
1896 pThis
->DragFinished( *pAction
);
1897 rSortLBoxes
.Remove( nFnd
, 1 );
1902 Link
SvLBox::GetDragFinishedHdl() const
1904 AddBoxToDDList_Impl( *this );
1905 return STATIC_LINK( this, SvLBox
, DragFinishHdl_Impl
);
1908 void SvLBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper
& ) const
1912 ::com::sun::star::uno::Reference
< XAccessible
> SvLBox::CreateAccessible()
1914 return ::com::sun::star::uno::Reference
< XAccessible
>();
1917 Rectangle
SvLBox::GetBoundingRect( SvLBoxEntry
* )