xref: /trunk/main/svtools/source/contnr/svlbox.cxx (revision 5900e8ec)
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