xref: /trunk/main/svtools/source/contnr/svlbox.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svtools.hxx"
30 
31 /*
32     Todo:
33         - Anker loeschen in SelectionEngine bei manuellem Selektieren
34         - SelectAll( sal_False ), nur die deselektierten Entries repainten
35 */
36 
37 #include <string.h>
38 #include <svtools/svlbox.hxx>
39 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
40 #include <vcl/svapp.hxx>
41 #include <vcl/accel.hxx>
42 #include <vcl/i18nhelp.hxx>
43 #include <sot/formats.hxx>
44 #include <unotools/accessiblestatesethelper.hxx>
45 #include <rtl/instance.hxx>
46 
47 #define _SVSTDARR_ULONGSSORT
48 #include <svl/svstdarr.hxx>
49 
50 #ifndef _SVEDI_HXX
51 #include <svtools/svmedit.hxx>
52 #endif
53 #include <svtools/svlbitm.hxx>
54 
55 using namespace ::com::sun::star::accessibility;
56 
57 // Drag&Drop
58 static SvLBox* pDDSource = NULL;
59 static SvLBox* pDDTarget = NULL;
60 
61 DBG_NAME(SvInplaceEdit)
62 DBG_NAME(SvInplaceEdit2)
63 
64 #define SVLBOX_ACC_RETURN 1
65 #define SVLBOX_ACC_ESCAPE 2
66 
67 SvInplaceEdit::SvInplaceEdit
68 (
69     Window*             pParent,
70     const Point&        rPos,
71     const Size&         rSize,
72     const String&       rData,
73     const Link&         rNotifyEditEnd,
74     const Selection&    rSelection
75 ) :
76 
77     Edit( pParent, WB_LEFT ),
78 
79     aCallBackHdl        ( rNotifyEditEnd ),
80     bCanceled           ( sal_False ),
81     bAlreadyInCallBack  ( sal_False )
82 
83 {
84     DBG_CTOR(SvInplaceEdit,0);
85 
86     Font aFont( pParent->GetFont() );
87     aFont.SetTransparent( sal_False );
88     Color aColor( pParent->GetBackground().GetColor() );
89     aFont.SetFillColor(aColor );
90     SetFont( aFont );
91     SetBackground( pParent->GetBackground() );
92     SetPosPixel( rPos );
93     SetSizePixel( rSize );
94     SetText( rData );
95     SetSelection( rSelection );
96     SaveValue();
97 
98     aAccReturn.InsertItem( SVLBOX_ACC_RETURN, KeyCode(KEY_RETURN) );
99     aAccEscape.InsertItem( SVLBOX_ACC_ESCAPE, KeyCode(KEY_ESCAPE) );
100 
101     aAccReturn.SetActivateHdl( LINK( this, SvInplaceEdit, ReturnHdl_Impl) );
102     aAccEscape.SetActivateHdl( LINK( this, SvInplaceEdit, EscapeHdl_Impl) );
103     GetpApp()->InsertAccel( &aAccReturn  );
104     GetpApp()->InsertAccel( &aAccEscape );
105 
106     Show();
107     GrabFocus();
108 }
109 
110 SvInplaceEdit::~SvInplaceEdit()
111 {
112     DBG_DTOR(SvInplaceEdit,0);
113     if( !bAlreadyInCallBack )
114     {
115         GetpApp()->RemoveAccel( &aAccReturn );
116         GetpApp()->RemoveAccel( &aAccEscape );
117     }
118 }
119 
120 IMPL_LINK_INLINE_START( SvInplaceEdit, ReturnHdl_Impl, Accelerator *, EMPTYARG )
121 {
122     DBG_CHKTHIS(SvInplaceEdit,0);
123     bCanceled = sal_False;
124     CallCallBackHdl_Impl();
125     return 1;
126 }
127 IMPL_LINK_INLINE_END( SvInplaceEdit, ReturnHdl_Impl, Accelerator *, EMPTYARG )
128 
129 IMPL_LINK_INLINE_START( SvInplaceEdit, EscapeHdl_Impl, Accelerator *, EMPTYARG )
130 {
131     DBG_CHKTHIS(SvInplaceEdit,0);
132     bCanceled = sal_True;
133     CallCallBackHdl_Impl();
134     return 1;
135 }
136 IMPL_LINK_INLINE_END( SvInplaceEdit, EscapeHdl_Impl, Accelerator *, EMPTYARG )
137 
138 void SvInplaceEdit::KeyInput( const KeyEvent& rKEvt )
139 {
140     DBG_CHKTHIS(SvInplaceEdit,0);
141     sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
142     switch ( nCode )
143     {
144         case KEY_ESCAPE:
145             bCanceled = sal_True;
146             CallCallBackHdl_Impl();
147             break;
148 
149         case KEY_RETURN:
150             bCanceled = sal_False;
151             CallCallBackHdl_Impl();
152             break;
153 
154         default:
155             Edit::KeyInput( rKEvt );
156     }
157 }
158 
159 void SvInplaceEdit::StopEditing( sal_Bool bCancel )
160 {
161     DBG_CHKTHIS(SvInplaceEdit,0);
162     if ( !bAlreadyInCallBack )
163     {
164         bCanceled = bCancel;
165         CallCallBackHdl_Impl();
166     }
167 }
168 
169 void SvInplaceEdit::LoseFocus()
170 {
171     DBG_CHKTHIS(SvInplaceEdit,0);
172     if ( !bAlreadyInCallBack )
173     {
174         bCanceled = sal_False;
175         aTimer.SetTimeout(10);
176         aTimer.SetTimeoutHdl(LINK(this,SvInplaceEdit,Timeout_Impl));
177         aTimer.Start();
178     }
179 }
180 
181 IMPL_LINK_INLINE_START( SvInplaceEdit, Timeout_Impl, Timer *, EMPTYARG )
182 {
183     DBG_CHKTHIS(SvInplaceEdit,0);
184     CallCallBackHdl_Impl();
185     return 0;
186 }
187 IMPL_LINK_INLINE_END( SvInplaceEdit, Timeout_Impl, Timer *, EMPTYARG )
188 
189 void SvInplaceEdit::CallCallBackHdl_Impl()
190 {
191     DBG_CHKTHIS(SvInplaceEdit,0);
192     aTimer.Stop();
193     if ( !bAlreadyInCallBack )
194     {
195         bAlreadyInCallBack = sal_True;
196         GetpApp()->RemoveAccel( &aAccReturn );
197         GetpApp()->RemoveAccel( &aAccEscape );
198         Hide();
199         aCallBackHdl.Call( this );
200         // bAlreadyInCallBack = sal_False;
201     }
202 }
203 
204 
205 // ***************************************************************
206 
207 class MyEdit_Impl : public Edit
208 {
209     SvInplaceEdit2* pOwner;
210 public:
211                  MyEdit_Impl( Window* pParent, SvInplaceEdit2* pOwner );
212     virtual void KeyInput( const KeyEvent& rKEvt );
213     virtual void LoseFocus();
214 };
215 
216 class MyMultiEdit_Impl : public MultiLineEdit
217 {
218     SvInplaceEdit2* pOwner;
219 public:
220                  MyMultiEdit_Impl( Window* pParent, SvInplaceEdit2* pOwner );
221     virtual void KeyInput( const KeyEvent& rKEvt );
222     virtual void LoseFocus();
223 };
224 
225 MyEdit_Impl::MyEdit_Impl( Window* pParent, SvInplaceEdit2* _pOwner ) :
226 
227     Edit( pParent, WB_LEFT ),
228 
229     pOwner( _pOwner )
230 
231 {
232 }
233 
234 void MyEdit_Impl::KeyInput( const KeyEvent& rKEvt )
235 {
236     if( !pOwner->KeyInput( rKEvt ))
237         Edit::KeyInput( rKEvt );
238 }
239 
240 void MyEdit_Impl::LoseFocus()
241 {
242     pOwner->LoseFocus();
243 }
244 
245 MyMultiEdit_Impl::MyMultiEdit_Impl( Window* pParent, SvInplaceEdit2* _pOwner )
246     : MultiLineEdit( pParent,
247     WB_CENTER
248     ), pOwner(_pOwner)
249 {
250 }
251 
252 void MyMultiEdit_Impl::KeyInput( const KeyEvent& rKEvt )
253 {
254     if( !pOwner->KeyInput( rKEvt ))
255         MultiLineEdit::KeyInput( rKEvt );
256 }
257 
258 void MyMultiEdit_Impl::LoseFocus()
259 {
260     pOwner->LoseFocus();
261 }
262 
263 
264 SvInplaceEdit2::SvInplaceEdit2
265 (
266     Window* pParent, const Point& rPos,
267     const Size& rSize,
268     const String& rData,
269     const Link& rNotifyEditEnd,
270     const Selection& rSelection,
271     sal_Bool bMulti
272 ) :
273 
274      aCallBackHdl       ( rNotifyEditEnd ),
275     bCanceled           ( sal_False ),
276     bAlreadyInCallBack  ( sal_False ),
277     bMultiLine          ( bMulti )
278 
279 {
280     DBG_CTOR(SvInplaceEdit2,0);
281 
282     if( bMulti )
283         pEdit = new MyMultiEdit_Impl( pParent, this );
284     else
285         pEdit = new MyEdit_Impl( pParent, this );
286 
287     Font aFont( pParent->GetFont() );
288     aFont.SetTransparent( sal_False );
289     Color aColor( pParent->GetBackground().GetColor() );
290     aFont.SetFillColor(aColor );
291     pEdit->SetFont( aFont );
292     pEdit->SetBackground( pParent->GetBackground() );
293     pEdit->SetPosPixel( rPos );
294     pEdit->SetSizePixel( rSize );
295     pEdit->SetText( rData );
296     pEdit->SetSelection( rSelection );
297     pEdit->SaveValue();
298 
299     aAccReturn.InsertItem( SVLBOX_ACC_RETURN, KeyCode(KEY_RETURN) );
300     aAccEscape.InsertItem( SVLBOX_ACC_ESCAPE, KeyCode(KEY_ESCAPE) );
301 
302     aAccReturn.SetActivateHdl( LINK( this, SvInplaceEdit2, ReturnHdl_Impl) );
303     aAccEscape.SetActivateHdl( LINK( this, SvInplaceEdit2, EscapeHdl_Impl) );
304     GetpApp()->InsertAccel( &aAccReturn );
305     GetpApp()->InsertAccel( &aAccEscape );
306 
307     pEdit->Show();
308     pEdit->GrabFocus();
309 }
310 
311 SvInplaceEdit2::~SvInplaceEdit2()
312 {
313     DBG_DTOR(SvInplaceEdit2,0);
314     if( !bAlreadyInCallBack )
315     {
316         GetpApp()->RemoveAccel( &aAccReturn );
317         GetpApp()->RemoveAccel( &aAccEscape );
318     }
319     delete pEdit;
320 }
321 
322 String SvInplaceEdit2::GetSavedValue() const
323 {
324     return pEdit->GetSavedValue();
325 }
326 
327 void SvInplaceEdit2::Hide()
328 {
329     pEdit->Hide();
330 }
331 
332 
333 IMPL_LINK_INLINE_START( SvInplaceEdit2, ReturnHdl_Impl, Accelerator *, EMPTYARG )
334 {
335     DBG_CHKTHIS(SvInplaceEdit2,0);
336     bCanceled = sal_False;
337     CallCallBackHdl_Impl();
338     return 1;
339 }
340 IMPL_LINK_INLINE_END( SvInplaceEdit2, ReturnHdl_Impl, Accelerator *, EMPTYARG )
341 
342 IMPL_LINK_INLINE_START( SvInplaceEdit2, EscapeHdl_Impl, Accelerator *, EMPTYARG )
343 {
344     DBG_CHKTHIS(SvInplaceEdit2,0);
345     bCanceled = sal_True;
346     CallCallBackHdl_Impl();
347     return 1;
348 }
349 IMPL_LINK_INLINE_END( SvInplaceEdit2, EscapeHdl_Impl, Accelerator *, EMPTYARG )
350 
351 
352 sal_Bool SvInplaceEdit2::KeyInput( const KeyEvent& rKEvt )
353 {
354     DBG_CHKTHIS(SvInplaceEdit2,0);
355     KeyCode aCode = rKEvt.GetKeyCode();
356     sal_uInt16 nCode = aCode.GetCode();
357 
358     switch ( nCode )
359     {
360         case KEY_ESCAPE:
361             bCanceled = sal_True;
362             CallCallBackHdl_Impl();
363             return sal_True;
364 
365         case KEY_RETURN:
366             bCanceled = sal_False;
367             CallCallBackHdl_Impl();
368             return sal_True;
369     }
370     return sal_False;
371 }
372 
373 void SvInplaceEdit2::StopEditing( sal_Bool bCancel )
374 {
375     DBG_CHKTHIS(SvInplaceEdit2,0);
376     if ( !bAlreadyInCallBack )
377     {
378         bCanceled = bCancel;
379         CallCallBackHdl_Impl();
380     }
381 }
382 
383 void SvInplaceEdit2::LoseFocus()
384 {
385     DBG_CHKTHIS(SvInplaceEdit2,0);
386     if ( !bAlreadyInCallBack
387     && ((!Application::GetFocusWindow()) || !pEdit->IsChild( Application::GetFocusWindow()) )
388     )
389     {
390         bCanceled = sal_False;
391         aTimer.SetTimeout(10);
392         aTimer.SetTimeoutHdl(LINK(this,SvInplaceEdit2,Timeout_Impl));
393         aTimer.Start();
394     }
395 }
396 
397 IMPL_LINK_INLINE_START( SvInplaceEdit2, Timeout_Impl, Timer *, EMPTYARG )
398 {
399     DBG_CHKTHIS(SvInplaceEdit2,0);
400     CallCallBackHdl_Impl();
401     return 0;
402 }
403 IMPL_LINK_INLINE_END( SvInplaceEdit2, Timeout_Impl, Timer *, EMPTYARG )
404 
405 void SvInplaceEdit2::CallCallBackHdl_Impl()
406 {
407     DBG_CHKTHIS(SvInplaceEdit2,0);
408     aTimer.Stop();
409     if ( !bAlreadyInCallBack )
410     {
411         bAlreadyInCallBack = sal_True;
412         GetpApp()->RemoveAccel( &aAccReturn );
413         GetpApp()->RemoveAccel( &aAccEscape );
414         pEdit->Hide();
415         aCallBackHdl.Call( this );
416     }
417 }
418 
419 String SvInplaceEdit2::GetText() const
420 {
421     return pEdit->GetText();
422 }
423 
424 // ***************************************************************
425 // class SvLBoxTab
426 // ***************************************************************
427 
428 DBG_NAME(SvLBoxTab);
429 
430 SvLBoxTab::SvLBoxTab()
431 {
432     DBG_CTOR(SvLBoxTab,0);
433     nPos = 0;
434     pUserData = 0;
435     nFlags = 0;
436 }
437 
438 SvLBoxTab::SvLBoxTab( long nPosition, sal_uInt16 nTabFlags )
439 {
440     DBG_CTOR(SvLBoxTab,0);
441     nPos = nPosition;
442     pUserData = 0;
443     nFlags = nTabFlags;
444 }
445 
446 SvLBoxTab::SvLBoxTab( const SvLBoxTab& rTab )
447 {
448     DBG_CTOR(SvLBoxTab,0);
449     nPos = rTab.nPos;
450     pUserData = rTab.pUserData;
451     nFlags = rTab.nFlags;
452 }
453 
454 SvLBoxTab::~SvLBoxTab()
455 {
456     DBG_DTOR(SvLBoxTab,0);
457 }
458 
459 
460 long SvLBoxTab::CalcOffset( long nItemWidth, long nTabWidth )
461 {
462     DBG_CHKTHIS(SvLBoxTab,0);
463     long nOffset = 0;
464     if ( nFlags & SV_LBOXTAB_ADJUST_RIGHT )
465     {
466         nOffset = nTabWidth - nItemWidth;
467         if( nOffset < 0 )
468             nOffset = 0;
469     }
470     else if ( nFlags & SV_LBOXTAB_ADJUST_CENTER )
471     {
472         if( nFlags & SV_LBOXTAB_FORCE )
473         {
474             //richtige Implementierung der Zentrierung
475             nOffset = ( nTabWidth - nItemWidth ) / 2;
476             if( nOffset < 0 )
477                 nOffset = 0;
478         }
479         else
480         {
481             // historisch gewachsene falsche Berechnung des Tabs, auf die sich
482             // Abo-Tabbox, Extras/Optionen/Anpassen etc. verlassen
483             nItemWidth++;
484             nOffset = -( nItemWidth / 2 );
485         }
486     }
487     return nOffset;
488 }
489 
490 /*
491 long SvLBoxTab::CalcOffset( const String& rStr, const OutputDevice& rOutDev )
492 {
493     DBG_CHKTHIS(SvLBoxTab,0);
494     long nWidth;
495     if ( nFlags & SV_LBOXTAB_ADJUST_NUMERIC )
496     {
497         sal_uInt16 nPos = rStr.Search( '.' );
498         if ( nPos == STRING_NOTFOUND )
499             nPos = rStr.Search( ',' );
500         if ( nPos == STRING_NOTFOUND )
501             nPos = STRING_LEN;
502 
503         nWidth = rOutDev.GetTextSize( rStr, 0, nPos ).Width();
504         nWidth *= -1;
505     }
506     else
507     {
508         nWidth = rOutDev.GetTextSize( rStr ).Width();
509         nWidth = CalcOffset( nWidth );
510     }
511     return nWidth;
512 }
513 */
514 
515 // ***************************************************************
516 // class SvLBoxItem
517 // ***************************************************************
518 
519 DBG_NAME(SvLBoxItem);
520 
521 SvLBoxItem::SvLBoxItem( SvLBoxEntry*, sal_uInt16 )
522 {
523     DBG_CTOR(SvLBoxItem,0);
524 }
525 
526 SvLBoxItem::SvLBoxItem()
527 {
528     DBG_CTOR(SvLBoxItem,0);
529 }
530 
531 SvLBoxItem::~SvLBoxItem()
532 {
533     DBG_DTOR(SvLBoxItem,0);
534 }
535 
536 const Size& SvLBoxItem::GetSize( SvLBox* pView,SvLBoxEntry* pEntry )
537 {
538     DBG_CHKTHIS(SvLBoxItem,0);
539     SvViewDataItem* pViewData = pView->GetViewDataItem( pEntry, this );
540     return pViewData->aSize;
541 }
542 
543 const Size& SvLBoxItem::GetSize( SvLBoxEntry* pEntry, SvViewDataEntry* pViewData)
544 {
545     DBG_CHKTHIS(SvLBoxItem,0);
546     sal_uInt16 nItemPos = pEntry->GetPos( this );
547     SvViewDataItem* pItemData = pViewData->pItemData+nItemPos;
548     return pItemData->aSize;
549 }
550 
551 DBG_NAME(SvViewDataItem);
552 
553 SvViewDataItem::SvViewDataItem()
554 {
555     DBG_CTOR(SvViewDataItem,0);
556 }
557 
558 SvViewDataItem::~SvViewDataItem()
559 {
560     DBG_DTOR(SvViewDataItem,0);
561 }
562 
563 
564 
565 // ***************************************************************
566 // class SvLBoxEntry
567 // ***************************************************************
568 
569 DBG_NAME(SvLBoxEntry);
570 
571 SvLBoxEntry::SvLBoxEntry() : aItems()
572 {
573     DBG_CTOR(SvLBoxEntry,0);
574     nEntryFlags = 0;
575     pUserData = 0;
576 }
577 
578 SvLBoxEntry::~SvLBoxEntry()
579 {
580     DBG_DTOR(SvLBoxEntry,0);
581     DeleteItems_Impl();
582 }
583 
584 void SvLBoxEntry::DeleteItems_Impl()
585 {
586     DBG_CHKTHIS(SvLBoxEntry,0);
587     sal_uInt16 nCount = aItems.Count();
588     while( nCount )
589     {
590         nCount--;
591         SvLBoxItem* pItem = (SvLBoxItem*)aItems.GetObject( nCount );
592         delete pItem;
593     }
594     aItems.Remove(0, aItems.Count() );
595 }
596 
597 
598 void SvLBoxEntry::AddItem( SvLBoxItem* pItem )
599 {
600     DBG_CHKTHIS(SvLBoxEntry,0);
601     aItems.Insert( pItem, aItems.Count() );
602 }
603 
604 void SvLBoxEntry::Clone( SvListEntry* pSource )
605 {
606     DBG_CHKTHIS(SvLBoxEntry,0);
607     SvListEntry::Clone( pSource );
608     SvLBoxItem* pNewItem;
609     DeleteItems_Impl();
610     sal_uInt16 nCount = ((SvLBoxEntry*)pSource)->ItemCount();
611     sal_uInt16 nCurPos = 0;
612     while( nCurPos < nCount )
613     {
614         SvLBoxItem* pItem = ((SvLBoxEntry*)pSource)->GetItem( nCurPos );
615         pNewItem = pItem->Create();
616         pNewItem->Clone( pItem );
617         AddItem( pNewItem );
618         nCurPos++;
619     }
620     pUserData = ((SvLBoxEntry*)pSource)->GetUserData();
621     nEntryFlags = ((SvLBoxEntry*)pSource)->nEntryFlags;
622 }
623 
624 void SvLBoxEntry::EnableChildsOnDemand( sal_Bool bEnable )
625 {
626     DBG_CHKTHIS(SvLBoxEntry,0);
627     if ( bEnable )
628         nEntryFlags |= SV_ENTRYFLAG_CHILDS_ON_DEMAND;
629     else
630         nEntryFlags &= (~SV_ENTRYFLAG_CHILDS_ON_DEMAND);
631 }
632 
633 void SvLBoxEntry::ReplaceItem( SvLBoxItem* pNewItem, sal_uInt16 nPos )
634 {
635     DBG_CHKTHIS(SvLBoxEntry,0);
636     DBG_ASSERT(pNewItem,"ReplaceItem:No Item");
637     SvLBoxItem* pOld = GetItem( nPos );
638     if ( pOld )
639     {
640         aItems.Remove( nPos );
641         aItems.Insert( pNewItem, nPos );
642         delete pOld;
643     }
644 }
645 
646 SvLBoxItem* SvLBoxEntry::GetFirstItem( sal_uInt16 nId )
647 {
648     sal_uInt16 nCount = aItems.Count();
649     sal_uInt16 nCur = 0;
650     SvLBoxItem* pItem;
651     while( nCur < nCount )
652     {
653         pItem = GetItem( nCur );
654         if( pItem->IsA() == nId )
655             return pItem;
656         nCur++;
657     }
658     return 0;
659 }
660 
661 // ***************************************************************
662 // class SvLBoxViewData
663 // ***************************************************************
664 
665 DBG_NAME(SvViewDataEntry);
666 
667 SvViewDataEntry::SvViewDataEntry()
668     : SvViewData()
669 {
670     DBG_CTOR(SvViewDataEntry,0);
671     pItemData = 0;
672 }
673 
674 SvViewDataEntry::~SvViewDataEntry()
675 {
676     DBG_DTOR(SvViewDataEntry,0);
677     delete [] pItemData;
678 }
679 
680 // ***************************************************************
681 // struct SvLBox_Impl
682 // ***************************************************************
683 SvLBox_Impl::SvLBox_Impl( SvLBox& _rBox )
684     :m_bIsEmptyTextAllowed( true )
685     ,m_bEntryMnemonicsEnabled( false )
686     ,m_bDoingQuickSelection( false )
687     ,m_pLink( NULL )
688     ,m_aMnemonicEngine( _rBox )
689     ,m_aQuickSelectionEngine( _rBox )
690 {
691 }
692 
693 // ***************************************************************
694 // class SvLBox
695 // ***************************************************************
696 
697 DBG_NAME(SvLBox);
698 
699 SvLBox::SvLBox( Window* pParent, WinBits nWinStyle  ) :
700     Control( pParent, nWinStyle | WB_CLIPCHILDREN ),
701     DropTargetHelper( this ), DragSourceHelper( this ), eSelMode( NO_SELECTION )
702 {
703     DBG_CTOR(SvLBox,0);
704     nDragOptions =  DND_ACTION_COPYMOVE | DND_ACTION_LINK;
705     nImpFlags = 0;
706     pTargetEntry = 0;
707     nDragDropMode = 0;
708     pLBoxImpl = new SvLBox_Impl( *this );
709     SvLBoxTreeList* pTempModel = new SvLBoxTreeList;
710     pTempModel->SetRefCount( 0 );
711     SetModel( pTempModel );
712     pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
713     pModel->InsertView( this );
714     pHdlEntry = 0;
715     pEdCtrl = 0;
716     SetSelectionMode( SINGLE_SELECTION );  // pruefen ob TreeListBox gecallt wird
717     SetDragDropMode( SV_DRAGDROP_NONE );
718     SetType(WINDOW_TREELISTBOX);
719 }
720 
721 SvLBox::SvLBox( Window* pParent, const ResId& rResId ) :
722     Control( pParent, rResId ),
723     DropTargetHelper( this ), DragSourceHelper( this ), eSelMode( NO_SELECTION )
724 {
725     DBG_CTOR(SvLBox,0);
726     pTargetEntry = 0;
727     nImpFlags = 0;
728     pLBoxImpl = new SvLBox_Impl( *this );
729     nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK;
730     nDragDropMode = 0;
731     SvLBoxTreeList* pTempModel = new SvLBoxTreeList;
732     pTempModel->SetRefCount( 0 );
733     SetModel( pTempModel );
734     pModel->InsertView( this );
735     pHdlEntry = 0;
736     pEdCtrl = 0;
737     pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
738     SetType(WINDOW_TREELISTBOX);
739 }
740 
741 __EXPORT SvLBox::~SvLBox()
742 {
743     DBG_DTOR(SvLBox,0);
744     delete pEdCtrl;
745     pEdCtrl = 0;
746     pModel->RemoveView( this );
747     if ( pModel->GetRefCount() == 0 )
748     {
749         pModel->Clear();
750         delete pModel;
751         pModel = NULL;
752     }
753 
754     SvLBox::RemoveBoxFromDDList_Impl( *this );
755 
756     if( this == pDDSource )
757         pDDSource = 0;
758     if( this == pDDTarget )
759         pDDTarget = 0;
760     delete pLBoxImpl;
761 }
762 
763 void SvLBox::SetModel( SvLBoxTreeList* pNewModel )
764 {
765     DBG_CHKTHIS(SvLBox,0);
766     // erledigt das ganz CleanUp
767     SvListView::SetModel( pNewModel );
768     pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
769     SvLBoxEntry* pEntry = First();
770     while( pEntry )
771     {
772         ModelHasInserted( pEntry );
773         pEntry = Next( pEntry );
774     }
775 }
776 
777 void SvLBox::DisconnectFromModel()
778 {
779     DBG_CHKTHIS(SvLBox,0);
780     SvLBoxTreeList* pNewModel = new SvLBoxTreeList;
781     pNewModel->SetRefCount( 0 );    // else this will never be deleted
782     SvListView::SetModel( pNewModel );
783 }
784 
785 void SvLBox::Clear()
786 {
787     DBG_CHKTHIS(SvLBox,0);
788     pModel->Clear();  // Model ruft SvLBox::ModelHasCleared() auf
789 }
790 
791 void SvLBox::EnableEntryMnemonics( bool _bEnable )
792 {
793     if ( _bEnable == IsEntryMnemonicsEnabled() )
794         return;
795 
796     pLBoxImpl->m_bEntryMnemonicsEnabled = _bEnable;
797     Invalidate();
798 }
799 
800 bool SvLBox::IsEntryMnemonicsEnabled() const
801 {
802     return pLBoxImpl->m_bEntryMnemonicsEnabled;
803 }
804 
805 sal_uInt16 SvLBox::IsA()
806 {
807     DBG_CHKTHIS(SvLBox,0);
808     return SVLISTBOX_ID_LBOX;
809 }
810 
811 IMPL_LINK_INLINE_START( SvLBox, CloneHdl_Impl, SvListEntry*, pEntry )
812 {
813     DBG_CHKTHIS(SvLBox,0);
814     return (long)(CloneEntry((SvLBoxEntry*)pEntry));
815 }
816 IMPL_LINK_INLINE_END( SvLBox, CloneHdl_Impl, SvListEntry*, pEntry )
817 
818 sal_uLong SvLBox::Insert( SvLBoxEntry* pEntry, SvLBoxEntry* pParent, sal_uLong nPos )
819 {
820     DBG_CHKTHIS(SvLBox,0);
821     sal_uLong nInsPos = pModel->Insert( pEntry, pParent, nPos );
822     return nInsPos;
823 }
824 
825 sal_uLong SvLBox::Insert( SvLBoxEntry* pEntry,sal_uLong nRootPos )
826 {
827     DBG_CHKTHIS(SvLBox,0);
828     sal_uLong nInsPos = pModel->Insert( pEntry, nRootPos );
829     return nInsPos;
830 }
831 
832 long SvLBox::ExpandingHdl()
833 {
834     DBG_CHKTHIS(SvLBox,0);
835     return aExpandingHdl.IsSet() ? aExpandingHdl.Call( this ) : 1;
836 }
837 
838 void SvLBox::ExpandedHdl()
839 {
840     DBG_CHKTHIS(SvLBox,0);
841     aExpandedHdl.Call( this );
842 }
843 
844 void SvLBox::SelectHdl()
845 {
846     DBG_CHKTHIS(SvLBox,0);
847     aSelectHdl.Call( this );
848 }
849 
850 void SvLBox::DeselectHdl()
851 {
852     DBG_CHKTHIS(SvLBox,0);
853     aDeselectHdl.Call( this );
854 }
855 
856 sal_Bool SvLBox::DoubleClickHdl()
857 {
858     DBG_CHKTHIS(SvLBox,0);
859     aDoubleClickHdl.Call( this );
860     return sal_True;
861 }
862 
863 
864 sal_Bool SvLBox::CheckDragAndDropMode( SvLBox* pSource, sal_Int8 nAction )
865 {
866     DBG_CHKTHIS(SvLBox,0);
867     if ( pSource == this )
868     {
869         if ( !(nDragDropMode & (SV_DRAGDROP_CTRL_MOVE | SV_DRAGDROP_CTRL_COPY) ) )
870             return sal_False; // D&D innerhalb der Liste gesperrt
871         if( DND_ACTION_MOVE == nAction )
872         {
873             if ( !(nDragDropMode & SV_DRAGDROP_CTRL_MOVE) )
874                  return sal_False; // kein lokales Move
875         }
876         else
877         {
878             if ( !(nDragDropMode & SV_DRAGDROP_CTRL_COPY))
879                 return sal_False; // kein lokales Copy
880         }
881     }
882     else
883     {
884         if ( !(nDragDropMode & SV_DRAGDROP_APP_DROP ) )
885             return sal_False; // kein Drop
886         if ( DND_ACTION_MOVE == nAction )
887         {
888             if ( !(nDragDropMode & SV_DRAGDROP_APP_MOVE) )
889                 return sal_False; // kein globales Move
890         }
891         else
892         {
893             if ( !(nDragDropMode & SV_DRAGDROP_APP_COPY))
894                 return sal_False; // kein globales Copy
895         }
896     }
897     return sal_True;
898 }
899 
900 
901 
902 
903 void SvLBox::NotifyRemoving( SvLBoxEntry* )
904 {
905     DBG_CHKTHIS(SvLBox,0);
906 }
907 
908 /*
909     NotifyMoving/Copying
910     ====================
911 
912     Standard-Verhalten:
913 
914     1. Target hat keine Childs
915         - Entry wird Sibling des Targets. Entry steht hinter dem
916           Target (->Fenster: Unter dem Target)
917     2. Target ist ein aufgeklappter Parent
918         - Entry wird an den Anfang der Target-Childlist gehaengt
919     3. Target ist ein zugeklappter Parent
920         - Entry wird an das Ende der Target-Childlist gehaengt
921 */
922 #ifdef DBG_UTIL
923 sal_Bool SvLBox::NotifyMoving(
924     SvLBoxEntry*  pTarget,       // D&D-Drop-Position in this->GetModel()
925     SvLBoxEntry*  pEntry,        // Zu verschiebender Entry aus
926                                  // GetSourceListBox()->GetModel()
927     SvLBoxEntry*& rpNewParent,   // Neuer Target-Parent
928     sal_uLong&        rNewChildPos)  // Position in Childlist des Target-Parents
929 #else
930 sal_Bool SvLBox::NotifyMoving(
931     SvLBoxEntry*  pTarget,       // D&D-Drop-Position in this->GetModel()
932     SvLBoxEntry*,                // Zu verschiebender Entry aus
933                                  // GetSourceListBox()->GetModel()
934     SvLBoxEntry*& rpNewParent,   // Neuer Target-Parent
935     sal_uLong&        rNewChildPos)  // Position in Childlist des Target-Parents
936 #endif
937 {
938     DBG_CHKTHIS(SvLBox,0);
939     DBG_ASSERT(pEntry,"NotifyMoving:SoureEntry?");
940     if( !pTarget )
941     {
942         rpNewParent = 0;
943         rNewChildPos = 0;
944         return sal_True;
945     }
946     if ( !pTarget->HasChilds() && !pTarget->HasChildsOnDemand() )
947     {
948         // Fall 1
949         rpNewParent = GetParent( pTarget );
950         rNewChildPos = pModel->GetRelPos( pTarget ) + 1;
951         rNewChildPos += nCurEntrySelPos;
952         nCurEntrySelPos++;
953     }
954     else
955     {
956         // Faelle 2 & 3
957         rpNewParent = pTarget;
958         if( IsExpanded(pTarget))
959             rNewChildPos = 0;
960         else
961             rNewChildPos = LIST_APPEND;
962     }
963     return sal_True;
964 }
965 
966 sal_Bool SvLBox::NotifyCopying(
967     SvLBoxEntry*  pTarget,       // D&D-Drop-Position in this->GetModel()
968     SvLBoxEntry*  pEntry,        // Zu kopierender Entry aus
969                                  // GetSourceListBox()->GetModel()
970     SvLBoxEntry*& rpNewParent,   // Neuer Target-Parent
971     sal_uLong&        rNewChildPos)  // Position in Childlist des Target-Parents
972 {
973     DBG_CHKTHIS(SvLBox,0);
974     return NotifyMoving(pTarget,pEntry,rpNewParent,rNewChildPos);
975     /*
976     DBG_ASSERT(pEntry,"NotifyCopying:SourceEntry?");
977     if( !pTarget )
978     {
979         rpNewParent = 0;
980         rNewChildPos = 0;
981         return sal_True;
982     }
983     if ( !pTarget->HasChilds() && !pTarget->HasChildsOnDemand() )
984     {
985         // Fall 1
986         rpNewParent = GetParent( pTarget );
987         rNewChildPos = GetRelPos( pTarget ) + 1;
988     }
989     else
990     {
991         // Faelle 2 & 3
992         rpNewParent = pTarget;
993         if( IsExpanded(pTarget))
994             rNewChildPos = 0;
995         else
996             rNewChildPos = LIST_APPEND;
997     }
998     return sal_True;
999     */
1000 }
1001 
1002 SvLBoxEntry* SvLBox::CloneEntry( SvLBoxEntry* pSource )
1003 {
1004     DBG_CHKTHIS(SvLBox,0);
1005     SvLBoxEntry* pEntry = (SvLBoxEntry*)CreateEntry(); // new SvLBoxEntry;
1006     pEntry->Clone( (SvListEntry*)pSource );
1007     return pEntry;
1008 }
1009 
1010 
1011 // Rueckgabe: Alle Entries wurden kopiert
1012 sal_Bool SvLBox::CopySelection( SvLBox* pSource, SvLBoxEntry* pTarget )
1013 {
1014     DBG_CHKTHIS(SvLBox,0);
1015     nCurEntrySelPos = 0; // Selektionszaehler fuer NotifyMoving/Copying
1016     sal_Bool bSuccess = sal_True;
1017     SvTreeEntryList aList;
1018     sal_Bool bClone = (sal_Bool)( (sal_uLong)(pSource->GetModel()) != (sal_uLong)GetModel() );
1019     Link aCloneLink( pModel->GetCloneLink() );
1020     pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
1021 
1022     // Selektion zwischenspeichern, um bei D&D-Austausch
1023     // innerhalb der gleichen Listbox das Iterieren ueber
1024     // die Selektion zu vereinfachen
1025     SvLBoxEntry* pSourceEntry = pSource->FirstSelected();
1026     while ( pSourceEntry )
1027     {
1028         // Childs werden automatisch mitkopiert
1029         pSource->SelectChilds( pSourceEntry, sal_False );
1030         aList.Insert( pSourceEntry, LIST_APPEND );
1031         pSourceEntry = pSource->NextSelected( pSourceEntry );
1032     }
1033 
1034     pSourceEntry = (SvLBoxEntry*)aList.First();
1035     while ( pSourceEntry )
1036     {
1037         SvLBoxEntry* pNewParent = 0;
1038         sal_uLong nInsertionPos = LIST_APPEND;
1039         sal_Bool bOk=NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos);
1040         if ( bOk )
1041         {
1042             if ( bClone )
1043             {
1044                 sal_uLong nCloneCount = 0;
1045                 pSourceEntry = (SvLBoxEntry*)
1046                     pModel->Clone( (SvListEntry*)pSourceEntry, nCloneCount );
1047                 pModel->InsertTree( (SvListEntry*)pSourceEntry,
1048                                     (SvListEntry*)pNewParent, nInsertionPos );
1049             }
1050             else
1051             {
1052                 sal_uLong nListPos = pModel->Copy( (SvListEntry*)pSourceEntry,
1053                     (SvListEntry*)pNewParent, nInsertionPos );
1054                 pSourceEntry = GetEntry( pNewParent, nListPos );
1055             }
1056         }
1057         else
1058             bSuccess = sal_False;
1059 
1060         if( bOk == (sal_Bool)2 )  // !!!HACK  verschobenen Entry sichtbar machen?
1061             MakeVisible( pSourceEntry );
1062 
1063         pSourceEntry = (SvLBoxEntry*)aList.Next();
1064     }
1065     pModel->SetCloneLink( aCloneLink );
1066     return bSuccess;
1067 }
1068 
1069 // Rueckgabe: Alle Entries wurden verschoben
1070 sal_Bool SvLBox::MoveSelection( SvLBox* pSource, SvLBoxEntry* pTarget )
1071 {
1072     return MoveSelectionCopyFallbackPossible( pSource, pTarget, sal_False );
1073 }
1074 
1075 sal_Bool SvLBox::MoveSelectionCopyFallbackPossible( SvLBox* pSource, SvLBoxEntry* pTarget, sal_Bool bAllowCopyFallback )
1076 {
1077     DBG_CHKTHIS(SvLBox,0);
1078     nCurEntrySelPos = 0; // Selektionszaehler fuer NotifyMoving/Copying
1079     sal_Bool bSuccess = sal_True;
1080     SvTreeEntryList aList;
1081     sal_Bool bClone = (sal_Bool)( (sal_uLong)(pSource->GetModel()) != (sal_uLong)GetModel() );
1082     Link aCloneLink( pModel->GetCloneLink() );
1083     if ( bClone )
1084         pModel->SetCloneLink( LINK(this, SvLBox, CloneHdl_Impl ));
1085 
1086     SvLBoxEntry* pSourceEntry = pSource->FirstSelected();
1087     while ( pSourceEntry )
1088     {
1089         // Childs werden automatisch mitbewegt
1090         pSource->SelectChilds( pSourceEntry, sal_False );
1091         aList.Insert( pSourceEntry, LIST_APPEND );
1092         pSourceEntry = pSource->NextSelected( pSourceEntry );
1093     }
1094 
1095     pSourceEntry = (SvLBoxEntry*)aList.First();
1096     while ( pSourceEntry )
1097     {
1098         SvLBoxEntry* pNewParent = 0;
1099         sal_uLong nInsertionPos = LIST_APPEND;
1100         sal_Bool bOk = NotifyMoving(pTarget,pSourceEntry,pNewParent,nInsertionPos);
1101         sal_Bool bCopyOk = bOk;
1102         if ( !bOk && bAllowCopyFallback )
1103         {
1104             nInsertionPos = LIST_APPEND;
1105             bCopyOk = NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos);
1106         }
1107 
1108         if ( bOk || bCopyOk )
1109         {
1110             if ( bClone )
1111             {
1112                 sal_uLong nCloneCount = 0;
1113                 pSourceEntry = (SvLBoxEntry*)
1114                     pModel->Clone( (SvListEntry*)pSourceEntry, nCloneCount );
1115                 pModel->InsertTree( (SvListEntry*)pSourceEntry,
1116                                     (SvListEntry*)pNewParent, nInsertionPos );
1117             }
1118             else
1119             {
1120                 if ( bOk )
1121                     pModel->Move( (SvListEntry*)pSourceEntry,
1122                                   (SvListEntry*)pNewParent, nInsertionPos );
1123                 else
1124                     pModel->Copy( (SvListEntry*)pSourceEntry,
1125                                   (SvListEntry*)pNewParent, nInsertionPos );
1126             }
1127         }
1128         else
1129             bSuccess = sal_False;
1130 
1131         if( bOk == (sal_Bool)2 )  // !!!HACK  verschobenen Entry sichtbar machen?
1132             MakeVisible( pSourceEntry );
1133 
1134         pSourceEntry = (SvLBoxEntry*)aList.Next();
1135     }
1136     pModel->SetCloneLink( aCloneLink );
1137     return bSuccess;
1138 }
1139 
1140 void SvLBox::RemoveSelection()
1141 {
1142     DBG_CHKTHIS(SvLBox,0);
1143     SvTreeEntryList aList;
1144     // Selektion zwischenspeichern, da die Impl bei
1145     // dem ersten Remove alles deselektiert!
1146     SvLBoxEntry* pEntry = FirstSelected();
1147     while ( pEntry )
1148     {
1149         aList.Insert( pEntry );
1150         if ( pEntry->HasChilds() )
1151             // Remove loescht Childs automatisch
1152             SelectChilds( pEntry, sal_False );
1153         pEntry = NextSelected( pEntry );
1154     }
1155     pEntry = (SvLBoxEntry*)aList.First();
1156     while ( pEntry )
1157     {
1158         pModel->Remove( pEntry );
1159         pEntry = (SvLBoxEntry*)aList.Next();
1160     }
1161 }
1162 
1163 SvLBox* SvLBox::GetSourceView() const
1164 {
1165     return pDDSource;
1166 }
1167 
1168 SvLBox* SvLBox::GetTargetView() const
1169 {
1170     return pDDTarget;
1171 }
1172 
1173 void SvLBox::RequestingChilds( SvLBoxEntry*  )
1174 {
1175     DBG_CHKTHIS(SvLBox,0);
1176     DBG_ERROR("Child-Request-Hdl not implemented!");
1177 }
1178 
1179 void SvLBox::RecalcViewData()
1180 {
1181     DBG_CHKTHIS(SvLBox,0);
1182     SvLBoxEntry* pEntry = First();
1183     while( pEntry )
1184     {
1185         sal_uInt16 nCount = pEntry->ItemCount();
1186         sal_uInt16 nCurPos = 0;
1187         while ( nCurPos < nCount )
1188         {
1189             SvLBoxItem* pItem = pEntry->GetItem( nCurPos );
1190             pItem->InitViewData( this, pEntry );
1191             nCurPos++;
1192         }
1193         ViewDataInitialized( pEntry );
1194         pEntry = Next( pEntry );
1195     }
1196 }
1197 
1198 void SvLBox::ViewDataInitialized( SvLBoxEntry* )
1199 {
1200     DBG_CHKTHIS(SvLBox,0);
1201 }
1202 
1203 void SvLBox::StateChanged( StateChangedType eType )
1204 {
1205     if( eType == STATE_CHANGE_ENABLE )
1206         Invalidate( INVALIDATE_CHILDREN );
1207     Control::StateChanged( eType );
1208 }
1209 
1210 void SvLBox::ImplShowTargetEmphasis( SvLBoxEntry* pEntry, sal_Bool bShow)
1211 {
1212     DBG_CHKTHIS(SvLBox,0);
1213     if ( bShow && (nImpFlags & SVLBOX_TARGEMPH_VIS) )
1214         return;
1215     if ( !bShow && !(nImpFlags & SVLBOX_TARGEMPH_VIS) )
1216         return;
1217     ShowTargetEmphasis( pEntry, bShow );
1218     if( bShow )
1219         nImpFlags |= SVLBOX_TARGEMPH_VIS;
1220     else
1221         nImpFlags &= ~SVLBOX_TARGEMPH_VIS;
1222 }
1223 
1224 void SvLBox::ShowTargetEmphasis( SvLBoxEntry*, sal_Bool /* bShow */ )
1225 {
1226     DBG_CHKTHIS(SvLBox,0);
1227 }
1228 
1229 
1230 sal_Bool SvLBox::Expand( SvLBoxEntry* )
1231 {
1232     DBG_CHKTHIS(SvLBox,0);
1233     return sal_True;
1234 }
1235 
1236 sal_Bool SvLBox::Collapse( SvLBoxEntry* )
1237 {
1238     DBG_CHKTHIS(SvLBox,0);
1239     return sal_True;
1240 }
1241 
1242 sal_Bool SvLBox::Select( SvLBoxEntry*, sal_Bool  )
1243 {
1244     DBG_CHKTHIS(SvLBox,0);
1245     return sal_False;
1246 }
1247 
1248 sal_uLong SvLBox::SelectChilds( SvLBoxEntry* , sal_Bool  )
1249 {
1250     DBG_CHKTHIS(SvLBox,0);
1251     return 0;
1252 }
1253 
1254 void SvLBox::OnCurrentEntryChanged()
1255 {
1256     if ( !pLBoxImpl->m_bDoingQuickSelection )
1257         pLBoxImpl->m_aQuickSelectionEngine.Reset();
1258 }
1259 
1260 void SvLBox::SelectAll( sal_Bool /* bSelect */ , sal_Bool /* bPaint */ )
1261 {
1262     DBG_CHKTHIS(SvLBox,0);
1263 }
1264 
1265 SvLBoxEntry* SvLBox::GetEntryFromPath( const ::std::deque< sal_Int32 >& _rPath ) const
1266 {
1267     DBG_CHKTHIS(SvLBox,0);
1268 
1269     SvLBoxEntry* pEntry = NULL;
1270     SvLBoxEntry* pParent = NULL;
1271     for( ::std::deque< sal_Int32 >::const_iterator pItem = _rPath.begin(); pItem != _rPath.end(); ++pItem )
1272     {
1273         pEntry = GetEntry( pParent, *pItem );
1274         if ( !pEntry )
1275             break;
1276         pParent = pEntry;
1277     }
1278 
1279     return pEntry;
1280 }
1281 
1282 void SvLBox::FillEntryPath( SvLBoxEntry* pEntry, ::std::deque< sal_Int32 >& _rPath ) const
1283 {
1284     DBG_CHKTHIS(SvLBox,0);
1285 
1286     if ( pEntry )
1287     {
1288         SvLBoxEntry* pParentEntry = GetParent( pEntry );
1289         while ( sal_True )
1290         {
1291             sal_uLong i, nCount = GetLevelChildCount( pParentEntry );
1292             for ( i = 0; i < nCount; ++i )
1293             {
1294                 SvLBoxEntry* pTemp = GetEntry( pParentEntry, i );
1295                 DBG_ASSERT( pEntry, "invalid entry" );
1296                 if ( pEntry == pTemp )
1297                 {
1298                     _rPath.push_front( (sal_Int32)i );
1299                     break;
1300                 }
1301             }
1302 
1303             if ( pParentEntry )
1304             {
1305                 pEntry = pParentEntry;
1306                 pParentEntry = GetParent( pParentEntry );
1307             }
1308             else
1309                 break;
1310         }
1311     }
1312 }
1313 
1314 String SvLBox::GetEntryText( SvLBoxEntry* ) const
1315 {
1316     DBG_CHKTHIS(SvLBox,0);
1317 
1318     return String();
1319 }
1320 
1321 sal_uLong SvLBox::GetLevelChildCount( SvLBoxEntry* _pParent ) const
1322 {
1323     DBG_CHKTHIS(SvLBox,0);
1324 
1325     sal_uLong nCount = 0;
1326     SvLBoxEntry* pEntry = FirstChild( _pParent );
1327     while ( pEntry )
1328     {
1329         ++nCount;
1330         pEntry = NextSibling( pEntry );
1331     }
1332 
1333     return nCount;
1334 }
1335 
1336 void SvLBox::SetSelectionMode( SelectionMode eSelectMode )
1337 {
1338     DBG_CHKTHIS(SvLBox,0);
1339     eSelMode = eSelectMode;
1340 }
1341 
1342 void SvLBox::SetDragDropMode( DragDropMode nDDMode )
1343 {
1344     DBG_CHKTHIS(SvLBox,0);
1345     nDragDropMode = nDDMode;
1346 }
1347 
1348 SvViewData* SvLBox::CreateViewData( SvListEntry* )
1349 {
1350     DBG_CHKTHIS(SvLBox,0);
1351     SvViewDataEntry* pEntryData = new SvViewDataEntry;
1352     return (SvViewData*)pEntryData;
1353 }
1354 
1355 void SvLBox::InitViewData( SvViewData* pData, SvListEntry* pEntry )
1356 {
1357     DBG_CHKTHIS(SvLBox,0);
1358     SvLBoxEntry* pInhEntry = (SvLBoxEntry*)pEntry;
1359     SvViewDataEntry* pEntryData = (SvViewDataEntry*)pData;
1360 
1361     pEntryData->pItemData = new SvViewDataItem[ pInhEntry->ItemCount() ];
1362     SvViewDataItem* pItemData = pEntryData->pItemData;
1363     pEntryData->nItmCnt = pInhEntry->ItemCount(); // Anzahl Items fuer delete
1364     sal_uInt16 nCount = pInhEntry->ItemCount();
1365     sal_uInt16 nCurPos = 0;
1366     while( nCurPos < nCount )
1367     {
1368         SvLBoxItem* pItem = pInhEntry->GetItem( nCurPos );
1369         pItem->InitViewData( this, pInhEntry, pItemData );
1370         pItemData++;
1371         nCurPos++;
1372     }
1373 }
1374 
1375 
1376 
1377 void SvLBox::EnableSelectionAsDropTarget( sal_Bool bEnable, sal_Bool bWithChilds )
1378 {
1379     DBG_CHKTHIS(SvLBox,0);
1380     sal_uInt16 nRefDepth;
1381     SvLBoxEntry* pTemp;
1382 
1383     SvLBoxEntry* pSelEntry = FirstSelected();
1384     while( pSelEntry )
1385     {
1386         if ( !bEnable )
1387         {
1388             pSelEntry->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP;
1389             if ( bWithChilds )
1390             {
1391                 nRefDepth = pModel->GetDepth( pSelEntry );
1392                 pTemp = Next( pSelEntry );
1393                 while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth )
1394                 {
1395                     pTemp->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP;
1396                     pTemp = Next( pTemp );
1397                 }
1398             }
1399         }
1400         else
1401         {
1402             pSelEntry->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP);
1403             if ( bWithChilds )
1404             {
1405                 nRefDepth = pModel->GetDepth( pSelEntry );
1406                 pTemp = Next( pSelEntry );
1407                 while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth )
1408                 {
1409                     pTemp->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP);
1410                     pTemp = Next( pTemp );
1411                 }
1412             }
1413         }
1414         pSelEntry = NextSelected( pSelEntry );
1415     }
1416 }
1417 
1418 SvLBoxEntry* SvLBox::GetDropTarget( const Point& )
1419 {
1420     DBG_CHKTHIS(SvLBox,0);
1421     return 0;
1422 }
1423 
1424 // ******************************************************************
1425 // InplaceEditing
1426 // ******************************************************************
1427 
1428 void SvLBox::EditText( const String& rStr, const Rectangle& rRect,
1429     const Selection& rSel )
1430 {
1431     EditText( rStr, rRect, rSel, sal_False );
1432 }
1433 
1434 void SvLBox::EditText( const String& rStr, const Rectangle& rRect,
1435     const Selection& rSel, sal_Bool bMulti )
1436 {
1437     DBG_CHKTHIS(SvLBox,0);
1438     if( pEdCtrl )
1439         delete pEdCtrl;
1440     nImpFlags |= SVLBOX_IN_EDT;
1441     nImpFlags &= ~SVLBOX_EDTEND_CALLED;
1442     HideFocus();
1443     pEdCtrl = new SvInplaceEdit2(
1444         this, rRect.TopLeft(), rRect.GetSize(), rStr,
1445         LINK( this, SvLBox, TextEditEndedHdl_Impl ),
1446         rSel, bMulti );
1447 }
1448 
1449 IMPL_LINK( SvLBox, TextEditEndedHdl_Impl, SvInplaceEdit2 *, EMPTYARG )
1450 {
1451     DBG_CHKTHIS(SvLBox,0);
1452     if ( nImpFlags & SVLBOX_EDTEND_CALLED ) // Nesting verhindern
1453         return 0;
1454     nImpFlags |= SVLBOX_EDTEND_CALLED;
1455     String aStr;
1456     if ( !pEdCtrl->EditingCanceled() )
1457         aStr = pEdCtrl->GetText();
1458     else
1459         aStr = pEdCtrl->GetSavedValue();
1460     if ( IsEmptyTextAllowed() || aStr.Len() > 0 )
1461         EditedText( aStr );
1462     // Hide darf erst gerufen werden, nachdem der neue Text in den
1463     // Entry gesetzt wurde, damit im GetFocus der ListBox nicht
1464     // der Selecthandler mit dem alten EntryText gerufen wird.
1465     pEdCtrl->Hide();
1466     // delete pEdCtrl;
1467     // pEdCtrl = 0;
1468     nImpFlags &= (~SVLBOX_IN_EDT);
1469     GrabFocus();
1470     return 0;
1471 }
1472 
1473 void SvLBox::CancelTextEditing()
1474 {
1475     DBG_CHKTHIS(SvLBox,0);
1476     if ( pEdCtrl )
1477         pEdCtrl->StopEditing( sal_True );
1478     nImpFlags &= (~SVLBOX_IN_EDT);
1479 }
1480 
1481 void SvLBox::EndEditing( sal_Bool bCancel )
1482 {
1483     DBG_CHKTHIS(SvLBox,0);
1484     if( pEdCtrl )
1485         pEdCtrl->StopEditing( bCancel );
1486     nImpFlags &= (~SVLBOX_IN_EDT);
1487 }
1488 
1489 
1490 bool SvLBox::IsEmptyTextAllowed() const
1491 {
1492     DBG_CHKTHIS(SvLBox,0);
1493     return pLBoxImpl->m_bIsEmptyTextAllowed;
1494 }
1495 
1496 void SvLBox::ForbidEmptyText()
1497 {
1498     DBG_CHKTHIS(SvLBox,0);
1499     pLBoxImpl->m_bIsEmptyTextAllowed = false;
1500 }
1501 
1502 void SvLBox::EditedText( const String& )
1503 {
1504     DBG_CHKTHIS(SvLBox,0);
1505 }
1506 
1507 void SvLBox::EditingRequest( SvLBoxEntry*, SvLBoxItem*,const Point& )
1508 {
1509     DBG_CHKTHIS(SvLBox,0);
1510 }
1511 
1512 
1513 SvLBoxEntry* SvLBox::CreateEntry() const
1514 {
1515     DBG_CHKTHIS(SvLBox,0);
1516     return new SvLBoxEntry;
1517 }
1518 
1519 void SvLBox::MakeVisible( SvLBoxEntry* )
1520 {
1521     DBG_CHKTHIS(SvLBox,0);
1522 }
1523 
1524 void SvLBox::Command( const CommandEvent& i_rCommandEvent )
1525 {
1526     DBG_CHKTHIS(SvLBox,0);
1527 
1528     if ( COMMAND_STARTDRAG == i_rCommandEvent.GetCommand() )
1529     {
1530         Point aEventPos( i_rCommandEvent.GetMousePosPixel() );
1531         MouseEvent aMouseEvt( aEventPos, 1, MOUSE_SELECT, MOUSE_LEFT );
1532         MouseButtonUp( aMouseEvt );
1533     }
1534     Control::Command( i_rCommandEvent );
1535 }
1536 
1537 void SvLBox::KeyInput( const KeyEvent& rKEvt )
1538 {
1539     bool bHandled = HandleKeyInput( rKEvt );
1540     if ( !bHandled )
1541         Control::KeyInput( rKEvt );
1542 }
1543 
1544 const void* SvLBox::FirstSearchEntry( String& _rEntryText ) const
1545 {
1546     SvLBoxEntry* pEntry = GetCurEntry();
1547     if ( pEntry )
1548         pEntry = const_cast< SvLBoxEntry* >( static_cast< const SvLBoxEntry* >( NextSearchEntry( pEntry, _rEntryText ) ) );
1549     else
1550     {
1551         pEntry = FirstSelected();
1552         if ( !pEntry )
1553             pEntry = First();
1554     }
1555 
1556     if ( pEntry )
1557         _rEntryText = GetEntryText( pEntry );
1558 
1559     return pEntry;
1560 }
1561 
1562 const void* SvLBox::NextSearchEntry( const void* _pCurrentSearchEntry, String& _rEntryText ) const
1563 {
1564     SvLBoxEntry* pEntry = const_cast< SvLBoxEntry* >( static_cast< const SvLBoxEntry* >( _pCurrentSearchEntry ) );
1565 
1566     if  (   (   ( GetChildCount( pEntry ) > 0 )
1567             ||  ( pEntry->HasChildsOnDemand() )
1568             )
1569         &&  !IsExpanded( pEntry )
1570         )
1571     {
1572         pEntry = NextSibling( pEntry );
1573     }
1574     else
1575     {
1576         pEntry = Next( pEntry );
1577     }
1578 
1579     if ( !pEntry )
1580         pEntry = First();
1581 
1582     if ( pEntry )
1583         _rEntryText = GetEntryText( pEntry );
1584 
1585     return pEntry;
1586 }
1587 
1588 void SvLBox::SelectSearchEntry( const void* _pEntry )
1589 {
1590     SvLBoxEntry* pEntry = const_cast< SvLBoxEntry* >( static_cast< const SvLBoxEntry* >( _pEntry ) );
1591     DBG_ASSERT( pEntry, "SvLBox::SelectSearchEntry: invalid entry!" );
1592     if ( !pEntry )
1593         return;
1594 
1595     SelectAll( sal_False );
1596     SetCurEntry( pEntry );
1597     Select( pEntry );
1598 }
1599 
1600 void SvLBox::ExecuteSearchEntry( const void* /*_pEntry*/ ) const
1601 {
1602     // nothing to do here, we have no "execution"
1603 }
1604 
1605 ::vcl::StringEntryIdentifier SvLBox::CurrentEntry( String& _out_entryText ) const
1606 {
1607     // always accept the current entry if there is one
1608     SvLBoxEntry* pCurrentEntry( GetCurEntry() );
1609     if ( pCurrentEntry )
1610     {
1611         _out_entryText = GetEntryText( pCurrentEntry );
1612         return pCurrentEntry;
1613     }
1614     return FirstSearchEntry( _out_entryText );
1615 }
1616 
1617 ::vcl::StringEntryIdentifier SvLBox::NextEntry( ::vcl::StringEntryIdentifier _currentEntry, String& _out_entryText ) const
1618 {
1619     return NextSearchEntry( _currentEntry, _out_entryText );
1620 }
1621 
1622 void SvLBox::SelectEntry( ::vcl::StringEntryIdentifier _entry )
1623 {
1624     SelectSearchEntry( _entry );
1625 }
1626 
1627 bool SvLBox::HandleKeyInput( const KeyEvent& _rKEvt )
1628 {
1629     if  (   IsEntryMnemonicsEnabled()
1630         &&  pLBoxImpl->m_aMnemonicEngine.HandleKeyEvent( _rKEvt )
1631         )
1632         return true;
1633 
1634     if ( ( GetStyle() & WB_QUICK_SEARCH ) != 0 )
1635     {
1636         pLBoxImpl->m_bDoingQuickSelection = true;
1637         const bool bHandled = pLBoxImpl->m_aQuickSelectionEngine.HandleKeyEvent( _rKEvt );
1638         pLBoxImpl->m_bDoingQuickSelection = false;
1639         if ( bHandled )
1640             return true;
1641     }
1642 
1643     return false;
1644 }
1645 
1646 SvLBoxEntry* SvLBox::GetEntry( const Point&, sal_Bool ) const
1647 {
1648     DBG_CHKTHIS(SvLBox,0);
1649     return 0;
1650 }
1651 
1652 void SvLBox::ModelHasEntryInvalidated( SvListEntry* pEntry )
1653 {
1654     DBG_CHKTHIS(SvLBox,0);
1655     sal_uInt16 nCount = ((SvLBoxEntry*)pEntry)->ItemCount();
1656     for( sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++ )
1657     {
1658         SvLBoxItem* pItem = ((SvLBoxEntry*)pEntry)->GetItem( nIdx );
1659         pItem->InitViewData( this, (SvLBoxEntry*)pEntry, 0 );
1660     }
1661 }
1662 
1663 void SvLBox::SetInUseEmphasis( SvLBoxEntry* pEntry, sal_Bool bInUse )
1664 {
1665     DBG_CHKTHIS(SvLBox,0);
1666     DBG_ASSERT(pEntry,"SetInUseEmphasis:No Entry");
1667     if( bInUse )
1668     {
1669         if( !pEntry->HasInUseEmphasis() )
1670         {
1671             pEntry->nEntryFlags |= SV_ENTRYFLAG_IN_USE;
1672             pModel->InvalidateEntry( pEntry );
1673         }
1674     }
1675     else
1676     {
1677         if( pEntry->HasInUseEmphasis() )
1678         {
1679             pEntry->nEntryFlags &= (~SV_ENTRYFLAG_IN_USE);
1680             pModel->InvalidateEntry( pEntry );
1681         }
1682     }
1683 }
1684 
1685 void SvLBox::SetCursorEmphasis( SvLBoxEntry* pEntry, sal_Bool bCursored )
1686 {
1687     DBG_CHKTHIS(SvLBox,0);
1688     DBG_ASSERT(pEntry,"SetInUseEmphasis:No Entry");
1689     SvViewDataEntry* pViewData = GetViewDataEntry( pEntry );
1690     if( pViewData && (bCursored != pViewData->IsCursored()) )
1691     {
1692         pViewData->SetCursored( bCursored );
1693         // paintet in allen Views
1694         // pModel->InvalidateEntry( pEntry );
1695         // invalidiert nur in dieser View
1696         ModelHasEntryInvalidated( pEntry );
1697     }
1698 }
1699 
1700 sal_Bool SvLBox::HasCursorEmphasis( SvLBoxEntry* pEntry ) const
1701 {
1702     DBG_CHKTHIS(SvLBox,0);
1703     DBG_ASSERT(pEntry,"SetInUseEmphasis:No Entry");
1704     SvViewDataEntry* pViewData = GetViewDataEntry( pEntry );
1705     DBG_ASSERT(pViewData,"Entry not in View");
1706     return pViewData->IsCursored();
1707 }
1708 
1709 void SvLBox::WriteDragServerInfo( const Point&, SvLBoxDDInfo* )
1710 {
1711     DBG_CHKTHIS(SvLBox,0);
1712 }
1713 
1714 void SvLBox::ReadDragServerInfo(const Point&, SvLBoxDDInfo* )
1715 {
1716     DBG_CHKTHIS(SvLBox,0);
1717 }
1718 
1719 sal_Bool SvLBox::EditingCanceled() const
1720 {
1721     if( pEdCtrl && pEdCtrl->EditingCanceled() )
1722         return sal_True;
1723     return sal_False;
1724 }
1725 
1726 
1727 //JP 28.3.2001: new Drag & Drop API
1728 sal_Int8 SvLBox::AcceptDrop( const AcceptDropEvent& rEvt )
1729 {
1730     DBG_CHKTHIS(SvLBox,0);
1731     sal_Int8 nRet = DND_ACTION_NONE;
1732 
1733     if( rEvt.mbLeaving || !CheckDragAndDropMode( pDDSource, rEvt.mnAction ) )
1734     {
1735         ImplShowTargetEmphasis( pTargetEntry, sal_False );
1736     }
1737     else if( !nDragDropMode )
1738     {
1739         DBG_ERRORFILE( "SvLBox::QueryDrop(): no target" );
1740     }
1741     else
1742     {
1743         SvLBoxEntry* pEntry = GetDropTarget( rEvt.maPosPixel );
1744         if( !IsDropFormatSupported( SOT_FORMATSTR_ID_TREELISTBOX ) )
1745         {
1746             DBG_ERRORFILE( "SvLBox::QueryDrop(): no format" );
1747         }
1748         else
1749         {
1750             DBG_ASSERT( pDDSource, "SvLBox::QueryDrop(): SourceBox == 0 (__EXPORT?)" );
1751             if( !( pEntry && pDDSource->GetModel() == this->GetModel()
1752                     && DND_ACTION_MOVE == rEvt.mnAction
1753                     && ( pEntry->nEntryFlags & SV_ENTRYFLAG_DISABLE_DROP ) ))
1754             {
1755                 if( NotifyAcceptDrop( pEntry ))
1756                     nRet = rEvt.mnAction;
1757             }
1758         }
1759 
1760         // **** Emphasis zeichnen ****
1761         if( DND_ACTION_NONE == nRet )
1762             ImplShowTargetEmphasis( pTargetEntry, sal_False );
1763         else if( pEntry != pTargetEntry || !(nImpFlags & SVLBOX_TARGEMPH_VIS) )
1764         {
1765             ImplShowTargetEmphasis( pTargetEntry, sal_False );
1766             pTargetEntry = pEntry;
1767             ImplShowTargetEmphasis( pTargetEntry, sal_True );
1768         }
1769     }
1770     return nRet;
1771 }
1772 
1773 sal_Int8 SvLBox::ExecuteDrop( const ExecuteDropEvent& rEvt, SvLBox* pSourceView )
1774 {
1775     DBG_CHKTHIS(SvLBox,0);
1776     sal_Int8 nRet = DND_ACTION_NONE;
1777 
1778     DBG_ASSERT( pSourceView, "SvLBox::ExecuteDrop(): no source view" );
1779     pSourceView->EnableSelectionAsDropTarget( sal_True, sal_True );
1780 
1781     ImplShowTargetEmphasis( pTargetEntry, sal_False );
1782     pDDTarget = this;
1783 
1784     SvLBoxDDInfo aDDInfo;
1785 
1786     TransferableDataHelper aData( rEvt.maDropEvent.Transferable );
1787     if( aData.HasFormat( SOT_FORMATSTR_ID_TREELISTBOX ))
1788     {
1789         ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
1790         if( aData.GetSequence( SOT_FORMATSTR_ID_TREELISTBOX, aSeq ) &&
1791             sizeof(SvLBoxDDInfo) == aSeq.getLength() )
1792         {
1793             memcpy( &aDDInfo, aSeq.getConstArray(), sizeof(SvLBoxDDInfo) );
1794             nRet = rEvt.mnAction;
1795         }
1796     }
1797 
1798     if( DND_ACTION_NONE != nRet )
1799     {
1800         nRet = DND_ACTION_NONE;
1801 
1802         ReadDragServerInfo( rEvt.maPosPixel, &aDDInfo );
1803 
1804         SvLBoxEntry* pTarget = pTargetEntry; // !!! kann 0 sein !!!
1805 
1806         if( DND_ACTION_COPY == rEvt.mnAction )
1807         {
1808             if ( CopySelection( aDDInfo.pSource, pTarget ) )
1809                 nRet = rEvt.mnAction;
1810         }
1811         else if( DND_ACTION_MOVE == rEvt.mnAction )
1812         {
1813             if ( MoveSelection( aDDInfo.pSource, pTarget ) )
1814                 nRet = rEvt.mnAction;
1815         }
1816         else if( DND_ACTION_COPYMOVE == rEvt.mnAction )
1817         {
1818             if ( MoveSelectionCopyFallbackPossible( aDDInfo.pSource, pTarget, sal_True ) )
1819                 nRet = rEvt.mnAction;
1820         }
1821     }
1822     return nRet;
1823 }
1824 
1825 sal_Int8 SvLBox::ExecuteDrop( const ExecuteDropEvent& rEvt )
1826 {
1827     DBG_CHKTHIS(SvLBox,0);
1828     return ExecuteDrop( rEvt, GetSourceView() );
1829 }
1830 
1831 void SvLBox::StartDrag( sal_Int8, const Point& rPosPixel )
1832 {
1833     DBG_CHKTHIS(SvLBox,0);
1834 
1835     Point aEventPos( rPosPixel );
1836     MouseEvent aMouseEvt( aEventPos, 1, MOUSE_SELECT, MOUSE_LEFT );
1837     MouseButtonUp( aMouseEvt );
1838 
1839     nOldDragMode = GetDragDropMode();
1840     if ( !nOldDragMode )
1841         return;
1842 
1843     ReleaseMouse();
1844 
1845     SvLBoxEntry* pEntry = GetEntry( rPosPixel ); // GetDropTarget( rPos );
1846     if( !pEntry )
1847     {
1848         DragFinished( DND_ACTION_NONE );
1849         return;
1850     }
1851 
1852     TransferDataContainer* pContainer = new TransferDataContainer;
1853     ::com::sun::star::uno::Reference<
1854         ::com::sun::star::datatransfer::XTransferable > xRef( pContainer );
1855 
1856     nDragDropMode = NotifyStartDrag( *pContainer, pEntry );
1857     if( !nDragDropMode || 0 == GetSelectionCount() )
1858     {
1859         nDragDropMode = nOldDragMode;
1860         DragFinished( DND_ACTION_NONE );
1861         return;
1862     }
1863 
1864     SvLBoxDDInfo aDDInfo;
1865     memset(&aDDInfo,0,sizeof(SvLBoxDDInfo));
1866     aDDInfo.pApp = GetpApp();
1867     aDDInfo.pSource = this;
1868     aDDInfo.pDDStartEntry = pEntry;
1869     // abgeleitete Views zum Zuge kommen lassen
1870     WriteDragServerInfo( rPosPixel, &aDDInfo );
1871 
1872     pContainer->CopyAnyData( SOT_FORMATSTR_ID_TREELISTBOX,
1873                         (sal_Char*)&aDDInfo, sizeof(SvLBoxDDInfo) );
1874     pDDSource = this;
1875     pDDTarget = 0;
1876 
1877     sal_Bool bOldUpdateMode = Control::IsUpdateMode();
1878     Control::SetUpdateMode( sal_True );
1879     Update();
1880     Control::SetUpdateMode( bOldUpdateMode );
1881 
1882     // Selektion & deren Childs im Model als DropTargets sperren
1883     // Wichtig: Wenn im DropHandler die Selektion der
1884     // SourceListBox veraendert wird, muessen vorher die Eintraege
1885     // als DropTargets wieder freigeschaltet werden:
1886     // (GetSourceListBox()->EnableSelectionAsDropTarget( sal_True, sal_True );)
1887     EnableSelectionAsDropTarget( sal_False, sal_True /* with Childs */ );
1888 
1889     pContainer->StartDrag( this, nDragOptions, GetDragFinishedHdl() );
1890 }
1891 
1892 void SvLBox::DragFinished( sal_Int8
1893 #ifndef UNX
1894 nAction
1895 #endif
1896 )
1897 {
1898     EnableSelectionAsDropTarget( sal_True, sal_True );
1899 
1900 #ifndef UNX
1901     if( (nAction == DND_ACTION_MOVE) && ( (pDDTarget &&
1902         ((sal_uLong)(pDDTarget->GetModel())!=(sal_uLong)(this->GetModel()))) ||
1903         !pDDTarget ))
1904     {
1905         RemoveSelection();
1906     }
1907 #endif
1908 
1909     ImplShowTargetEmphasis( pTargetEntry, sal_False );
1910     pDDSource = 0;
1911     pDDTarget = 0;
1912     pTargetEntry = 0;
1913     nDragDropMode = nOldDragMode;
1914 }
1915 
1916 DragDropMode SvLBox::NotifyStartDrag( TransferDataContainer&, SvLBoxEntry* )
1917 {
1918     DBG_CHKTHIS(SvLBox,0);
1919     return (DragDropMode)0xffff;
1920 }
1921 
1922 sal_Bool SvLBox::NotifyAcceptDrop( SvLBoxEntry* )
1923 {
1924     DBG_CHKTHIS(SvLBox,0);
1925     return sal_True;
1926 }
1927 
1928 // handler and methods for Drag - finished handler.
1929 // The with get GetDragFinishedHdl() get link can set on the
1930 // TransferDataContainer. This link is a callback for the DragFinished
1931 // call. AddBox method is called from the GetDragFinishedHdl() and the
1932 // remove is called in link callback and in the destructor. So it can't
1933 // called to a deleted object.
1934 
1935 namespace
1936 {
1937     struct SortLBoxes : public rtl::Static<SvULongsSort, SortLBoxes> {};
1938 }
1939 
1940 void SvLBox::AddBoxToDDList_Impl( const SvLBox& rB )
1941 {
1942     sal_uLong nVal = (sal_uLong)&rB;
1943     SortLBoxes::get().Insert( nVal );
1944 }
1945 
1946 void SvLBox::RemoveBoxFromDDList_Impl( const SvLBox& rB )
1947 {
1948     sal_uLong nVal = (sal_uLong)&rB;
1949     SortLBoxes::get().Remove( nVal );
1950 }
1951 
1952 IMPL_STATIC_LINK( SvLBox, DragFinishHdl_Impl, sal_Int8*, pAction )
1953 {
1954     sal_uLong nVal = (sal_uLong)pThis;
1955     sal_uInt16 nFnd;
1956     SvULongsSort &rSortLBoxes = SortLBoxes::get();
1957     if( rSortLBoxes.Seek_Entry( nVal, &nFnd ) )
1958     {
1959         pThis->DragFinished( *pAction );
1960         rSortLBoxes.Remove( nFnd, 1 );
1961     }
1962     return 0;
1963 }
1964 
1965 Link SvLBox::GetDragFinishedHdl() const
1966 {
1967     AddBoxToDDList_Impl( *this );
1968     return STATIC_LINK( this, SvLBox, DragFinishHdl_Impl );
1969 }
1970 
1971 void SvLBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& ) const
1972 {
1973 }
1974 
1975 ::com::sun::star::uno::Reference< XAccessible > SvLBox::CreateAccessible()
1976 {
1977     return ::com::sun::star::uno::Reference< XAccessible >();
1978 }
1979 
1980 Rectangle SvLBox::GetBoundingRect( SvLBoxEntry* )
1981 {
1982     return Rectangle();
1983 }
1984 
1985