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