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