Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : /*
21 : TODO:
22 : - delete anchor in SelectionEngine when selecting manually
23 : - SelectAll( false ) => only repaint the delselected entries
24 : */
25 :
26 : #include <svtools/treelistbox.hxx>
27 : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 : #include <vcl/svapp.hxx>
29 : #include <vcl/accel.hxx>
30 : #include <vcl/i18nhelp.hxx>
31 : #include <vcl/builder.hxx>
32 : #include <vcl/settings.hxx>
33 : #include <sot/formats.hxx>
34 : #include <unotools/accessiblestatesethelper.hxx>
35 : #include <rtl/instance.hxx>
36 : #include <comphelper/string.hxx>
37 :
38 : #include <svtools/svmedit.hxx>
39 : #include <svtools/svlbitm.hxx>
40 : #include "svtools/treelistentry.hxx"
41 : #include "svtools/viewdataentry.hxx"
42 : #include "svimpbox.hxx"
43 :
44 : #include <set>
45 : #include <string.h>
46 : #include <vector>
47 :
48 : using namespace ::com::sun::star::accessibility;
49 :
50 : // Drag&Drop
51 : static SvTreeListBox* pDDSource = NULL;
52 : static SvTreeListBox* pDDTarget = NULL;
53 :
54 :
55 : #define SVLBOX_ACC_RETURN 1
56 : #define SVLBOX_ACC_ESCAPE 2
57 :
58 : // ***************************************************************
59 :
60 0 : class MyEdit_Impl : public Edit
61 : {
62 : SvInplaceEdit2* pOwner;
63 : public:
64 : MyEdit_Impl( Window* pParent, SvInplaceEdit2* pOwner );
65 : virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
66 : virtual void LoseFocus() SAL_OVERRIDE;
67 : };
68 :
69 0 : class MyMultiEdit_Impl : public MultiLineEdit
70 : {
71 : SvInplaceEdit2* pOwner;
72 : public:
73 : MyMultiEdit_Impl( Window* pParent, SvInplaceEdit2* pOwner );
74 : virtual void KeyInput( const KeyEvent& rKEvt ) SAL_OVERRIDE;
75 : virtual void LoseFocus() SAL_OVERRIDE;
76 : };
77 :
78 0 : MyEdit_Impl::MyEdit_Impl( Window* pParent, SvInplaceEdit2* _pOwner ) :
79 :
80 : Edit( pParent, WB_LEFT ),
81 :
82 0 : pOwner( _pOwner )
83 :
84 : {
85 0 : }
86 :
87 0 : void MyEdit_Impl::KeyInput( const KeyEvent& rKEvt )
88 : {
89 0 : if( !pOwner->KeyInput( rKEvt ))
90 0 : Edit::KeyInput( rKEvt );
91 0 : }
92 :
93 0 : void MyEdit_Impl::LoseFocus()
94 : {
95 0 : pOwner->LoseFocus();
96 0 : }
97 :
98 0 : MyMultiEdit_Impl::MyMultiEdit_Impl( Window* pParent, SvInplaceEdit2* _pOwner )
99 : : MultiLineEdit( pParent,
100 : WB_CENTER
101 0 : ), pOwner(_pOwner)
102 : {
103 0 : }
104 :
105 0 : void MyMultiEdit_Impl::KeyInput( const KeyEvent& rKEvt )
106 : {
107 0 : if( !pOwner->KeyInput( rKEvt ))
108 0 : MultiLineEdit::KeyInput( rKEvt );
109 0 : }
110 :
111 0 : void MyMultiEdit_Impl::LoseFocus()
112 : {
113 0 : pOwner->LoseFocus();
114 0 : }
115 :
116 :
117 0 : SvInplaceEdit2::SvInplaceEdit2
118 : (
119 : Window* pParent, const Point& rPos,
120 : const Size& rSize,
121 : const OUString& rData,
122 : const Link& rNotifyEditEnd,
123 : const Selection& rSelection,
124 : bool bMulti
125 : ) :
126 :
127 : aCallBackHdl ( rNotifyEditEnd ),
128 : bCanceled ( false ),
129 0 : bAlreadyInCallBack ( false )
130 :
131 : {
132 :
133 0 : if( bMulti )
134 0 : pEdit = new MyMultiEdit_Impl( pParent, this );
135 : else
136 0 : pEdit = new MyEdit_Impl( pParent, this );
137 :
138 0 : Font aFont( pParent->GetFont() );
139 0 : aFont.SetTransparent( false );
140 0 : Color aColor( pParent->GetBackground().GetColor() );
141 0 : aFont.SetFillColor(aColor );
142 0 : pEdit->SetFont( aFont );
143 0 : pEdit->SetBackground( pParent->GetBackground() );
144 0 : pEdit->SetPosPixel( rPos );
145 0 : pEdit->SetSizePixel( rSize );
146 0 : pEdit->SetText( rData );
147 0 : pEdit->SetSelection( rSelection );
148 0 : pEdit->SaveValue();
149 :
150 0 : aAccReturn.InsertItem( SVLBOX_ACC_RETURN, KeyCode(KEY_RETURN) );
151 0 : aAccEscape.InsertItem( SVLBOX_ACC_ESCAPE, KeyCode(KEY_ESCAPE) );
152 :
153 0 : aAccReturn.SetActivateHdl( LINK( this, SvInplaceEdit2, ReturnHdl_Impl) );
154 0 : aAccEscape.SetActivateHdl( LINK( this, SvInplaceEdit2, EscapeHdl_Impl) );
155 0 : GetpApp()->InsertAccel( &aAccReturn );
156 0 : GetpApp()->InsertAccel( &aAccEscape );
157 :
158 0 : pEdit->Show();
159 0 : pEdit->GrabFocus();
160 0 : }
161 :
162 0 : SvInplaceEdit2::~SvInplaceEdit2()
163 : {
164 0 : if( !bAlreadyInCallBack )
165 : {
166 0 : GetpApp()->RemoveAccel( &aAccReturn );
167 0 : GetpApp()->RemoveAccel( &aAccEscape );
168 : }
169 0 : delete pEdit;
170 0 : }
171 :
172 0 : OUString SvInplaceEdit2::GetSavedValue() const
173 : {
174 0 : return pEdit->GetSavedValue();
175 : }
176 :
177 0 : void SvInplaceEdit2::Hide()
178 : {
179 0 : pEdit->Hide();
180 0 : }
181 :
182 :
183 0 : IMPL_LINK_NOARG_INLINE_START(SvInplaceEdit2, ReturnHdl_Impl)
184 : {
185 0 : bCanceled = false;
186 0 : CallCallBackHdl_Impl();
187 0 : return 1;
188 : }
189 0 : IMPL_LINK_NOARG_INLINE_END(SvInplaceEdit2, ReturnHdl_Impl)
190 :
191 0 : IMPL_LINK_NOARG_INLINE_START(SvInplaceEdit2, EscapeHdl_Impl)
192 : {
193 0 : bCanceled = true;
194 0 : CallCallBackHdl_Impl();
195 0 : return 1;
196 : }
197 0 : IMPL_LINK_NOARG_INLINE_END(SvInplaceEdit2, EscapeHdl_Impl)
198 :
199 :
200 0 : bool SvInplaceEdit2::KeyInput( const KeyEvent& rKEvt )
201 : {
202 0 : KeyCode aCode = rKEvt.GetKeyCode();
203 0 : sal_uInt16 nCode = aCode.GetCode();
204 :
205 0 : switch ( nCode )
206 : {
207 : case KEY_ESCAPE:
208 0 : bCanceled = true;
209 0 : CallCallBackHdl_Impl();
210 0 : return true;
211 :
212 : case KEY_RETURN:
213 0 : bCanceled = false;
214 0 : CallCallBackHdl_Impl();
215 0 : return true;
216 : }
217 0 : return false;
218 : }
219 :
220 0 : void SvInplaceEdit2::StopEditing( bool bCancel )
221 : {
222 0 : if ( !bAlreadyInCallBack )
223 : {
224 0 : bCanceled = bCancel;
225 0 : CallCallBackHdl_Impl();
226 : }
227 0 : }
228 :
229 0 : void SvInplaceEdit2::LoseFocus()
230 : {
231 0 : if ( !bAlreadyInCallBack
232 0 : && ((!Application::GetFocusWindow()) || !pEdit->IsChild( Application::GetFocusWindow()) )
233 : )
234 : {
235 0 : bCanceled = false;
236 0 : aTimer.SetTimeout(10);
237 0 : aTimer.SetTimeoutHdl(LINK(this,SvInplaceEdit2,Timeout_Impl));
238 0 : aTimer.Start();
239 : }
240 0 : }
241 :
242 0 : IMPL_LINK_NOARG_INLINE_START(SvInplaceEdit2, Timeout_Impl)
243 : {
244 0 : CallCallBackHdl_Impl();
245 0 : return 0;
246 : }
247 0 : IMPL_LINK_NOARG_INLINE_END(SvInplaceEdit2, Timeout_Impl)
248 :
249 0 : void SvInplaceEdit2::CallCallBackHdl_Impl()
250 : {
251 0 : aTimer.Stop();
252 0 : if ( !bAlreadyInCallBack )
253 : {
254 0 : bAlreadyInCallBack = true;
255 0 : GetpApp()->RemoveAccel( &aAccReturn );
256 0 : GetpApp()->RemoveAccel( &aAccEscape );
257 0 : pEdit->Hide();
258 0 : aCallBackHdl.Call( this );
259 : }
260 0 : }
261 :
262 0 : OUString SvInplaceEdit2::GetText() const
263 : {
264 0 : return pEdit->GetText();
265 : }
266 :
267 : // ***************************************************************
268 : // class SvLBoxTab
269 : // ***************************************************************
270 :
271 :
272 0 : SvLBoxTab::SvLBoxTab()
273 : {
274 0 : nPos = 0;
275 0 : pUserData = 0;
276 0 : nFlags = 0;
277 0 : }
278 :
279 0 : SvLBoxTab::SvLBoxTab( long nPosition, sal_uInt16 nTabFlags )
280 : {
281 0 : nPos = nPosition;
282 0 : pUserData = 0;
283 0 : nFlags = nTabFlags;
284 0 : }
285 :
286 0 : SvLBoxTab::SvLBoxTab( const SvLBoxTab& rTab )
287 : {
288 0 : nPos = rTab.nPos;
289 0 : pUserData = rTab.pUserData;
290 0 : nFlags = rTab.nFlags;
291 0 : }
292 :
293 0 : SvLBoxTab::~SvLBoxTab()
294 : {
295 0 : }
296 :
297 :
298 0 : long SvLBoxTab::CalcOffset( long nItemWidth, long nTabWidth )
299 : {
300 0 : long nOffset = 0;
301 0 : if ( nFlags & SV_LBOXTAB_ADJUST_RIGHT )
302 : {
303 0 : nOffset = nTabWidth - nItemWidth;
304 0 : if( nOffset < 0 )
305 0 : nOffset = 0;
306 : }
307 0 : else if ( nFlags & SV_LBOXTAB_ADJUST_CENTER )
308 : {
309 0 : if( nFlags & SV_LBOXTAB_FORCE )
310 : {
311 : // correct implementation of centering
312 0 : nOffset = ( nTabWidth - nItemWidth ) / 2;
313 0 : if( nOffset < 0 )
314 0 : nOffset = 0;
315 : }
316 : else
317 : {
318 : // historically grown, wrong calculation of tabs which is needed by
319 : // Abo-Tabbox, Tools/Options/Customize etc.
320 0 : nItemWidth++;
321 0 : nOffset = -( nItemWidth / 2 );
322 : }
323 : }
324 0 : return nOffset;
325 : }
326 :
327 : // ***************************************************************
328 : // class SvLBoxItem
329 : // ***************************************************************
330 :
331 :
332 0 : SvLBoxItem::SvLBoxItem( SvTreeListEntry*, sal_uInt16 )
333 : {
334 0 : }
335 :
336 0 : SvLBoxItem::SvLBoxItem()
337 : {
338 0 : }
339 :
340 0 : SvLBoxItem::~SvLBoxItem()
341 : {
342 0 : }
343 :
344 0 : const Size& SvLBoxItem::GetSize(const SvTreeListBox* pView, const SvTreeListEntry* pEntry) const
345 : {
346 0 : const SvViewDataItem* pViewData = pView->GetViewDataItem( pEntry, this );
347 0 : return pViewData->maSize;
348 : }
349 :
350 0 : const Size& SvLBoxItem::GetSize(const SvViewDataEntry* pData, sal_uInt16 nItemPos) const
351 : {
352 0 : const SvViewDataItem* pIData = pData->GetItem(nItemPos);
353 0 : return pIData->maSize;
354 : }
355 :
356 0 : struct SvTreeListBoxImpl
357 : {
358 : bool m_bIsEmptyTextAllowed:1;
359 : bool m_bEntryMnemonicsEnabled:1;
360 : bool m_bDoingQuickSelection:1;
361 :
362 : Link* m_pLink;
363 :
364 : vcl::MnemonicEngine m_aMnemonicEngine;
365 : vcl::QuickSelectionEngine m_aQuickSelectionEngine;
366 :
367 0 : SvTreeListBoxImpl(SvTreeListBox& _rBox) :
368 : m_bIsEmptyTextAllowed(true),
369 : m_bEntryMnemonicsEnabled(false),
370 : m_bDoingQuickSelection(false),
371 : m_pLink(NULL),
372 : m_aMnemonicEngine(_rBox),
373 0 : m_aQuickSelectionEngine(_rBox) {}
374 : };
375 :
376 :
377 0 : SvTreeListBox::SvTreeListBox(Window* pParent, WinBits nWinStyle) :
378 : Control(pParent, nWinStyle | WB_CLIPCHILDREN),
379 : DropTargetHelper(this),
380 : DragSourceHelper(this),
381 0 : mpImpl(new SvTreeListBoxImpl(*this)),
382 : mbContextBmpExpanded(false),
383 : eSelMode(NO_SELECTION),
384 0 : nMinWidthInChars(0)
385 : {
386 0 : nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK;
387 0 : nImpFlags = 0;
388 0 : pTargetEntry = 0;
389 0 : nDragDropMode = 0;
390 0 : SvTreeList* pTempModel = new SvTreeList;
391 0 : pTempModel->SetRefCount( 0 );
392 0 : SetBaseModel(pTempModel);
393 0 : pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
394 0 : pModel->InsertView( this );
395 0 : pHdlEntry = 0;
396 0 : pEdCtrl = 0;
397 0 : eSelMode = SINGLE_SELECTION;
398 0 : nDragDropMode = SV_DRAGDROP_NONE;
399 0 : SetType(WINDOW_TREELISTBOX);
400 :
401 0 : InitTreeView();
402 :
403 0 : SetSublistOpenWithLeftRight();
404 0 : }
405 :
406 0 : SvTreeListBox::SvTreeListBox(Window* pParent, const ResId& rResId) :
407 : Control(pParent, rResId),
408 : DropTargetHelper(this),
409 : DragSourceHelper(this),
410 0 : mpImpl(new SvTreeListBoxImpl(*this)),
411 : mbContextBmpExpanded(false),
412 : eSelMode(NO_SELECTION),
413 0 : nMinWidthInChars(0)
414 : {
415 0 : pTargetEntry = 0;
416 0 : nImpFlags = 0;
417 0 : nDragOptions = DND_ACTION_COPYMOVE | DND_ACTION_LINK;
418 0 : nDragDropMode = 0;
419 0 : SvTreeList* pTempModel = new SvTreeList;
420 0 : pTempModel->SetRefCount( 0 );
421 0 : SetBaseModel(pTempModel);
422 0 : pModel->InsertView( this );
423 0 : pHdlEntry = 0;
424 0 : pEdCtrl = 0;
425 0 : pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
426 0 : SetType(WINDOW_TREELISTBOX);
427 :
428 0 : InitTreeView();
429 0 : Resize();
430 :
431 0 : SetSublistOpenWithLeftRight();
432 0 : }
433 :
434 0 : extern "C" SAL_DLLPUBLIC_EXPORT Window* SAL_CALL makeSvTreeListBox(Window *pParent, VclBuilder::stringmap &rMap)
435 : {
436 0 : WinBits nWinStyle = WB_TABSTOP;
437 0 : OString sBorder = VclBuilder::extractCustomProperty(rMap);
438 0 : if (!sBorder.isEmpty())
439 0 : nWinStyle |= WB_BORDER;
440 0 : return new SvTreeListBox(pParent, nWinStyle);
441 : }
442 :
443 0 : void SvTreeListBox::Clear()
444 : {
445 0 : pModel->Clear(); // Model calls SvTreeListBox::ModelHasCleared()
446 0 : }
447 :
448 0 : void SvTreeListBox::EnableEntryMnemonics( bool _bEnable )
449 : {
450 0 : if ( _bEnable == IsEntryMnemonicsEnabled() )
451 0 : return;
452 :
453 0 : mpImpl->m_bEntryMnemonicsEnabled = _bEnable;
454 0 : Invalidate();
455 : }
456 :
457 0 : bool SvTreeListBox::IsEntryMnemonicsEnabled() const
458 : {
459 0 : return mpImpl->m_bEntryMnemonicsEnabled;
460 : }
461 :
462 0 : IMPL_LINK_INLINE_START( SvTreeListBox, CloneHdl_Impl, SvTreeListEntry*, pEntry )
463 : {
464 0 : return (sal_IntPtr)(CloneEntry((SvTreeListEntry*)pEntry));
465 : }
466 0 : IMPL_LINK_INLINE_END( SvTreeListBox, CloneHdl_Impl, SvTreeListEntry*, pEntry )
467 :
468 0 : sal_uLong SvTreeListBox::Insert( SvTreeListEntry* pEntry, SvTreeListEntry* pParent, sal_uLong nPos )
469 : {
470 0 : sal_uLong nInsPos = pModel->Insert( pEntry, pParent, nPos );
471 0 : return nInsPos;
472 : }
473 :
474 0 : sal_uLong SvTreeListBox::Insert( SvTreeListEntry* pEntry,sal_uLong nRootPos )
475 : {
476 0 : sal_uLong nInsPos = pModel->Insert( pEntry, nRootPos );
477 0 : return nInsPos;
478 : }
479 :
480 0 : bool SvTreeListBox::ExpandingHdl()
481 : {
482 0 : return !aExpandingHdl.IsSet() || aExpandingHdl.Call( this );
483 : }
484 :
485 0 : void SvTreeListBox::ExpandedHdl()
486 : {
487 0 : aExpandedHdl.Call( this );
488 0 : }
489 :
490 0 : void SvTreeListBox::SelectHdl()
491 : {
492 0 : aSelectHdl.Call( this );
493 0 : }
494 :
495 0 : void SvTreeListBox::DeselectHdl()
496 : {
497 0 : aDeselectHdl.Call( this );
498 0 : }
499 :
500 0 : bool SvTreeListBox::DoubleClickHdl()
501 : {
502 0 : aDoubleClickHdl.Call( this );
503 0 : return true;
504 : }
505 :
506 :
507 0 : bool SvTreeListBox::CheckDragAndDropMode( SvTreeListBox* pSource, sal_Int8 nAction )
508 : {
509 0 : if ( pSource == this )
510 : {
511 0 : if ( !(nDragDropMode & (SV_DRAGDROP_CTRL_MOVE | SV_DRAGDROP_CTRL_COPY) ) )
512 0 : return false; // D&D locked within list
513 0 : if( DND_ACTION_MOVE == nAction )
514 : {
515 0 : if ( !(nDragDropMode & SV_DRAGDROP_CTRL_MOVE) )
516 0 : return false; // no local move
517 : }
518 : else
519 : {
520 0 : if ( !(nDragDropMode & SV_DRAGDROP_CTRL_COPY))
521 0 : return false; // no local copy
522 : }
523 : }
524 : else
525 : {
526 0 : if ( !(nDragDropMode & SV_DRAGDROP_APP_DROP ) )
527 0 : return false; // no drop
528 0 : if ( DND_ACTION_MOVE == nAction )
529 : {
530 0 : if ( !(nDragDropMode & SV_DRAGDROP_APP_MOVE) )
531 0 : return false; // no global move
532 : }
533 : else
534 : {
535 0 : if ( !(nDragDropMode & SV_DRAGDROP_APP_COPY))
536 0 : return false; // no global copy
537 : }
538 : }
539 0 : return true;
540 : }
541 :
542 :
543 :
544 :
545 0 : void SvTreeListBox::NotifyRemoving( SvTreeListEntry* )
546 : {
547 0 : }
548 :
549 : /*
550 : NotifyMoving/Copying
551 : ====================
552 :
553 : default behavior:
554 :
555 : 1. target doesn't have children
556 : - entry becomes sibling of target. entry comes after target
557 : (->Window: below the target)
558 : 2. target is an expanded parent
559 : - entry inserted at the beginning of the target childlist
560 : 3. target is a collapsed parent
561 : - entry is inserted at the end of the target childlist
562 : */
563 : #ifdef DBG_UTIL
564 : TriState SvTreeListBox::NotifyMoving(
565 : SvTreeListEntry* pTarget, // D&D dropping position in this->GetModel()
566 : SvTreeListEntry* pEntry, // entry that we want to move, from
567 : // GetSourceListBox()->GetModel()
568 : SvTreeListEntry*& rpNewParent, // new target parent
569 : sal_uLong& rNewChildPos) // position in childlist of target parent
570 : #else
571 0 : TriState SvTreeListBox::NotifyMoving(
572 : SvTreeListEntry* pTarget, // D&D dropping position in this->GetModel()
573 : SvTreeListEntry*, // entry that we want to move, from
574 : // GetSourceListBox()->GetModel()
575 : SvTreeListEntry*& rpNewParent, // new target parent
576 : sal_uLong& rNewChildPos) // position in childlist of target parent
577 : #endif
578 : {
579 : DBG_ASSERT(pEntry,"NotifyMoving:SoureEntry?");
580 0 : if( !pTarget )
581 : {
582 0 : rpNewParent = 0;
583 0 : rNewChildPos = 0;
584 0 : return TRISTATE_TRUE;
585 : }
586 0 : if ( !pTarget->HasChildren() && !pTarget->HasChildrenOnDemand() )
587 : {
588 : // case 1
589 0 : rpNewParent = GetParent( pTarget );
590 0 : rNewChildPos = pModel->GetRelPos( pTarget ) + 1;
591 0 : rNewChildPos += nCurEntrySelPos;
592 0 : nCurEntrySelPos++;
593 : }
594 : else
595 : {
596 : // cases 2 & 3
597 0 : rpNewParent = pTarget;
598 0 : if( IsExpanded(pTarget))
599 0 : rNewChildPos = 0;
600 : else
601 0 : rNewChildPos = TREELIST_APPEND;
602 : }
603 0 : return TRISTATE_TRUE;
604 : }
605 :
606 0 : TriState SvTreeListBox::NotifyCopying(
607 : SvTreeListEntry* pTarget, // D&D dropping position in this->GetModel()
608 : SvTreeListEntry* pEntry, // entry that we want to move, from
609 : // GetSourceListBox()->GetModel()
610 : SvTreeListEntry*& rpNewParent, // new target parent
611 : sal_uLong& rNewChildPos) // position in childlist of target parent
612 : {
613 0 : return NotifyMoving(pTarget,pEntry,rpNewParent,rNewChildPos);
614 : }
615 :
616 0 : SvTreeListEntry* SvTreeListBox::FirstChild( SvTreeListEntry* pParent ) const
617 : {
618 0 : return pModel->FirstChild(pParent);
619 : }
620 :
621 0 : SvTreeListEntry* SvTreeListBox::NextSibling( SvTreeListEntry* pEntry ) const
622 : {
623 0 : return pModel->NextSibling(pEntry);
624 : }
625 :
626 0 : SvTreeListEntry* SvTreeListBox::PrevSibling( SvTreeListEntry* pEntry ) const
627 : {
628 0 : return pModel->PrevSibling(pEntry);
629 : }
630 :
631 : // return: all entries copied
632 0 : bool SvTreeListBox::CopySelection( SvTreeListBox* pSource, SvTreeListEntry* pTarget )
633 : {
634 0 : nCurEntrySelPos = 0; // selection counter for NotifyMoving/Copying
635 0 : bool bSuccess = true;
636 0 : std::vector<SvTreeListEntry*> aList;
637 0 : bool bClone = ( (sal_uLong)(pSource->GetModel()) != (sal_uLong)GetModel() );
638 0 : Link aCloneLink( pModel->GetCloneLink() );
639 0 : pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
640 :
641 : // cache selection to simplify iterating over the selection when doing a D&D
642 : // exchange within the same listbox
643 0 : SvTreeListEntry* pSourceEntry = pSource->FirstSelected();
644 0 : while ( pSourceEntry )
645 : {
646 : // children are copied automatically
647 0 : pSource->SelectChildren( pSourceEntry, false );
648 0 : aList.push_back( pSourceEntry );
649 0 : pSourceEntry = pSource->NextSelected( pSourceEntry );
650 : }
651 :
652 0 : std::vector<SvTreeListEntry*>::const_iterator it = aList.begin(), itEnd = aList.end();
653 0 : for (; it != itEnd; ++it)
654 : {
655 0 : pSourceEntry = *it;
656 0 : SvTreeListEntry* pNewParent = 0;
657 0 : sal_uLong nInsertionPos = TREELIST_APPEND;
658 0 : TriState nOk = NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos);
659 0 : if ( nOk )
660 : {
661 0 : if ( bClone )
662 : {
663 0 : sal_uLong nCloneCount = 0;
664 0 : pSourceEntry = pModel->Clone(pSourceEntry, nCloneCount);
665 0 : pModel->InsertTree(pSourceEntry, pNewParent, nInsertionPos);
666 : }
667 : else
668 : {
669 0 : sal_uLong nListPos = pModel->Copy(pSourceEntry, pNewParent, nInsertionPos);
670 0 : pSourceEntry = GetEntry( pNewParent, nListPos );
671 : }
672 : }
673 : else
674 0 : bSuccess = false;
675 :
676 0 : if (nOk == TRISTATE_INDET) // HACK: make visible moved entry
677 0 : MakeVisible( pSourceEntry );
678 : }
679 0 : pModel->SetCloneLink( aCloneLink );
680 0 : return bSuccess;
681 : }
682 :
683 : // return: all entries were moved
684 0 : bool SvTreeListBox::MoveSelection( SvTreeListBox* pSource, SvTreeListEntry* pTarget )
685 : {
686 0 : return MoveSelectionCopyFallbackPossible( pSource, pTarget, false );
687 : }
688 :
689 0 : bool SvTreeListBox::MoveSelectionCopyFallbackPossible( SvTreeListBox* pSource, SvTreeListEntry* pTarget, bool bAllowCopyFallback )
690 : {
691 0 : nCurEntrySelPos = 0; // selection counter for NotifyMoving/Copying
692 0 : bool bSuccess = true;
693 0 : std::vector<SvTreeListEntry*> aList;
694 0 : bool bClone = ( (sal_uLong)(pSource->GetModel()) != (sal_uLong)GetModel() );
695 0 : Link aCloneLink( pModel->GetCloneLink() );
696 0 : if ( bClone )
697 0 : pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
698 :
699 0 : SvTreeListEntry* pSourceEntry = pSource->FirstSelected();
700 0 : while ( pSourceEntry )
701 : {
702 : // children are automatically moved
703 0 : pSource->SelectChildren( pSourceEntry, false );
704 0 : aList.push_back( pSourceEntry );
705 0 : pSourceEntry = pSource->NextSelected( pSourceEntry );
706 : }
707 :
708 0 : std::vector<SvTreeListEntry*>::const_iterator it = aList.begin(), itEnd = aList.end();
709 0 : for (; it != itEnd; ++it)
710 : {
711 0 : pSourceEntry = *it;
712 :
713 0 : SvTreeListEntry* pNewParent = 0;
714 0 : sal_uLong nInsertionPos = TREELIST_APPEND;
715 0 : TriState nOk = NotifyMoving(pTarget,pSourceEntry,pNewParent,nInsertionPos);
716 0 : TriState nCopyOk = nOk;
717 0 : if ( !nOk && bAllowCopyFallback )
718 : {
719 0 : nInsertionPos = TREELIST_APPEND;
720 0 : nCopyOk = NotifyCopying(pTarget,pSourceEntry,pNewParent,nInsertionPos);
721 : }
722 :
723 0 : if ( nOk || nCopyOk )
724 : {
725 0 : if ( bClone )
726 : {
727 0 : sal_uLong nCloneCount = 0;
728 0 : pSourceEntry = pModel->Clone(pSourceEntry, nCloneCount);
729 0 : pModel->InsertTree(pSourceEntry, pNewParent, nInsertionPos);
730 : }
731 : else
732 : {
733 0 : if ( nOk )
734 0 : pModel->Move(pSourceEntry, pNewParent, nInsertionPos);
735 : else
736 0 : pModel->Copy(pSourceEntry, pNewParent, nInsertionPos);
737 0 : }
738 : }
739 : else
740 0 : bSuccess = false;
741 :
742 0 : if (nOk == TRISTATE_INDET) // HACK: make moved entry visible
743 0 : MakeVisible( pSourceEntry );
744 : }
745 0 : pModel->SetCloneLink( aCloneLink );
746 0 : return bSuccess;
747 : }
748 :
749 0 : void SvTreeListBox::RemoveSelection()
750 : {
751 0 : std::vector<const SvTreeListEntry*> aList;
752 : // cache selection, as the implementation deselects everything on the first
753 : // remove
754 0 : SvTreeListEntry* pEntry = FirstSelected();
755 0 : while ( pEntry )
756 : {
757 0 : aList.push_back( pEntry );
758 0 : if ( pEntry->HasChildren() )
759 : // remove deletes all children automatically
760 0 : SelectChildren(pEntry, false);
761 0 : pEntry = NextSelected( pEntry );
762 : }
763 :
764 0 : std::vector<const SvTreeListEntry*>::const_iterator it = aList.begin(), itEnd = aList.end();
765 0 : for (; it != itEnd; ++it)
766 0 : pModel->Remove(*it);
767 0 : }
768 :
769 0 : SvTreeListBox* SvTreeListBox::GetSourceView() const
770 : {
771 0 : return pDDSource;
772 : }
773 :
774 0 : void SvTreeListBox::RecalcViewData()
775 : {
776 0 : SvTreeListEntry* pEntry = First();
777 0 : while( pEntry )
778 : {
779 0 : sal_uInt16 nCount = pEntry->ItemCount();
780 0 : sal_uInt16 nCurPos = 0;
781 0 : while ( nCurPos < nCount )
782 : {
783 0 : SvLBoxItem* pItem = pEntry->GetItem( nCurPos );
784 0 : pItem->InitViewData( this, pEntry );
785 0 : nCurPos++;
786 : }
787 0 : ViewDataInitialized( pEntry );
788 0 : pEntry = Next( pEntry );
789 : }
790 0 : }
791 :
792 0 : void SvTreeListBox::ViewDataInitialized( SvTreeListEntry* )
793 : {
794 0 : }
795 :
796 0 : void SvTreeListBox::ImplShowTargetEmphasis( SvTreeListEntry* pEntry, bool bShow)
797 : {
798 0 : if ( bShow && (nImpFlags & SVLBOX_TARGEMPH_VIS) )
799 0 : return;
800 0 : if ( !bShow && !(nImpFlags & SVLBOX_TARGEMPH_VIS) )
801 0 : return;
802 0 : ShowTargetEmphasis( pEntry, bShow );
803 0 : if( bShow )
804 0 : nImpFlags |= SVLBOX_TARGEMPH_VIS;
805 : else
806 0 : nImpFlags &= ~SVLBOX_TARGEMPH_VIS;
807 : }
808 :
809 0 : void SvTreeListBox::OnCurrentEntryChanged()
810 : {
811 0 : if ( !mpImpl->m_bDoingQuickSelection )
812 0 : mpImpl->m_aQuickSelectionEngine.Reset();
813 0 : }
814 :
815 0 : SvTreeListEntry* SvTreeListBox::GetEntry( SvTreeListEntry* pParent, sal_uLong nPos ) const
816 : {
817 0 : return pModel->GetEntry(pParent, nPos);
818 : }
819 :
820 0 : SvTreeListEntry* SvTreeListBox::GetEntry( sal_uLong nRootPos ) const
821 : {
822 0 : return pModel->GetEntry(nRootPos);
823 : }
824 :
825 0 : SvTreeListEntry* SvTreeListBox::GetEntryFromPath( const ::std::deque< sal_Int32 >& _rPath ) const
826 : {
827 :
828 0 : SvTreeListEntry* pEntry = NULL;
829 0 : SvTreeListEntry* pParent = NULL;
830 0 : for( ::std::deque< sal_Int32 >::const_iterator pItem = _rPath.begin(); pItem != _rPath.end(); ++pItem )
831 : {
832 0 : pEntry = GetEntry( pParent, *pItem );
833 0 : if ( !pEntry )
834 0 : break;
835 0 : pParent = pEntry;
836 : }
837 :
838 0 : return pEntry;
839 : }
840 :
841 0 : void SvTreeListBox::FillEntryPath( SvTreeListEntry* pEntry, ::std::deque< sal_Int32 >& _rPath ) const
842 : {
843 :
844 0 : if ( pEntry )
845 : {
846 0 : SvTreeListEntry* pParentEntry = GetParent( pEntry );
847 : while ( true )
848 : {
849 0 : sal_uLong i, nCount = GetLevelChildCount( pParentEntry );
850 0 : for ( i = 0; i < nCount; ++i )
851 : {
852 0 : SvTreeListEntry* pTemp = GetEntry( pParentEntry, i );
853 : DBG_ASSERT( pEntry, "invalid entry" );
854 0 : if ( pEntry == pTemp )
855 : {
856 0 : _rPath.push_front( (sal_Int32)i );
857 0 : break;
858 : }
859 : }
860 :
861 0 : if ( pParentEntry )
862 : {
863 0 : pEntry = pParentEntry;
864 0 : pParentEntry = GetParent( pParentEntry );
865 : }
866 : else
867 0 : break;
868 0 : }
869 : }
870 0 : }
871 :
872 0 : const SvTreeListEntry* SvTreeListBox::GetParent( const SvTreeListEntry* pEntry ) const
873 : {
874 0 : return pModel->GetParent(pEntry);
875 : }
876 :
877 0 : SvTreeListEntry* SvTreeListBox::GetParent( SvTreeListEntry* pEntry ) const
878 : {
879 0 : return pModel->GetParent(pEntry);
880 : }
881 :
882 0 : SvTreeListEntry* SvTreeListBox::GetRootLevelParent( SvTreeListEntry* pEntry ) const
883 : {
884 0 : return pModel->GetRootLevelParent(pEntry);
885 : }
886 :
887 0 : sal_uLong SvTreeListBox::GetChildCount( SvTreeListEntry* pParent ) const
888 : {
889 0 : return pModel->GetChildCount(pParent);
890 : }
891 :
892 0 : sal_uLong SvTreeListBox::GetLevelChildCount( SvTreeListEntry* _pParent ) const
893 : {
894 :
895 : //if _pParent is 0, then pEntry is the first child of the root.
896 0 : SvTreeListEntry* pEntry = FirstChild( _pParent );
897 :
898 0 : if( !pEntry )//there is only root, root don't have children
899 0 : return 0;
900 :
901 0 : if( !_pParent )//root and children of root
902 0 : return pEntry->pParent->maChildren.size();
903 :
904 0 : return _pParent->maChildren.size();
905 : }
906 :
907 0 : SvViewDataEntry* SvTreeListBox::GetViewDataEntry( SvTreeListEntry* pEntry ) const
908 : {
909 0 : return (SvViewDataEntry*)SvListView::GetViewData(pEntry);
910 : }
911 :
912 0 : SvViewDataItem* SvTreeListBox::GetViewDataItem(SvTreeListEntry* pEntry, SvLBoxItem* pItem)
913 : {
914 0 : return const_cast<SvViewDataItem*>(static_cast<const SvTreeListBox*>(this)->GetViewDataItem(pEntry, pItem));
915 : }
916 :
917 0 : const SvViewDataItem* SvTreeListBox::GetViewDataItem(const SvTreeListEntry* pEntry, const SvLBoxItem* pItem) const
918 : {
919 0 : const SvViewDataEntry* pEntryData = (const SvViewDataEntry*)SvListView::GetViewData(pEntry);
920 : DBG_ASSERT(pEntryData,"Entry not in View");
921 0 : sal_uInt16 nItemPos = pEntry->GetPos(pItem);
922 0 : return pEntryData->GetItem(nItemPos);
923 : }
924 :
925 0 : SvViewDataEntry* SvTreeListBox::CreateViewData( SvTreeListEntry* )
926 : {
927 0 : SvViewDataEntry* pEntryData = new SvViewDataEntry;
928 0 : return (SvViewDataEntry*)pEntryData;
929 : }
930 :
931 0 : void SvTreeListBox::InitViewData( SvViewDataEntry* pData, SvTreeListEntry* pEntry )
932 : {
933 0 : SvTreeListEntry* pInhEntry = (SvTreeListEntry*)pEntry;
934 0 : SvViewDataEntry* pEntryData = (SvViewDataEntry*)pData;
935 :
936 0 : pEntryData->Init(pInhEntry->ItemCount());
937 0 : sal_uInt16 nCount = pInhEntry->ItemCount();
938 0 : sal_uInt16 nCurPos = 0;
939 0 : while( nCurPos < nCount )
940 : {
941 0 : SvLBoxItem* pItem = pInhEntry->GetItem( nCurPos );
942 0 : SvViewDataItem* pItemData = pEntryData->GetItem(nCurPos);
943 0 : pItem->InitViewData( this, pInhEntry, pItemData );
944 0 : pItemData++;
945 0 : nCurPos++;
946 : }
947 0 : }
948 :
949 :
950 :
951 0 : void SvTreeListBox::EnableSelectionAsDropTarget( bool bEnable, bool bWithChildren )
952 : {
953 : sal_uInt16 nRefDepth;
954 : SvTreeListEntry* pTemp;
955 :
956 0 : SvTreeListEntry* pSelEntry = FirstSelected();
957 0 : while( pSelEntry )
958 : {
959 0 : if ( !bEnable )
960 : {
961 0 : pSelEntry->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP;
962 0 : if ( bWithChildren )
963 : {
964 0 : nRefDepth = pModel->GetDepth( pSelEntry );
965 0 : pTemp = Next( pSelEntry );
966 0 : while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth )
967 : {
968 0 : pTemp->nEntryFlags |= SV_ENTRYFLAG_DISABLE_DROP;
969 0 : pTemp = Next( pTemp );
970 : }
971 : }
972 : }
973 : else
974 : {
975 0 : pSelEntry->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP);
976 0 : if ( bWithChildren )
977 : {
978 0 : nRefDepth = pModel->GetDepth( pSelEntry );
979 0 : pTemp = Next( pSelEntry );
980 0 : while( pTemp && pModel->GetDepth( pTemp ) > nRefDepth )
981 : {
982 0 : pTemp->nEntryFlags &= (~SV_ENTRYFLAG_DISABLE_DROP);
983 0 : pTemp = Next( pTemp );
984 : }
985 : }
986 : }
987 0 : pSelEntry = NextSelected( pSelEntry );
988 : }
989 0 : }
990 :
991 : // ******************************************************************
992 : // InplaceEditing
993 : // ******************************************************************
994 :
995 0 : void SvTreeListBox::EditText( const OUString& rStr, const Rectangle& rRect,
996 : const Selection& rSel )
997 : {
998 0 : EditText( rStr, rRect, rSel, false );
999 0 : }
1000 :
1001 0 : void SvTreeListBox::EditText( const OUString& rStr, const Rectangle& rRect,
1002 : const Selection& rSel, bool bMulti )
1003 : {
1004 0 : if( pEdCtrl )
1005 0 : delete pEdCtrl;
1006 0 : nImpFlags |= SVLBOX_IN_EDT;
1007 0 : nImpFlags &= ~SVLBOX_EDTEND_CALLED;
1008 0 : HideFocus();
1009 : pEdCtrl = new SvInplaceEdit2(
1010 : this, rRect.TopLeft(), rRect.GetSize(), rStr,
1011 : LINK( this, SvTreeListBox, TextEditEndedHdl_Impl ),
1012 0 : rSel, bMulti );
1013 0 : }
1014 :
1015 0 : IMPL_LINK_NOARG(SvTreeListBox, TextEditEndedHdl_Impl)
1016 : {
1017 0 : if ( nImpFlags & SVLBOX_EDTEND_CALLED ) // avoid nesting
1018 0 : return 0;
1019 0 : nImpFlags |= SVLBOX_EDTEND_CALLED;
1020 0 : OUString aStr;
1021 0 : if ( !pEdCtrl->EditingCanceled() )
1022 0 : aStr = pEdCtrl->GetText();
1023 : else
1024 0 : aStr = pEdCtrl->GetSavedValue();
1025 0 : if ( IsEmptyTextAllowed() || !aStr.isEmpty() )
1026 0 : EditedText( aStr );
1027 : // Hide may only be called after the new text was put into the entry, so
1028 : // that we don't call the selection handler in the GetFocus of the listbox
1029 : // with the old entry text.
1030 0 : pEdCtrl->Hide();
1031 : // delete pEdCtrl;
1032 : // pEdCtrl = 0;
1033 0 : nImpFlags &= (~SVLBOX_IN_EDT);
1034 0 : GrabFocus();
1035 0 : return 0;
1036 : }
1037 :
1038 0 : void SvTreeListBox::CancelTextEditing()
1039 : {
1040 0 : if ( pEdCtrl )
1041 0 : pEdCtrl->StopEditing( true );
1042 0 : nImpFlags &= (~SVLBOX_IN_EDT);
1043 0 : }
1044 :
1045 0 : void SvTreeListBox::EndEditing( bool bCancel )
1046 : {
1047 0 : if( pEdCtrl )
1048 0 : pEdCtrl->StopEditing( bCancel );
1049 0 : nImpFlags &= (~SVLBOX_IN_EDT);
1050 0 : }
1051 :
1052 :
1053 0 : bool SvTreeListBox::IsEmptyTextAllowed() const
1054 : {
1055 0 : return mpImpl->m_bIsEmptyTextAllowed;
1056 : }
1057 :
1058 0 : void SvTreeListBox::ForbidEmptyText()
1059 : {
1060 0 : mpImpl->m_bIsEmptyTextAllowed = false;
1061 0 : }
1062 :
1063 0 : SvTreeListEntry* SvTreeListBox::CreateEntry() const
1064 : {
1065 0 : return new SvTreeListEntry;
1066 : }
1067 :
1068 0 : const void* SvTreeListBox::FirstSearchEntry( OUString& _rEntryText ) const
1069 : {
1070 0 : SvTreeListEntry* pEntry = GetCurEntry();
1071 0 : if ( pEntry )
1072 0 : pEntry = const_cast< SvTreeListEntry* >( static_cast< const SvTreeListEntry* >( NextSearchEntry( pEntry, _rEntryText ) ) );
1073 : else
1074 : {
1075 0 : pEntry = FirstSelected();
1076 0 : if ( !pEntry )
1077 0 : pEntry = First();
1078 : }
1079 :
1080 0 : if ( pEntry )
1081 0 : _rEntryText = GetEntryText( pEntry );
1082 :
1083 0 : return pEntry;
1084 : }
1085 :
1086 0 : const void* SvTreeListBox::NextSearchEntry( const void* _pCurrentSearchEntry, OUString& _rEntryText ) const
1087 : {
1088 0 : SvTreeListEntry* pEntry = const_cast< SvTreeListEntry* >( static_cast< const SvTreeListEntry* >( _pCurrentSearchEntry ) );
1089 :
1090 0 : if ( ( ( GetChildCount( pEntry ) > 0 )
1091 0 : || ( pEntry->HasChildrenOnDemand() )
1092 : )
1093 0 : && !IsExpanded( pEntry )
1094 : )
1095 : {
1096 0 : pEntry = NextSibling( pEntry );
1097 : }
1098 : else
1099 : {
1100 0 : pEntry = Next( pEntry );
1101 : }
1102 :
1103 0 : if ( !pEntry )
1104 0 : pEntry = First();
1105 :
1106 0 : if ( pEntry )
1107 0 : _rEntryText = GetEntryText( pEntry );
1108 :
1109 0 : return pEntry;
1110 : }
1111 :
1112 0 : void SvTreeListBox::SelectSearchEntry( const void* _pEntry )
1113 : {
1114 0 : SvTreeListEntry* pEntry = const_cast< SvTreeListEntry* >( static_cast< const SvTreeListEntry* >( _pEntry ) );
1115 : DBG_ASSERT( pEntry, "SvTreeListBox::SelectSearchEntry: invalid entry!" );
1116 0 : if ( !pEntry )
1117 0 : return;
1118 :
1119 0 : SelectAll( false );
1120 0 : SetCurEntry( pEntry );
1121 0 : Select( pEntry );
1122 : }
1123 :
1124 0 : void SvTreeListBox::ExecuteSearchEntry( const void* /*_pEntry*/ ) const
1125 : {
1126 : // nothing to do here, we have no "execution"
1127 0 : }
1128 :
1129 0 : ::vcl::StringEntryIdentifier SvTreeListBox::CurrentEntry( OUString& _out_entryText ) const
1130 : {
1131 : // always accept the current entry if there is one
1132 0 : SvTreeListEntry* pCurrentEntry( GetCurEntry() );
1133 0 : if ( pCurrentEntry )
1134 : {
1135 0 : _out_entryText = GetEntryText( pCurrentEntry );
1136 0 : return pCurrentEntry;
1137 : }
1138 0 : return FirstSearchEntry( _out_entryText );
1139 : }
1140 :
1141 0 : ::vcl::StringEntryIdentifier SvTreeListBox::NextEntry( ::vcl::StringEntryIdentifier _currentEntry, OUString& _out_entryText ) const
1142 : {
1143 0 : return NextSearchEntry( _currentEntry, _out_entryText );
1144 : }
1145 :
1146 0 : void SvTreeListBox::SelectEntry( ::vcl::StringEntryIdentifier _entry )
1147 : {
1148 0 : SelectSearchEntry( _entry );
1149 0 : }
1150 :
1151 0 : bool SvTreeListBox::HandleKeyInput( const KeyEvent& _rKEvt )
1152 : {
1153 0 : if ( IsEntryMnemonicsEnabled()
1154 0 : && mpImpl->m_aMnemonicEngine.HandleKeyEvent( _rKEvt )
1155 : )
1156 0 : return true;
1157 :
1158 0 : if ( ( GetStyle() & WB_QUICK_SEARCH ) != 0 )
1159 : {
1160 0 : mpImpl->m_bDoingQuickSelection = true;
1161 0 : const bool bHandled = mpImpl->m_aQuickSelectionEngine.HandleKeyEvent( _rKEvt );
1162 0 : mpImpl->m_bDoingQuickSelection = false;
1163 0 : if ( bHandled )
1164 0 : return true;
1165 : }
1166 :
1167 0 : return false;
1168 : }
1169 :
1170 0 : void SvTreeListBox::WriteDragServerInfo( const Point&, SvLBoxDDInfo* )
1171 : {
1172 0 : }
1173 :
1174 0 : void SvTreeListBox::ReadDragServerInfo(const Point&, SvLBoxDDInfo* )
1175 : {
1176 0 : }
1177 :
1178 0 : bool SvTreeListBox::EditingCanceled() const
1179 : {
1180 0 : if( pEdCtrl && pEdCtrl->EditingCanceled() )
1181 0 : return true;
1182 0 : return false;
1183 : }
1184 :
1185 :
1186 : //JP 28.3.2001: new Drag & Drop API
1187 0 : sal_Int8 SvTreeListBox::AcceptDrop( const AcceptDropEvent& rEvt )
1188 : {
1189 0 : sal_Int8 nRet = DND_ACTION_NONE;
1190 :
1191 0 : if( rEvt.mbLeaving || !CheckDragAndDropMode( pDDSource, rEvt.mnAction ) )
1192 : {
1193 0 : ImplShowTargetEmphasis( pTargetEntry, false );
1194 : }
1195 0 : else if( !nDragDropMode )
1196 : {
1197 : SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no target" );
1198 : }
1199 : else
1200 : {
1201 0 : SvTreeListEntry* pEntry = GetDropTarget( rEvt.maPosPixel );
1202 0 : if( !IsDropFormatSupported( SOT_FORMATSTR_ID_TREELISTBOX ) )
1203 : {
1204 : SAL_WARN( "svtools.contnr", "SvTreeListBox::QueryDrop(): no format" );
1205 : }
1206 : else
1207 : {
1208 : DBG_ASSERT( pDDSource, "SvTreeListBox::QueryDrop(): SourceBox == 0" );
1209 0 : if( !( pEntry && pDDSource->GetModel() == this->GetModel()
1210 0 : && DND_ACTION_MOVE == rEvt.mnAction
1211 0 : && ( pEntry->nEntryFlags & SV_ENTRYFLAG_DISABLE_DROP ) ))
1212 : {
1213 0 : if( NotifyAcceptDrop( pEntry ))
1214 0 : nRet = rEvt.mnAction;
1215 : }
1216 : }
1217 :
1218 : // **** draw emphasis ****
1219 0 : if( DND_ACTION_NONE == nRet )
1220 0 : ImplShowTargetEmphasis( pTargetEntry, false );
1221 0 : else if( pEntry != pTargetEntry || !(nImpFlags & SVLBOX_TARGEMPH_VIS) )
1222 : {
1223 0 : ImplShowTargetEmphasis( pTargetEntry, false );
1224 0 : pTargetEntry = pEntry;
1225 0 : ImplShowTargetEmphasis( pTargetEntry, true );
1226 : }
1227 : }
1228 0 : return nRet;
1229 : }
1230 :
1231 0 : sal_Int8 SvTreeListBox::ExecuteDrop( const ExecuteDropEvent& rEvt, SvTreeListBox* pSourceView )
1232 : {
1233 0 : sal_Int8 nRet = DND_ACTION_NONE;
1234 :
1235 : DBG_ASSERT( pSourceView, "SvTreeListBox::ExecuteDrop(): no source view" );
1236 0 : pSourceView->EnableSelectionAsDropTarget( true, true );
1237 :
1238 0 : ImplShowTargetEmphasis( pTargetEntry, false );
1239 0 : pDDTarget = this;
1240 :
1241 : SvLBoxDDInfo aDDInfo;
1242 :
1243 0 : TransferableDataHelper aData( rEvt.maDropEvent.Transferable );
1244 0 : if( aData.HasFormat( SOT_FORMATSTR_ID_TREELISTBOX ))
1245 : {
1246 0 : ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
1247 0 : if( aData.GetSequence( SOT_FORMATSTR_ID_TREELISTBOX, aSeq ) &&
1248 0 : sizeof(SvLBoxDDInfo) == aSeq.getLength() )
1249 : {
1250 0 : memcpy( &aDDInfo, aSeq.getConstArray(), sizeof(SvLBoxDDInfo) );
1251 0 : nRet = rEvt.mnAction;
1252 0 : }
1253 : }
1254 :
1255 0 : if( DND_ACTION_NONE != nRet )
1256 : {
1257 0 : nRet = DND_ACTION_NONE;
1258 :
1259 0 : ReadDragServerInfo( rEvt.maPosPixel, &aDDInfo );
1260 :
1261 0 : SvTreeListEntry* pTarget = pTargetEntry; // may be 0!
1262 :
1263 0 : if( DND_ACTION_COPY == rEvt.mnAction )
1264 : {
1265 0 : if ( CopySelection( aDDInfo.pSource, pTarget ) )
1266 0 : nRet = rEvt.mnAction;
1267 : }
1268 0 : else if( DND_ACTION_MOVE == rEvt.mnAction )
1269 : {
1270 0 : if ( MoveSelection( aDDInfo.pSource, pTarget ) )
1271 0 : nRet = rEvt.mnAction;
1272 : }
1273 0 : else if( DND_ACTION_COPYMOVE == rEvt.mnAction )
1274 : {
1275 0 : if ( MoveSelectionCopyFallbackPossible( aDDInfo.pSource, pTarget, true ) )
1276 0 : nRet = rEvt.mnAction;
1277 : }
1278 : }
1279 0 : return nRet;
1280 : }
1281 :
1282 0 : sal_Int8 SvTreeListBox::ExecuteDrop( const ExecuteDropEvent& rEvt )
1283 : {
1284 0 : return ExecuteDrop( rEvt, GetSourceView() );
1285 : }
1286 :
1287 0 : void SvTreeListBox::StartDrag( sal_Int8, const Point& rPosPixel )
1288 : {
1289 :
1290 0 : Point aEventPos( rPosPixel );
1291 0 : MouseEvent aMouseEvt( aEventPos, 1, MOUSE_SELECT, MOUSE_LEFT );
1292 0 : MouseButtonUp( aMouseEvt );
1293 :
1294 0 : nOldDragMode = GetDragDropMode();
1295 0 : if ( !nOldDragMode )
1296 0 : return;
1297 :
1298 0 : ReleaseMouse();
1299 :
1300 0 : SvTreeListEntry* pEntry = GetEntry( rPosPixel ); // GetDropTarget( rPos );
1301 0 : if( !pEntry )
1302 : {
1303 0 : DragFinished( DND_ACTION_NONE );
1304 0 : return;
1305 : }
1306 :
1307 0 : TransferDataContainer* pContainer = new TransferDataContainer;
1308 : ::com::sun::star::uno::Reference<
1309 0 : ::com::sun::star::datatransfer::XTransferable > xRef( pContainer );
1310 :
1311 0 : nDragDropMode = NotifyStartDrag( *pContainer, pEntry );
1312 0 : if( !nDragDropMode || 0 == GetSelectionCount() )
1313 : {
1314 0 : nDragDropMode = nOldDragMode;
1315 0 : DragFinished( DND_ACTION_NONE );
1316 0 : return;
1317 : }
1318 :
1319 : SvLBoxDDInfo aDDInfo;
1320 0 : memset(&aDDInfo,0,sizeof(SvLBoxDDInfo));
1321 0 : aDDInfo.pApp = GetpApp();
1322 0 : aDDInfo.pSource = this;
1323 0 : aDDInfo.pDDStartEntry = pEntry;
1324 : // let derived views do their thing
1325 0 : WriteDragServerInfo( rPosPixel, &aDDInfo );
1326 :
1327 : pContainer->CopyAnyData( SOT_FORMATSTR_ID_TREELISTBOX,
1328 0 : (sal_Char*)&aDDInfo, sizeof(SvLBoxDDInfo) );
1329 0 : pDDSource = this;
1330 0 : pDDTarget = 0;
1331 :
1332 0 : bool bOldUpdateMode = Control::IsUpdateMode();
1333 0 : Control::SetUpdateMode( true );
1334 0 : Update();
1335 0 : Control::SetUpdateMode( bOldUpdateMode );
1336 :
1337 : // Disallow using the selection and its children as drop targets.
1338 : // Important: If the selection of the SourceListBox is changed in the
1339 : // DropHandler, the entries have to be allowed as drop targets again:
1340 : // (GetSourceListBox()->EnableSelectionAsDropTarget( true, true );)
1341 0 : EnableSelectionAsDropTarget( false, true /* with children */ );
1342 :
1343 0 : pContainer->StartDrag( this, nDragOptions, GetDragFinishedHdl() );
1344 : }
1345 :
1346 0 : void SvTreeListBox::DragFinished( sal_Int8
1347 : #ifndef UNX
1348 : nAction
1349 : #endif
1350 : )
1351 : {
1352 0 : EnableSelectionAsDropTarget( true, true );
1353 :
1354 : #ifndef UNX
1355 : if( (nAction == DND_ACTION_MOVE) && ( (pDDTarget &&
1356 : ((sal_uLong)(pDDTarget->GetModel())!=(sal_uLong)(this->GetModel()))) ||
1357 : !pDDTarget ))
1358 : {
1359 : RemoveSelection();
1360 : }
1361 : #endif
1362 :
1363 0 : ImplShowTargetEmphasis( pTargetEntry, false );
1364 0 : pDDSource = 0;
1365 0 : pDDTarget = 0;
1366 0 : pTargetEntry = 0;
1367 0 : nDragDropMode = nOldDragMode;
1368 0 : }
1369 :
1370 0 : DragDropMode SvTreeListBox::NotifyStartDrag( TransferDataContainer&, SvTreeListEntry* )
1371 : {
1372 0 : return (DragDropMode)0xffff;
1373 : }
1374 :
1375 0 : bool SvTreeListBox::NotifyAcceptDrop( SvTreeListEntry* )
1376 : {
1377 0 : return true;
1378 : }
1379 :
1380 : // Handler and methods for Drag - finished handler.
1381 : // The with get GetDragFinishedHdl() get link can set on the
1382 : // TransferDataContainer. This link is a callback for the DragFinished
1383 : // call. AddBox method is called from the GetDragFinishedHdl() and the
1384 : // remove is called in link callback and in the destructor. So it can't
1385 : // called to a deleted object.
1386 :
1387 : namespace
1388 : {
1389 : struct SortLBoxes : public rtl::Static<std::set<sal_uLong>, SortLBoxes> {};
1390 : }
1391 :
1392 0 : void SvTreeListBox::AddBoxToDDList_Impl( const SvTreeListBox& rB )
1393 : {
1394 0 : sal_uLong nVal = (sal_uLong)&rB;
1395 0 : SortLBoxes::get().insert( nVal );
1396 0 : }
1397 :
1398 0 : void SvTreeListBox::RemoveBoxFromDDList_Impl( const SvTreeListBox& rB )
1399 : {
1400 0 : sal_uLong nVal = (sal_uLong)&rB;
1401 0 : SortLBoxes::get().erase( nVal );
1402 0 : }
1403 :
1404 0 : IMPL_STATIC_LINK( SvTreeListBox, DragFinishHdl_Impl, sal_Int8*, pAction )
1405 : {
1406 0 : sal_uLong nVal = (sal_uLong)pThis;
1407 0 : std::set<sal_uLong> &rSortLBoxes = SortLBoxes::get();
1408 0 : std::set<sal_uLong>::const_iterator it = rSortLBoxes.find(nVal);
1409 0 : if( it != rSortLBoxes.end() )
1410 : {
1411 0 : pThis->DragFinished( *pAction );
1412 0 : rSortLBoxes.erase( it );
1413 : }
1414 0 : return 0;
1415 : }
1416 :
1417 0 : Link SvTreeListBox::GetDragFinishedHdl() const
1418 : {
1419 0 : AddBoxToDDList_Impl( *this );
1420 0 : return STATIC_LINK( this, SvTreeListBox, DragFinishHdl_Impl );
1421 : }
1422 :
1423 : /*
1424 : Bugs/TODO
1425 :
1426 : - calculate rectangle when editing in-place (bug with some fonts)
1427 : - SetSpaceBetweenEntries: offset is not taken into account in SetEntryHeight
1428 : */
1429 :
1430 : #define TREEFLAG_FIXEDHEIGHT 0x0010
1431 :
1432 : #define SV_LBOX_DEFAULT_INDENT_PIXEL 20
1433 :
1434 0 : void SvTreeListBox::InitTreeView()
1435 : {
1436 0 : pCheckButtonData = NULL;
1437 0 : pEdEntry = NULL;
1438 0 : pEdItem = NULL;
1439 0 : nEntryHeight = 0;
1440 0 : pEdCtrl = NULL;
1441 0 : nFirstSelTab = 0;
1442 0 : nLastSelTab = 0;
1443 0 : nFocusWidth = -1;
1444 0 : nAllItemAccRoleType = 0;
1445 0 : mnCheckboxItemWidth = 0;
1446 :
1447 0 : Link* pLink = new Link( LINK(this,SvTreeListBox, DefaultCompare) );
1448 0 : mpImpl->m_pLink = pLink;
1449 :
1450 0 : nTreeFlags = TREEFLAG_RECALCTABS;
1451 0 : nIndent = SV_LBOX_DEFAULT_INDENT_PIXEL;
1452 0 : nEntryHeightOffs = SV_ENTRYHEIGHTOFFS_PIXEL;
1453 0 : pImp = new SvImpLBox( this, GetModel(), GetStyle() );
1454 :
1455 0 : mbContextBmpExpanded = true;
1456 0 : nContextBmpWidthMax = 0;
1457 :
1458 0 : SetFont( GetFont() );
1459 0 : AdjustEntryHeightAndRecalc( GetFont() );
1460 :
1461 0 : SetSpaceBetweenEntries( 0 );
1462 0 : SetLineColor();
1463 0 : InitSettings( true, true, true );
1464 0 : ImplInitStyle();
1465 0 : SetTabs();
1466 0 : }
1467 :
1468 0 : OUString SvTreeListBox::GetEntryAltText( SvTreeListEntry* ) const
1469 : {
1470 0 : return OUString();
1471 : }
1472 :
1473 0 : OUString SvTreeListBox::GetEntryLongDescription( SvTreeListEntry* ) const
1474 : {
1475 0 : return OUString();
1476 : }
1477 :
1478 0 : OUString SvTreeListBox::SearchEntryTextWithHeadTitle( SvTreeListEntry* pEntry )
1479 : {
1480 : DBG_ASSERT( pEntry, "SvTreeListBox::SearchEntryText(): no entry" );
1481 0 : OUString sRet;
1482 :
1483 0 : sal_uInt16 nCount = pEntry->ItemCount();
1484 0 : sal_uInt16 nCur = 0;
1485 0 : sal_uInt16 nHeaderCur = 0;
1486 : SvLBoxItem* pItem;
1487 0 : while( nCur < nCount )
1488 : {
1489 : // MT: SV_ITEM_ID_EXTENDRLBOXSTRING / GetExtendText() was in use in IA2 cws, but only used in sc: ScSolverOptionsString. Needed?
1490 0 : pItem = pEntry->GetItem( nCur );
1491 0 : if ( (pItem->GetType() == SV_ITEM_ID_LBOXSTRING ) &&
1492 0 : !static_cast<SvLBoxString*>( pItem )->GetText().isEmpty() )
1493 : {
1494 : //want the column header
1495 0 : if (!headString.isEmpty())
1496 : {
1497 0 : sal_Int32 nEnd = headString.indexOf('\t');
1498 0 : if( nEnd == -1 )
1499 : {
1500 0 : if (!sRet.isEmpty())
1501 : {
1502 0 : sRet += ",";
1503 : }
1504 0 : if (!headString.isEmpty())
1505 : {
1506 0 : sRet += headString ;
1507 0 : sRet += ":" ;
1508 : }
1509 : }
1510 : else
1511 : {
1512 0 : OUString aString=headString.getToken(nHeaderCur, '\t');
1513 0 : if (!sRet.isEmpty())
1514 : {
1515 0 : sRet += ",";
1516 : }
1517 0 : if (!aString.isEmpty())
1518 : {
1519 0 : sRet += aString ;
1520 0 : sRet += ":" ;
1521 : }
1522 0 : nHeaderCur++;
1523 : }
1524 0 : sRet += static_cast<SvLBoxString*>( pItem )->GetText();
1525 : }
1526 : else
1527 : {
1528 0 : sRet += static_cast<SvLBoxString*>( pItem )->GetText();
1529 0 : sRet += ",";
1530 : }
1531 : //end want to the column header
1532 : }
1533 0 : nCur++;
1534 : }
1535 :
1536 0 : if (!sRet.isEmpty())
1537 0 : sRet = sRet.copy(0, sRet.getLength() - 1);
1538 0 : return sRet;
1539 : }
1540 :
1541 0 : SvTreeListBox::~SvTreeListBox()
1542 : {
1543 :
1544 0 : pImp->CallEventListeners( VCLEVENT_OBJECT_DYING );
1545 0 : delete pImp;
1546 0 : delete mpImpl->m_pLink;
1547 0 : ClearTabList();
1548 :
1549 0 : delete pEdCtrl;
1550 0 : pEdCtrl = 0;
1551 0 : pModel->RemoveView( this );
1552 0 : if ( pModel->GetRefCount() == 0 )
1553 : {
1554 0 : pModel->Clear();
1555 0 : delete pModel;
1556 0 : pModel = NULL;
1557 : }
1558 :
1559 0 : SvTreeListBox::RemoveBoxFromDDList_Impl( *this );
1560 :
1561 0 : if( this == pDDSource )
1562 0 : pDDSource = 0;
1563 0 : if( this == pDDTarget )
1564 0 : pDDTarget = 0;
1565 0 : delete mpImpl;
1566 0 : }
1567 :
1568 0 : void SvTreeListBox::SetExtendedWinBits( ExtendedWinBits _nBits )
1569 : {
1570 0 : pImp->SetExtendedWindowBits( _nBits );
1571 0 : }
1572 :
1573 0 : void SvTreeListBox::SetModel( SvTreeList* pNewModel )
1574 : {
1575 0 : pImp->SetModel( pNewModel );
1576 0 : SetBaseModel(pNewModel);
1577 0 : }
1578 :
1579 0 : void SvTreeListBox::SetBaseModel( SvTreeList* pNewModel )
1580 : {
1581 : // does the CleanUp
1582 0 : SvListView::SetModel( pNewModel );
1583 0 : pModel->SetCloneLink( LINK(this, SvTreeListBox, CloneHdl_Impl ));
1584 0 : SvTreeListEntry* pEntry = First();
1585 0 : while( pEntry )
1586 : {
1587 0 : ModelHasInserted( pEntry );
1588 0 : pEntry = Next( pEntry );
1589 : }
1590 0 : }
1591 :
1592 0 : void SvTreeListBox::DisconnectFromModel()
1593 : {
1594 0 : SvTreeList* pNewModel = new SvTreeList;
1595 0 : pNewModel->SetRefCount( 0 ); // else this will never be deleted
1596 0 : SvListView::SetModel( pNewModel );
1597 :
1598 0 : pImp->SetModel( GetModel() );
1599 0 : }
1600 :
1601 0 : void SvTreeListBox::SetSublistOpenWithReturn( bool b )
1602 : {
1603 0 : pImp->bSubLstOpRet = b;
1604 0 : }
1605 :
1606 0 : void SvTreeListBox::SetSublistOpenWithLeftRight( bool b )
1607 : {
1608 0 : pImp->bSubLstOpLR = b;
1609 0 : }
1610 :
1611 0 : void SvTreeListBox::Resize()
1612 : {
1613 0 : if( IsEditingActive() )
1614 0 : EndEditing( true );
1615 :
1616 0 : Control::Resize();
1617 :
1618 0 : pImp->Resize();
1619 0 : nFocusWidth = -1;
1620 0 : pImp->ShowCursor( false );
1621 0 : pImp->ShowCursor( true );
1622 0 : }
1623 :
1624 : /* Cases:
1625 :
1626 : A) entries have bitmaps
1627 : 0. no buttons
1628 : 1. node buttons (can optionally also be on root items)
1629 : 2. node buttons (can optionally also be on root items) + CheckButton
1630 : 3. CheckButton
1631 : B) entries don't have bitmaps (=>via WindowBits because of D&D!)
1632 : 0. no buttons
1633 : 1. node buttons (can optionally also be on root items)
1634 : 2. node buttons (can optionally also be on root items) + CheckButton
1635 : 3. CheckButton
1636 : */
1637 :
1638 : #define NO_BUTTONS 0
1639 : #define NODE_BUTTONS 1
1640 : #define NODE_AND_CHECK_BUTTONS 2
1641 : #define CHECK_BUTTONS 3
1642 :
1643 : #define TABFLAGS_TEXT (SV_LBOXTAB_DYNAMIC | \
1644 : SV_LBOXTAB_ADJUST_LEFT | \
1645 : SV_LBOXTAB_EDITABLE | \
1646 : SV_LBOXTAB_SHOW_SELECTION)
1647 :
1648 : #define TABFLAGS_CONTEXTBMP (SV_LBOXTAB_DYNAMIC | SV_LBOXTAB_ADJUST_CENTER)
1649 :
1650 : #define TABFLAGS_CHECKBTN (SV_LBOXTAB_DYNAMIC | \
1651 : SV_LBOXTAB_ADJUST_CENTER | \
1652 : SV_LBOXTAB_PUSHABLE)
1653 :
1654 : #define TAB_STARTPOS 2
1655 :
1656 : // take care of GetTextOffset when doing changes
1657 0 : void SvTreeListBox::SetTabs()
1658 : {
1659 0 : if( IsEditingActive() )
1660 0 : EndEditing( true );
1661 0 : nTreeFlags &= (~TREEFLAG_RECALCTABS);
1662 0 : nFocusWidth = -1;
1663 0 : const WinBits nStyle( GetStyle() );
1664 0 : bool bHasButtons = (nStyle & WB_HASBUTTONS)!=0;
1665 0 : bool bHasButtonsAtRoot = (nStyle & (WB_HASLINESATROOT |
1666 0 : WB_HASBUTTONSATROOT))!=0;
1667 0 : long nStartPos = TAB_STARTPOS;
1668 0 : long nNodeWidthPixel = GetExpandedNodeBmp().GetSizePixel().Width();
1669 :
1670 : // pCheckButtonData->Width() knows nothing about the native checkbox width,
1671 : // so we have mnCheckboxItemWidth which becomes valid when something is added.
1672 0 : long nCheckWidth = 0;
1673 0 : if( nTreeFlags & TREEFLAG_CHKBTN )
1674 0 : nCheckWidth = mnCheckboxItemWidth;
1675 0 : long nCheckWidthDIV2 = nCheckWidth / 2;
1676 :
1677 0 : long nContextWidth = nContextBmpWidthMax;
1678 0 : long nContextWidthDIV2 = nContextWidth / 2;
1679 :
1680 0 : ClearTabList();
1681 :
1682 0 : int nCase = NO_BUTTONS;
1683 0 : if( !(nTreeFlags & TREEFLAG_CHKBTN) )
1684 : {
1685 0 : if( bHasButtons )
1686 0 : nCase = NODE_BUTTONS;
1687 : }
1688 : else
1689 : {
1690 0 : if( bHasButtons )
1691 0 : nCase = NODE_AND_CHECK_BUTTONS;
1692 : else
1693 0 : nCase = CHECK_BUTTONS;
1694 : }
1695 :
1696 0 : switch( nCase )
1697 : {
1698 : case NO_BUTTONS :
1699 0 : nStartPos += nContextWidthDIV2; // because of centering
1700 0 : AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
1701 0 : nStartPos += nContextWidthDIV2; // right edge of context bitmap
1702 : // only set a distance if there are bitmaps
1703 0 : if( nContextBmpWidthMax )
1704 0 : nStartPos += 5; // distance context bitmap to text
1705 0 : AddTab( nStartPos, TABFLAGS_TEXT );
1706 0 : break;
1707 :
1708 : case NODE_BUTTONS :
1709 0 : if( bHasButtonsAtRoot )
1710 0 : nStartPos += ( nIndent + (nNodeWidthPixel/2) );
1711 : else
1712 0 : nStartPos += nContextWidthDIV2;
1713 0 : AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
1714 0 : nStartPos += nContextWidthDIV2; // right edge of context bitmap
1715 : // only set a distance if there are bitmaps
1716 0 : if( nContextBmpWidthMax )
1717 0 : nStartPos += 5; // distance context bitmap to text
1718 0 : AddTab( nStartPos, TABFLAGS_TEXT );
1719 0 : break;
1720 :
1721 : case NODE_AND_CHECK_BUTTONS :
1722 0 : if( bHasButtonsAtRoot )
1723 0 : nStartPos += ( nIndent + nNodeWidthPixel );
1724 : else
1725 0 : nStartPos += nCheckWidthDIV2;
1726 0 : AddTab( nStartPos, TABFLAGS_CHECKBTN );
1727 0 : nStartPos += nCheckWidthDIV2; // right edge of CheckButton
1728 0 : nStartPos += 3; // distance CheckButton to context bitmap
1729 0 : nStartPos += nContextWidthDIV2; // center of context bitmap
1730 0 : AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
1731 0 : nStartPos += nContextWidthDIV2; // right edge of context bitmap
1732 : // only set a distance if there are bitmaps
1733 0 : if( nContextBmpWidthMax )
1734 0 : nStartPos += 5; // distance context bitmap to text
1735 0 : AddTab( nStartPos, TABFLAGS_TEXT );
1736 0 : break;
1737 :
1738 : case CHECK_BUTTONS :
1739 0 : nStartPos += nCheckWidthDIV2;
1740 0 : AddTab( nStartPos, TABFLAGS_CHECKBTN );
1741 0 : nStartPos += nCheckWidthDIV2; // right edge of CheckButton
1742 0 : nStartPos += 3; // distance CheckButton to context bitmap
1743 0 : nStartPos += nContextWidthDIV2; // center of context bitmap
1744 0 : AddTab( nStartPos, TABFLAGS_CONTEXTBMP );
1745 0 : nStartPos += nContextWidthDIV2; // right edge of context bitmap
1746 : // only set a distance if there are bitmaps
1747 0 : if( nContextBmpWidthMax )
1748 0 : nStartPos += 5; // distance context bitmap to text
1749 0 : AddTab( nStartPos, TABFLAGS_TEXT );
1750 0 : break;
1751 : }
1752 0 : pImp->NotifyTabsChanged();
1753 0 : }
1754 :
1755 0 : void SvTreeListBox::InitEntry(SvTreeListEntry* pEntry,
1756 : const OUString& aStr, const Image& aCollEntryBmp, const Image& aExpEntryBmp,
1757 : SvLBoxButtonKind eButtonKind)
1758 : {
1759 : SvLBoxButton* pButton;
1760 : SvLBoxString* pString;
1761 : SvLBoxContextBmp* pContextBmp;
1762 :
1763 0 : if( nTreeFlags & TREEFLAG_CHKBTN )
1764 : {
1765 0 : pButton= new SvLBoxButton( pEntry,eButtonKind,0,pCheckButtonData );
1766 0 : pEntry->AddItem( pButton );
1767 : }
1768 :
1769 : pContextBmp= new SvLBoxContextBmp(
1770 0 : pEntry,0, aCollEntryBmp,aExpEntryBmp, mbContextBmpExpanded);
1771 0 : pEntry->AddItem( pContextBmp );
1772 :
1773 0 : pString = new SvLBoxString( pEntry, 0, aStr );
1774 0 : pEntry->AddItem( pString );
1775 0 : }
1776 :
1777 0 : OUString SvTreeListBox::GetEntryText(SvTreeListEntry* pEntry) const
1778 : {
1779 : DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): no entry" );
1780 0 : SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
1781 : DBG_ASSERT( pEntry, "SvTreeListBox::GetEntryText(): item not found" );
1782 0 : return pItem->GetText();
1783 : }
1784 :
1785 0 : const Image& SvTreeListBox::GetExpandedEntryBmp(const SvTreeListEntry* pEntry) const
1786 : {
1787 : DBG_ASSERT(pEntry,"Entry?");
1788 0 : const SvLBoxContextBmp* pItem = static_cast<const SvLBoxContextBmp*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
1789 : DBG_ASSERT(pItem,"GetContextBmp:Item not found");
1790 0 : return pItem->GetBitmap2( );
1791 : }
1792 :
1793 0 : const Image& SvTreeListBox::GetCollapsedEntryBmp( const SvTreeListEntry* pEntry ) const
1794 : {
1795 : DBG_ASSERT(pEntry,"Entry?");
1796 0 : const SvLBoxContextBmp* pItem = static_cast<const SvLBoxContextBmp*>(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
1797 : DBG_ASSERT(pItem,"GetContextBmp:Item not found");
1798 0 : return pItem->GetBitmap1( );
1799 : }
1800 :
1801 0 : IMPL_LINK_INLINE_START( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )
1802 : {
1803 0 : pHdlEntry = pData->GetActEntry();
1804 0 : CheckButtonHdl();
1805 0 : return 0;
1806 : }
1807 0 : IMPL_LINK_INLINE_END( SvTreeListBox, CheckButtonClick, SvLBoxButtonData *, pData )
1808 :
1809 0 : SvTreeListEntry* SvTreeListBox::InsertEntry(
1810 : const OUString& rText,
1811 : SvTreeListEntry* pParent,
1812 : bool bChildrenOnDemand, sal_uLong nPos,
1813 : void* pUser,
1814 : SvLBoxButtonKind eButtonKind
1815 : )
1816 : {
1817 0 : nTreeFlags |= TREEFLAG_MANINS;
1818 :
1819 0 : const Image& rDefExpBmp = pImp->GetDefaultEntryExpBmp( );
1820 0 : const Image& rDefColBmp = pImp->GetDefaultEntryColBmp( );
1821 :
1822 0 : aCurInsertedExpBmp = rDefExpBmp;
1823 0 : aCurInsertedColBmp = rDefColBmp;
1824 :
1825 0 : SvTreeListEntry* pEntry = CreateEntry();
1826 0 : pEntry->SetUserData( pUser );
1827 0 : InitEntry( pEntry, rText, rDefColBmp, rDefExpBmp, eButtonKind );
1828 0 : pEntry->EnableChildrenOnDemand( bChildrenOnDemand );
1829 :
1830 0 : if( !pParent )
1831 0 : Insert( pEntry, nPos );
1832 : else
1833 0 : Insert( pEntry, pParent, nPos );
1834 :
1835 0 : aPrevInsertedExpBmp = rDefExpBmp;
1836 0 : aPrevInsertedColBmp = rDefColBmp;
1837 :
1838 0 : nTreeFlags &= (~TREEFLAG_MANINS);
1839 :
1840 0 : return pEntry;
1841 : }
1842 :
1843 0 : SvTreeListEntry* SvTreeListBox::InsertEntry( const OUString& rText,
1844 : const Image& aExpEntryBmp, const Image& aCollEntryBmp,
1845 : SvTreeListEntry* pParent, bool bChildrenOnDemand, sal_uLong nPos, void* pUser,
1846 : SvLBoxButtonKind eButtonKind )
1847 : {
1848 0 : nTreeFlags |= TREEFLAG_MANINS;
1849 :
1850 0 : aCurInsertedExpBmp = aExpEntryBmp;
1851 0 : aCurInsertedColBmp = aCollEntryBmp;
1852 :
1853 0 : SvTreeListEntry* pEntry = CreateEntry();
1854 0 : pEntry->SetUserData( pUser );
1855 0 : InitEntry( pEntry, rText, aCollEntryBmp, aExpEntryBmp, eButtonKind );
1856 :
1857 0 : pEntry->EnableChildrenOnDemand( bChildrenOnDemand );
1858 :
1859 0 : if( !pParent )
1860 0 : Insert( pEntry, nPos );
1861 : else
1862 0 : Insert( pEntry, pParent, nPos );
1863 :
1864 0 : aPrevInsertedExpBmp = aExpEntryBmp;
1865 0 : aPrevInsertedColBmp = aCollEntryBmp;
1866 :
1867 0 : nTreeFlags &= (~TREEFLAG_MANINS);
1868 :
1869 0 : return pEntry;
1870 : }
1871 :
1872 0 : void SvTreeListBox::SetEntryText(SvTreeListEntry* pEntry, const OUString& rStr)
1873 : {
1874 0 : SvLBoxString* pItem = (SvLBoxString*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
1875 : DBG_ASSERT(pItem,"SetText:Item not found");
1876 0 : pItem->SetText(rStr);
1877 0 : pItem->InitViewData( this, pEntry, 0 );
1878 0 : GetModel()->InvalidateEntry( pEntry );
1879 0 : }
1880 :
1881 0 : void SvTreeListBox::SetExpandedEntryBmp( SvTreeListEntry* pEntry, const Image& aBmp )
1882 : {
1883 0 : SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
1884 :
1885 : DBG_ASSERT(pItem,"SetExpBmp:Item not found");
1886 0 : pItem->SetBitmap2( aBmp );
1887 :
1888 0 : GetModel()->InvalidateEntry( pEntry );
1889 0 : SetEntryHeight( pEntry );
1890 0 : Size aSize = aBmp.GetSizePixel();
1891 0 : short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
1892 0 : if( nWidth > nContextBmpWidthMax )
1893 : {
1894 0 : nContextBmpWidthMax = nWidth;
1895 0 : SetTabs();
1896 : }
1897 0 : }
1898 :
1899 0 : void SvTreeListBox::SetCollapsedEntryBmp(SvTreeListEntry* pEntry,const Image& aBmp )
1900 : {
1901 0 : SvLBoxContextBmp* pItem = (SvLBoxContextBmp*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
1902 :
1903 : DBG_ASSERT(pItem,"SetExpBmp:Item not found");
1904 0 : pItem->SetBitmap1( aBmp );
1905 :
1906 0 : GetModel()->InvalidateEntry( pEntry );
1907 0 : SetEntryHeight( pEntry );
1908 0 : Size aSize = aBmp.GetSizePixel();
1909 0 : short nWidth = pImp->UpdateContextBmpWidthVector( pEntry, (short)aSize.Width() );
1910 0 : if( nWidth > nContextBmpWidthMax )
1911 : {
1912 0 : nContextBmpWidthMax = nWidth;
1913 0 : SetTabs();
1914 : }
1915 0 : }
1916 :
1917 0 : void SvTreeListBox::ImpEntryInserted( SvTreeListEntry* pEntry )
1918 : {
1919 :
1920 0 : SvTreeListEntry* pParent = (SvTreeListEntry*)pModel->GetParent( pEntry );
1921 0 : if( pParent )
1922 : {
1923 0 : sal_uInt16 nFlags = pParent->GetFlags();
1924 0 : nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
1925 0 : pParent->SetFlags( nFlags );
1926 : }
1927 :
1928 0 : if(!((nTreeFlags & TREEFLAG_MANINS) &&
1929 0 : (aPrevInsertedExpBmp == aCurInsertedExpBmp) &&
1930 0 : (aPrevInsertedColBmp == aCurInsertedColBmp) ))
1931 : {
1932 0 : Size aSize = GetCollapsedEntryBmp( pEntry ).GetSizePixel();
1933 0 : if( aSize.Width() > nContextBmpWidthMax )
1934 : {
1935 0 : nContextBmpWidthMax = (short)aSize.Width();
1936 0 : nTreeFlags |= TREEFLAG_RECALCTABS;
1937 : }
1938 0 : aSize = GetExpandedEntryBmp( pEntry ).GetSizePixel();
1939 0 : if( aSize.Width() > nContextBmpWidthMax )
1940 : {
1941 0 : nContextBmpWidthMax = (short)aSize.Width();
1942 0 : nTreeFlags |= TREEFLAG_RECALCTABS;
1943 : }
1944 : }
1945 0 : SetEntryHeight( (SvTreeListEntry*)pEntry );
1946 :
1947 0 : if( nTreeFlags & TREEFLAG_CHKBTN )
1948 : {
1949 0 : SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
1950 0 : if( pItem )
1951 : {
1952 0 : long nWidth = pItem->GetSize(this, pEntry).Width();
1953 0 : if( mnCheckboxItemWidth < nWidth )
1954 : {
1955 0 : mnCheckboxItemWidth = nWidth;
1956 0 : nTreeFlags |= TREEFLAG_RECALCTABS;
1957 : }
1958 : }
1959 : }
1960 0 : }
1961 :
1962 :
1963 :
1964 0 : void SvTreeListBox::SetCheckButtonState( SvTreeListEntry* pEntry, SvButtonState eState)
1965 : {
1966 0 : if( nTreeFlags & TREEFLAG_CHKBTN )
1967 : {
1968 0 : SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
1969 0 : if(!(pItem && pItem->CheckModification()))
1970 0 : return ;
1971 0 : switch( eState )
1972 : {
1973 : case SV_BUTTON_CHECKED:
1974 0 : pItem->SetStateChecked();
1975 0 : break;
1976 :
1977 : case SV_BUTTON_UNCHECKED:
1978 0 : pItem->SetStateUnchecked();
1979 0 : break;
1980 :
1981 : case SV_BUTTON_TRISTATE:
1982 0 : pItem->SetStateTristate();
1983 0 : break;
1984 : }
1985 0 : InvalidateEntry( pEntry );
1986 : }
1987 : }
1988 :
1989 0 : void SvTreeListBox::SetCheckButtonInvisible( SvTreeListEntry* pEntry)
1990 : {
1991 0 : if( nTreeFlags & TREEFLAG_CHKBTN )
1992 : {
1993 0 : SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
1994 0 : pItem->SetStateInvisible();
1995 0 : InvalidateEntry( pEntry );
1996 : }
1997 0 : }
1998 :
1999 0 : SvButtonState SvTreeListBox::GetCheckButtonState( SvTreeListEntry* pEntry ) const
2000 : {
2001 0 : SvButtonState eState = SV_BUTTON_UNCHECKED;
2002 0 : if( nTreeFlags & TREEFLAG_CHKBTN )
2003 : {
2004 0 : SvLBoxButton* pItem = (SvLBoxButton*)(pEntry->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
2005 0 : if(!pItem)
2006 0 : return SV_BUTTON_TRISTATE;
2007 0 : sal_uInt16 nButtonFlags = pItem->GetButtonFlags();
2008 0 : eState = pCheckButtonData->ConvertToButtonState( nButtonFlags );
2009 : }
2010 0 : return eState;
2011 : }
2012 :
2013 0 : void SvTreeListBox::CheckButtonHdl()
2014 : {
2015 0 : aCheckButtonHdl.Call( this );
2016 0 : if ( pCheckButtonData )
2017 0 : pImp->CallEventListeners( VCLEVENT_CHECKBOX_TOGGLE, (void*)pCheckButtonData->GetActEntry() );
2018 0 : }
2019 :
2020 :
2021 : // TODO: Currently all data is cloned so that they conform to the default tree
2022 : // view format. Actually, the model should be used as a reference here. This
2023 : // leads to us _not_ calling SvTreeListEntry::Clone, but only its base class
2024 : // SvTreeListEntry.
2025 :
2026 :
2027 0 : SvTreeListEntry* SvTreeListBox::CloneEntry( SvTreeListEntry* pSource )
2028 : {
2029 0 : OUString aStr;
2030 0 : Image aCollEntryBmp;
2031 0 : Image aExpEntryBmp;
2032 0 : SvLBoxButtonKind eButtonKind = SvLBoxButtonKind_enabledCheckbox;
2033 :
2034 0 : SvLBoxString* pStringItem = (SvLBoxString*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXSTRING));
2035 0 : if( pStringItem )
2036 0 : aStr = pStringItem->GetText();
2037 0 : SvLBoxContextBmp* pBmpItem = (SvLBoxContextBmp*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXCONTEXTBMP));
2038 0 : if( pBmpItem )
2039 : {
2040 0 : aCollEntryBmp = pBmpItem->GetBitmap1( );
2041 0 : aExpEntryBmp = pBmpItem->GetBitmap2( );
2042 : }
2043 0 : SvLBoxButton* pButtonItem = (SvLBoxButton*)(pSource->GetFirstItem(SV_ITEM_ID_LBOXBUTTON));
2044 0 : if( pButtonItem )
2045 0 : eButtonKind = pButtonItem->GetKind();
2046 0 : SvTreeListEntry* pClone = CreateEntry();
2047 0 : InitEntry( pClone, aStr, aCollEntryBmp, aExpEntryBmp, eButtonKind );
2048 0 : pClone->SvTreeListEntry::Clone( pSource );
2049 0 : pClone->EnableChildrenOnDemand( pSource->HasChildrenOnDemand() );
2050 0 : pClone->SetUserData( pSource->GetUserData() );
2051 :
2052 0 : return pClone;
2053 : }
2054 :
2055 0 : void SvTreeListBox::SetIndent( short nNewIndent )
2056 : {
2057 0 : nIndent = nNewIndent;
2058 0 : SetTabs();
2059 0 : if( IsUpdateMode() )
2060 0 : Invalidate();
2061 0 : }
2062 :
2063 0 : const Image& SvTreeListBox::GetDefaultExpandedEntryBmp( ) const
2064 : {
2065 0 : return pImp->GetDefaultEntryExpBmp( );
2066 : }
2067 :
2068 0 : const Image& SvTreeListBox::GetDefaultCollapsedEntryBmp( ) const
2069 : {
2070 0 : return pImp->GetDefaultEntryColBmp( );
2071 : }
2072 :
2073 0 : void SvTreeListBox::SetDefaultExpandedEntryBmp( const Image& aBmp )
2074 : {
2075 0 : Size aSize = aBmp.GetSizePixel();
2076 0 : if( aSize.Width() > nContextBmpWidthMax )
2077 0 : nContextBmpWidthMax = (short)aSize.Width();
2078 0 : SetTabs();
2079 :
2080 0 : pImp->SetDefaultEntryExpBmp( aBmp );
2081 0 : }
2082 :
2083 0 : void SvTreeListBox::SetDefaultCollapsedEntryBmp( const Image& aBmp )
2084 : {
2085 0 : Size aSize = aBmp.GetSizePixel();
2086 0 : if( aSize.Width() > nContextBmpWidthMax )
2087 0 : nContextBmpWidthMax = (short)aSize.Width();
2088 0 : SetTabs();
2089 :
2090 0 : pImp->SetDefaultEntryColBmp( aBmp );
2091 0 : }
2092 :
2093 0 : void SvTreeListBox::EnableCheckButton( SvLBoxButtonData* pData )
2094 : {
2095 : DBG_ASSERT(!GetEntryCount(),"EnableCheckButton: Entry count != 0");
2096 0 : if( !pData )
2097 0 : nTreeFlags &= (~TREEFLAG_CHKBTN);
2098 : else
2099 : {
2100 0 : SetCheckButtonData( pData );
2101 0 : nTreeFlags |= TREEFLAG_CHKBTN;
2102 0 : pData->SetLink( LINK(this, SvTreeListBox, CheckButtonClick));
2103 : }
2104 :
2105 0 : SetTabs();
2106 0 : if( IsUpdateMode() )
2107 0 : Invalidate();
2108 0 : }
2109 :
2110 0 : void SvTreeListBox::SetCheckButtonData( SvLBoxButtonData* pData )
2111 : {
2112 0 : if ( pData )
2113 0 : pCheckButtonData = pData;
2114 0 : }
2115 :
2116 0 : const Image& SvTreeListBox::GetDefaultExpandedNodeImage( )
2117 : {
2118 0 : return SvImpLBox::GetDefaultExpandedNodeImage( );
2119 : }
2120 :
2121 0 : const Image& SvTreeListBox::GetDefaultCollapsedNodeImage( )
2122 : {
2123 0 : return SvImpLBox::GetDefaultCollapsedNodeImage( );
2124 : }
2125 :
2126 0 : void SvTreeListBox::SetNodeBitmaps( const Image& rCollapsedNodeBmp, const Image& rExpandedNodeBmp )
2127 : {
2128 0 : SetExpandedNodeBmp( rExpandedNodeBmp );
2129 0 : SetCollapsedNodeBmp( rCollapsedNodeBmp );
2130 0 : SetTabs();
2131 0 : }
2132 :
2133 0 : bool SvTreeListBox::EditingEntry( SvTreeListEntry*, Selection& )
2134 : {
2135 0 : return true;
2136 : }
2137 :
2138 0 : bool SvTreeListBox::EditedEntry( SvTreeListEntry* /*pEntry*/,const OUString& /*rNewText*/)
2139 : {
2140 0 : return true;
2141 : }
2142 :
2143 0 : void SvTreeListBox::EnableInplaceEditing( bool bOn )
2144 : {
2145 0 : if (bOn)
2146 0 : nImpFlags |= SVLBOX_EDT_ENABLED;
2147 : else
2148 0 : nImpFlags &= ~SVLBOX_EDT_ENABLED;
2149 0 : }
2150 :
2151 0 : void SvTreeListBox::KeyInput( const KeyEvent& rKEvt )
2152 : {
2153 : // under OS/2, we get key up/down even while editing
2154 0 : if( IsEditingActive() )
2155 0 : return;
2156 :
2157 0 : nImpFlags |= SVLBOX_IS_TRAVELSELECT;
2158 :
2159 : #ifdef OVDEBUG
2160 : sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
2161 : switch ( nCode )
2162 : {
2163 : case KEY_F1:
2164 : {
2165 : SvTreeListEntry* pEntry = First();
2166 : pEntry = NextVisible( pEntry );
2167 : SetEntryText( pEntry, "SetEntryText" );
2168 : }
2169 : break;
2170 : }
2171 : #endif
2172 :
2173 0 : if( !pImp->KeyInput( rKEvt ) )
2174 : {
2175 0 : bool bHandled = HandleKeyInput( rKEvt );
2176 0 : if ( !bHandled )
2177 0 : Control::KeyInput( rKEvt );
2178 : }
2179 :
2180 0 : nImpFlags &= ~SVLBOX_IS_TRAVELSELECT;
2181 : }
2182 :
2183 0 : void SvTreeListBox::RequestingChildren( SvTreeListEntry* pParent )
2184 : {
2185 0 : if( !pParent->HasChildren() )
2186 0 : InsertEntry( OUString("<dummy>"), pParent, false, TREELIST_APPEND );
2187 0 : }
2188 :
2189 0 : void SvTreeListBox::GetFocus()
2190 : {
2191 : //If there is no item in the tree, draw focus.
2192 0 : if( !First())
2193 : {
2194 0 : Invalidate();
2195 : }
2196 0 : pImp->GetFocus();
2197 0 : Control::GetFocus();
2198 :
2199 0 : SvTreeListEntry* pEntry = FirstSelected();
2200 0 : if ( !pEntry )
2201 : {
2202 0 : pEntry = pImp->GetCurrentEntry();
2203 : }
2204 0 : if (pImp->pCursor)
2205 : {
2206 0 : if (pEntry != pImp->pCursor)
2207 0 : pEntry = pImp->pCursor;
2208 : }
2209 0 : if ( pEntry )
2210 0 : pImp->CallEventListeners( VCLEVENT_LISTBOX_TREEFOCUS, pEntry );
2211 :
2212 0 : }
2213 :
2214 0 : void SvTreeListBox::LoseFocus()
2215 : {
2216 : //If there is no item in the tree, delete visual focus.
2217 0 : if( !First())
2218 : {
2219 0 : Invalidate();
2220 : }
2221 0 : pImp->LoseFocus();
2222 0 : Control::LoseFocus();
2223 0 : }
2224 :
2225 0 : void SvTreeListBox::ModelHasCleared()
2226 : {
2227 0 : pImp->pCursor = 0; // else we crash in GetFocus when editing in-place
2228 0 : delete pEdCtrl;
2229 0 : pEdCtrl = NULL;
2230 0 : pImp->Clear();
2231 0 : nFocusWidth = -1;
2232 :
2233 0 : nContextBmpWidthMax = 0;
2234 0 : SetDefaultExpandedEntryBmp( GetDefaultExpandedEntryBmp() );
2235 0 : SetDefaultCollapsedEntryBmp( GetDefaultCollapsedEntryBmp() );
2236 :
2237 0 : if( !(nTreeFlags & TREEFLAG_FIXEDHEIGHT ))
2238 0 : nEntryHeight = 0;
2239 0 : AdjustEntryHeight( GetFont() );
2240 0 : AdjustEntryHeight( GetDefaultExpandedEntryBmp() );
2241 0 : AdjustEntryHeight( GetDefaultCollapsedEntryBmp() );
2242 :
2243 0 : SvListView::ModelHasCleared();
2244 0 : }
2245 :
2246 0 : void SvTreeListBox::ShowTargetEmphasis( SvTreeListEntry* pEntry, bool /*bShow*/ )
2247 : {
2248 0 : pImp->PaintDDCursor( pEntry );
2249 0 : }
2250 :
2251 0 : void SvTreeListBox::ScrollOutputArea( short nDeltaEntries )
2252 : {
2253 0 : if( !nDeltaEntries || !pImp->aVerSBar.IsVisible() )
2254 0 : return;
2255 :
2256 0 : long nThumb = pImp->aVerSBar.GetThumbPos();
2257 0 : long nMax = pImp->aVerSBar.GetRange().Max();
2258 :
2259 0 : NotifyBeginScroll();
2260 0 : if( nDeltaEntries < 0 )
2261 : {
2262 : // move window up
2263 0 : nDeltaEntries *= -1;
2264 0 : long nVis = pImp->aVerSBar.GetVisibleSize();
2265 0 : long nTemp = nThumb + nVis;
2266 0 : if( nDeltaEntries > (nMax - nTemp) )
2267 0 : nDeltaEntries = (short)(nMax - nTemp);
2268 0 : pImp->PageDown( (sal_uInt16)nDeltaEntries );
2269 : }
2270 : else
2271 : {
2272 0 : if( nDeltaEntries > nThumb )
2273 0 : nDeltaEntries = (short)nThumb;
2274 0 : pImp->PageUp( (sal_uInt16)nDeltaEntries );
2275 : }
2276 0 : pImp->SyncVerThumb();
2277 0 : NotifyEndScroll();
2278 : }
2279 :
2280 0 : void SvTreeListBox::ScrollToAbsPos( long nPos )
2281 : {
2282 0 : pImp->ScrollToAbsPos( nPos );
2283 0 : }
2284 :
2285 0 : void SvTreeListBox::SetSelectionMode( SelectionMode eSelectMode )
2286 : {
2287 0 : eSelMode = eSelectMode;
2288 0 : pImp->SetSelectionMode( eSelectMode );
2289 0 : }
2290 :
2291 0 : void SvTreeListBox::SetDragDropMode( DragDropMode nDDMode )
2292 : {
2293 0 : nDragDropMode = nDDMode;
2294 0 : pImp->SetDragDropMode( nDDMode );
2295 0 : }
2296 :
2297 0 : short SvTreeListBox::GetHeightOffset(const Image& rBmp, Size& aSizeLogic )
2298 : {
2299 0 : short nOffset = 0;
2300 0 : aSizeLogic = rBmp.GetSizePixel();
2301 0 : if( GetEntryHeight() > aSizeLogic.Height() )
2302 0 : nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
2303 0 : return nOffset;
2304 : }
2305 :
2306 0 : short SvTreeListBox::GetHeightOffset(const Font& /* rFont */, Size& aSizeLogic )
2307 : {
2308 0 : short nOffset = 0;
2309 0 : aSizeLogic = Size(GetTextWidth(OUString('X')), GetTextHeight());
2310 0 : if( GetEntryHeight() > aSizeLogic.Height() )
2311 0 : nOffset = ( GetEntryHeight() - (short)aSizeLogic.Height()) / 2;
2312 0 : return nOffset;
2313 : }
2314 :
2315 0 : void SvTreeListBox::SetEntryHeight( SvTreeListEntry* pEntry )
2316 : {
2317 0 : short nHeight, nHeightMax=0;
2318 0 : sal_uInt16 nCount = pEntry->ItemCount();
2319 0 : sal_uInt16 nCur = 0;
2320 0 : SvViewDataEntry* pViewData = GetViewDataEntry( pEntry );
2321 0 : while( nCur < nCount )
2322 : {
2323 0 : SvLBoxItem* pItem = pEntry->GetItem( nCur );
2324 0 : nHeight = (short)(pItem->GetSize( pViewData, nCur ).Height());
2325 0 : if( nHeight > nHeightMax )
2326 0 : nHeightMax = nHeight;
2327 0 : nCur++;
2328 : }
2329 :
2330 0 : if( nHeightMax > nEntryHeight )
2331 : {
2332 0 : nEntryHeight = nHeightMax;
2333 0 : Control::SetFont( GetFont() );
2334 0 : pImp->SetEntryHeight( nHeightMax );
2335 : }
2336 0 : }
2337 :
2338 0 : void SvTreeListBox::SetEntryHeight( short nHeight, bool bAlways )
2339 : {
2340 :
2341 0 : if( bAlways || nHeight > nEntryHeight )
2342 : {
2343 0 : nEntryHeight = nHeight;
2344 0 : if( nEntryHeight )
2345 0 : nTreeFlags |= TREEFLAG_FIXEDHEIGHT;
2346 : else
2347 0 : nTreeFlags &= ~TREEFLAG_FIXEDHEIGHT;
2348 0 : Control::SetFont( GetFont() );
2349 0 : pImp->SetEntryHeight( nHeight );
2350 : }
2351 0 : }
2352 :
2353 :
2354 0 : void SvTreeListBox::AdjustEntryHeight( const Image& rBmp )
2355 : {
2356 0 : Size aSize;
2357 0 : GetHeightOffset( rBmp, aSize );
2358 0 : if( aSize.Height() > nEntryHeight )
2359 : {
2360 0 : nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
2361 0 : pImp->SetEntryHeight( nEntryHeight );
2362 : }
2363 0 : }
2364 :
2365 0 : void SvTreeListBox::AdjustEntryHeight( const Font& rFont )
2366 : {
2367 0 : Size aSize;
2368 0 : GetHeightOffset( rFont, aSize );
2369 0 : if( aSize.Height() > nEntryHeight )
2370 : {
2371 0 : nEntryHeight = (short)aSize.Height() + nEntryHeightOffs;
2372 0 : pImp->SetEntryHeight( nEntryHeight );
2373 : }
2374 0 : }
2375 :
2376 0 : bool SvTreeListBox::Expand( SvTreeListEntry* pParent )
2377 : {
2378 0 : pHdlEntry = pParent;
2379 0 : bool bExpanded = false;
2380 : sal_uInt16 nFlags;
2381 :
2382 0 : if( pParent->HasChildrenOnDemand() )
2383 0 : RequestingChildren( pParent );
2384 0 : if( pParent->HasChildren() )
2385 : {
2386 0 : nImpFlags |= SVLBOX_IS_EXPANDING;
2387 0 : if( ExpandingHdl() )
2388 : {
2389 0 : bExpanded = true;
2390 0 : ExpandListEntry( pParent );
2391 0 : pImp->EntryExpanded( pParent );
2392 0 : pHdlEntry = pParent;
2393 0 : ExpandedHdl();
2394 : }
2395 0 : nFlags = pParent->GetFlags();
2396 0 : nFlags &= ~SV_ENTRYFLAG_NO_NODEBMP;
2397 0 : nFlags |= SV_ENTRYFLAG_HAD_CHILDREN;
2398 0 : pParent->SetFlags( nFlags );
2399 : }
2400 : else
2401 : {
2402 0 : nFlags = pParent->GetFlags();
2403 0 : nFlags |= SV_ENTRYFLAG_NO_NODEBMP;
2404 0 : pParent->SetFlags( nFlags );
2405 0 : GetModel()->InvalidateEntry( pParent ); // repaint
2406 : }
2407 :
2408 : // #i92103#
2409 0 : if ( bExpanded )
2410 : {
2411 0 : pImp->CallEventListeners( VCLEVENT_ITEM_EXPANDED, pParent );
2412 : }
2413 :
2414 0 : return bExpanded;
2415 : }
2416 :
2417 0 : bool SvTreeListBox::Collapse( SvTreeListEntry* pParent )
2418 : {
2419 0 : nImpFlags &= ~SVLBOX_IS_EXPANDING;
2420 0 : pHdlEntry = pParent;
2421 0 : bool bCollapsed = false;
2422 :
2423 0 : if( ExpandingHdl() )
2424 : {
2425 0 : bCollapsed = true;
2426 0 : pImp->CollapsingEntry( pParent );
2427 0 : CollapseListEntry( pParent );
2428 0 : pImp->EntryCollapsed( pParent );
2429 0 : pHdlEntry = pParent;
2430 0 : ExpandedHdl();
2431 : }
2432 :
2433 : // #i92103#
2434 0 : if ( bCollapsed )
2435 : {
2436 0 : pImp->CallEventListeners( VCLEVENT_ITEM_COLLAPSED, pParent );
2437 : }
2438 :
2439 0 : return bCollapsed;
2440 : }
2441 :
2442 0 : bool SvTreeListBox::Select( SvTreeListEntry* pEntry, bool bSelect )
2443 : {
2444 : DBG_ASSERT(pEntry,"Select: Null-Ptr");
2445 0 : bool bRetVal = SelectListEntry( pEntry, bSelect );
2446 : DBG_ASSERT(IsSelected(pEntry)==bSelect,"Select failed");
2447 0 : if( bRetVal )
2448 : {
2449 0 : pImp->EntrySelected( pEntry, bSelect );
2450 0 : pHdlEntry = pEntry;
2451 0 : if( bSelect )
2452 : {
2453 0 : SelectHdl();
2454 0 : CallEventListeners( VCLEVENT_LISTBOX_TREESELECT, pEntry);
2455 : }
2456 : else
2457 0 : DeselectHdl();
2458 : }
2459 0 : return bRetVal;
2460 : }
2461 :
2462 0 : sal_uLong SvTreeListBox::SelectChildren( SvTreeListEntry* pParent, bool bSelect )
2463 : {
2464 0 : pImp->DestroyAnchor();
2465 0 : sal_uLong nRet = 0;
2466 0 : if( !pParent->HasChildren() )
2467 0 : return 0;
2468 0 : sal_uInt16 nRefDepth = pModel->GetDepth( pParent );
2469 0 : SvTreeListEntry* pChild = FirstChild( pParent );
2470 0 : do {
2471 0 : nRet++;
2472 0 : Select( pChild, bSelect );
2473 0 : pChild = Next( pChild );
2474 0 : } while( pChild && pModel->GetDepth( pChild ) > nRefDepth );
2475 0 : return nRet;
2476 : }
2477 :
2478 0 : void SvTreeListBox::SelectAll( bool bSelect, bool )
2479 : {
2480 : pImp->SelAllDestrAnch(
2481 : bSelect,
2482 : true, // delete anchor,
2483 0 : true ); // even when using SINGLE_SELECTION, deselect the cursor
2484 0 : }
2485 :
2486 0 : void SvTreeListBox::ModelHasInsertedTree( SvTreeListEntry* pEntry )
2487 : {
2488 0 : sal_uInt16 nRefDepth = pModel->GetDepth( (SvTreeListEntry*)pEntry );
2489 0 : SvTreeListEntry* pTmp = (SvTreeListEntry*)pEntry;
2490 0 : do
2491 : {
2492 0 : ImpEntryInserted( pTmp );
2493 0 : pTmp = Next( pTmp );
2494 0 : } while( pTmp && nRefDepth < pModel->GetDepth( pTmp ) );
2495 0 : pImp->TreeInserted( (SvTreeListEntry*)pEntry );
2496 0 : }
2497 :
2498 0 : void SvTreeListBox::ModelHasInserted( SvTreeListEntry* pEntry )
2499 : {
2500 0 : ImpEntryInserted( (SvTreeListEntry*)pEntry );
2501 0 : pImp->EntryInserted( (SvTreeListEntry*)pEntry );
2502 0 : }
2503 :
2504 0 : void SvTreeListBox::ModelIsMoving(SvTreeListEntry* pSource,
2505 : SvTreeListEntry* /* pTargetParent */,
2506 : sal_uLong /* nChildPos */ )
2507 : {
2508 0 : pImp->MovingEntry( (SvTreeListEntry*)pSource );
2509 0 : }
2510 :
2511 0 : void SvTreeListBox::ModelHasMoved( SvTreeListEntry* pSource )
2512 : {
2513 0 : pImp->EntryMoved( (SvTreeListEntry*)pSource );
2514 0 : }
2515 :
2516 0 : void SvTreeListBox::ModelIsRemoving( SvTreeListEntry* pEntry )
2517 : {
2518 0 : if(pEdEntry == pEntry)
2519 0 : pEdEntry = NULL;
2520 :
2521 0 : pImp->RemovingEntry( (SvTreeListEntry*)pEntry );
2522 0 : NotifyRemoving( (SvTreeListEntry*)pEntry );
2523 0 : }
2524 :
2525 0 : void SvTreeListBox::ModelHasRemoved( SvTreeListEntry* pEntry )
2526 : {
2527 0 : if ( pEntry == pHdlEntry)
2528 0 : pHdlEntry = NULL;
2529 0 : pImp->EntryRemoved();
2530 0 : }
2531 :
2532 0 : void SvTreeListBox::SetCollapsedNodeBmp( const Image& rBmp)
2533 : {
2534 0 : AdjustEntryHeight( rBmp );
2535 0 : pImp->SetCollapsedNodeBmp( rBmp );
2536 0 : }
2537 :
2538 0 : void SvTreeListBox::SetExpandedNodeBmp( const Image& rBmp )
2539 : {
2540 0 : AdjustEntryHeight( rBmp );
2541 0 : pImp->SetExpandedNodeBmp( rBmp );
2542 0 : }
2543 :
2544 :
2545 0 : void SvTreeListBox::SetFont( const Font& rFont )
2546 : {
2547 :
2548 0 : Font aTempFont( rFont );
2549 0 : Font aOrigFont( GetFont() );
2550 0 : aTempFont.SetTransparent( true );
2551 0 : if (aTempFont == aOrigFont)
2552 0 : return;
2553 0 : Control::SetFont( aTempFont );
2554 :
2555 0 : aTempFont.SetColor(aOrigFont.GetColor());
2556 0 : aTempFont.SetFillColor(aOrigFont.GetFillColor());
2557 0 : aTempFont.SetTransparent(aOrigFont.IsTransparent());
2558 :
2559 0 : if (aTempFont == aOrigFont)
2560 0 : return;
2561 :
2562 0 : AdjustEntryHeightAndRecalc( GetFont() );
2563 : }
2564 :
2565 0 : void SvTreeListBox::AdjustEntryHeightAndRecalc( const Font& rFont )
2566 : {
2567 0 : AdjustEntryHeight( rFont );
2568 : // always invalidate, else things go wrong in SetEntryHeight
2569 0 : RecalcViewData();
2570 0 : }
2571 :
2572 0 : void SvTreeListBox::Paint( const Rectangle& rRect )
2573 : {
2574 0 : Control::Paint( rRect );
2575 0 : if( nTreeFlags & TREEFLAG_RECALCTABS )
2576 0 : SetTabs();
2577 0 : pImp->Paint( rRect );
2578 : //Add visual focus draw
2579 0 : if( !First() )
2580 : {
2581 0 : if( HasFocus() )
2582 : {
2583 0 : long tempHeight = GetTextHeight();
2584 : Rectangle tempRect(
2585 0 : Point(0,0),Size(GetSizePixel().Width(),tempHeight)
2586 0 : );
2587 0 : ShowFocus(tempRect);
2588 : }
2589 :
2590 : else{
2591 0 : HideFocus();
2592 : }
2593 : }
2594 0 : }
2595 :
2596 0 : void SvTreeListBox::MouseButtonDown( const MouseEvent& rMEvt )
2597 : {
2598 0 : pImp->MouseButtonDown( rMEvt );
2599 0 : }
2600 :
2601 0 : void SvTreeListBox::MouseButtonUp( const MouseEvent& rMEvt )
2602 : {
2603 0 : pImp->MouseButtonUp( rMEvt );
2604 0 : }
2605 :
2606 0 : void SvTreeListBox::MouseMove( const MouseEvent& rMEvt )
2607 : {
2608 0 : pImp->MouseMove( rMEvt );
2609 0 : }
2610 :
2611 :
2612 0 : void SvTreeListBox::SetUpdateMode( bool bUpdate )
2613 : {
2614 0 : pImp->SetUpdateMode( bUpdate );
2615 0 : }
2616 :
2617 0 : void SvTreeListBox::SetSpaceBetweenEntries( short nOffsLogic )
2618 : {
2619 0 : if( nOffsLogic != nEntryHeightOffs )
2620 : {
2621 0 : nEntryHeight = nEntryHeight - nEntryHeightOffs;
2622 0 : nEntryHeightOffs = (short)nOffsLogic;
2623 0 : nEntryHeight = nEntryHeight + nOffsLogic;
2624 0 : AdjustEntryHeightAndRecalc( GetFont() );
2625 0 : pImp->SetEntryHeight( nEntryHeight );
2626 : }
2627 0 : }
2628 :
2629 0 : void SvTreeListBox::SetCursor( SvTreeListEntry* pEntry, bool bForceNoSelect )
2630 : {
2631 0 : pImp->SetCursor(pEntry, bForceNoSelect);
2632 0 : }
2633 :
2634 0 : void SvTreeListBox::SetCurEntry( SvTreeListEntry* pEntry )
2635 : {
2636 0 : pImp->SetCurEntry( pEntry );
2637 0 : }
2638 :
2639 0 : Image SvTreeListBox::GetExpandedNodeBmp( ) const
2640 : {
2641 0 : return pImp->GetExpandedNodeBmp( );
2642 : }
2643 :
2644 0 : Point SvTreeListBox::GetEntryPosition( SvTreeListEntry* pEntry ) const
2645 : {
2646 0 : return pImp->GetEntryPosition( pEntry );
2647 : }
2648 :
2649 0 : void SvTreeListBox::ShowEntry( SvTreeListEntry* pEntry )
2650 : {
2651 0 : MakeVisible( pEntry );
2652 0 : }
2653 :
2654 0 : void SvTreeListBox::MakeVisible( SvTreeListEntry* pEntry )
2655 : {
2656 0 : pImp->MakeVisible(pEntry);
2657 0 : }
2658 :
2659 0 : void SvTreeListBox::MakeVisible( SvTreeListEntry* pEntry, bool bMoveToTop )
2660 : {
2661 0 : pImp->MakeVisible( pEntry, bMoveToTop );
2662 0 : }
2663 :
2664 0 : void SvTreeListBox::ModelHasEntryInvalidated( SvTreeListEntry* pEntry )
2665 : {
2666 :
2667 : // reinitialize the separate items of the entries
2668 0 : sal_uInt16 nCount = ((SvTreeListEntry*)pEntry)->ItemCount();
2669 0 : for( sal_uInt16 nIdx = 0; nIdx < nCount; nIdx++ )
2670 : {
2671 0 : SvLBoxItem* pItem = ((SvTreeListEntry*)pEntry)->GetItem( nIdx );
2672 0 : pItem->InitViewData( this, (SvTreeListEntry*)pEntry, 0 );
2673 : }
2674 :
2675 : // repaint
2676 0 : pImp->InvalidateEntry( (SvTreeListEntry*)pEntry );
2677 0 : }
2678 :
2679 0 : void SvTreeListBox::EditItemText( SvTreeListEntry* pEntry, SvLBoxString* pItem,
2680 : const Selection& rSelection )
2681 : {
2682 : DBG_ASSERT(pEntry&&pItem,"EditItemText: Bad params");
2683 0 : if( IsSelected( pEntry ))
2684 : {
2685 0 : pImp->ShowCursor( false );
2686 0 : SelectListEntry( pEntry, false );
2687 0 : PaintEntry( pEntry );
2688 0 : SelectListEntry( pEntry, true );
2689 0 : pImp->ShowCursor( true );
2690 : }
2691 0 : pEdEntry = pEntry;
2692 0 : pEdItem = pItem;
2693 0 : SvLBoxTab* pTab = GetTab( pEntry, pItem );
2694 : DBG_ASSERT(pTab,"EditItemText:Tab not found");
2695 :
2696 0 : Size aItemSize( pItem->GetSize(this, pEntry) );
2697 0 : Point aPos = GetEntryPosition( pEntry );
2698 0 : aPos.Y() += ( nEntryHeight - aItemSize.Height() ) / 2;
2699 0 : aPos.X() = GetTabPos( pEntry, pTab );
2700 0 : long nOutputWidth = pImp->GetOutputSize().Width();
2701 0 : Size aSize( nOutputWidth - aPos.X(), aItemSize.Height() );
2702 0 : sal_uInt16 nPos = std::find( aTabs.begin(), aTabs.end(), pTab ) - aTabs.begin();
2703 0 : if( nPos+1 < (sal_uInt16)aTabs.size() )
2704 : {
2705 0 : SvLBoxTab* pRightTab = aTabs[ nPos + 1 ];
2706 0 : long nRight = GetTabPos( pEntry, pRightTab );
2707 0 : if( nRight <= nOutputWidth )
2708 0 : aSize.Width() = nRight - aPos.X();
2709 : }
2710 0 : Point aOrigin( GetMapMode().GetOrigin() );
2711 0 : aPos += aOrigin; // convert to win coordinates
2712 0 : aSize.Width() -= aOrigin.X();
2713 0 : Rectangle aRect( aPos, aSize );
2714 0 : EditText( pItem->GetText(), aRect, rSelection );
2715 0 : }
2716 :
2717 0 : void SvTreeListBox::EditEntry( SvTreeListEntry* pEntry )
2718 : {
2719 0 : pImp->aEditClickPos = Point( -1, -1 );
2720 0 : ImplEditEntry( pEntry );
2721 0 : }
2722 :
2723 0 : void SvTreeListBox::ImplEditEntry( SvTreeListEntry* pEntry )
2724 : {
2725 0 : if( IsEditingActive() )
2726 0 : EndEditing();
2727 0 : if( !pEntry )
2728 0 : pEntry = GetCurEntry();
2729 0 : if( pEntry )
2730 : {
2731 0 : long nClickX = pImp->aEditClickPos.X();
2732 0 : bool bIsMouseTriggered = nClickX >= 0;
2733 :
2734 0 : SvLBoxString* pItem = NULL;
2735 0 : sal_uInt16 nCount = pEntry->ItemCount();
2736 0 : long nTabPos, nNextTabPos = 0;
2737 0 : for( sal_uInt16 i = 0 ; i < nCount ; i++ )
2738 : {
2739 0 : SvLBoxItem* pTmpItem = pEntry->GetItem( i );
2740 0 : if (pTmpItem->GetType() != SV_ITEM_ID_LBOXSTRING)
2741 0 : continue;
2742 :
2743 0 : SvLBoxTab* pTab = GetTab( pEntry, pTmpItem );
2744 0 : nNextTabPos = -1;
2745 0 : if( i < nCount - 1 )
2746 : {
2747 0 : SvLBoxItem* pNextItem = pEntry->GetItem( i + 1 );
2748 0 : SvLBoxTab* pNextTab = GetTab( pEntry, pNextItem );
2749 0 : nNextTabPos = pNextTab->GetPos();
2750 : }
2751 :
2752 0 : if( pTab && pTab->IsEditable() )
2753 : {
2754 0 : nTabPos = pTab->GetPos();
2755 0 : if( !bIsMouseTriggered || (nClickX > nTabPos && (nNextTabPos == -1 || nClickX < nNextTabPos ) ) )
2756 : {
2757 0 : pItem = static_cast<SvLBoxString*>( pTmpItem );
2758 0 : break;
2759 : }
2760 : }
2761 : }
2762 :
2763 0 : Selection aSel( SELECTION_MIN, SELECTION_MAX );
2764 0 : if( pItem && EditingEntry( pEntry, aSel ) )
2765 : {
2766 0 : SelectAll( false );
2767 0 : MakeVisible( pEntry );
2768 0 : EditItemText( pEntry, pItem, aSel );
2769 : }
2770 : }
2771 0 : }
2772 :
2773 0 : bool SvTreeListBox::AreChildrenTransient() const
2774 : {
2775 0 : return pImp->AreChildrenTransient();
2776 : }
2777 :
2778 0 : void SvTreeListBox::SetChildrenNotTransient()
2779 : {
2780 0 : pImp->SetChildrenNotTransient();
2781 0 : }
2782 :
2783 0 : void SvTreeListBox::EditedText( const OUString& rStr )
2784 :
2785 : {
2786 0 : if(pEdEntry) // we have to check if this entry is null that means that it is removed while editing
2787 : {
2788 0 : if( EditedEntry( pEdEntry, rStr ) )
2789 : {
2790 0 : ((SvLBoxString*)pEdItem)->SetText( rStr );
2791 0 : pModel->InvalidateEntry( pEdEntry );
2792 : }
2793 0 : if( GetSelectionCount() == 0 )
2794 0 : Select( pEdEntry );
2795 0 : if( GetSelectionMode() == MULTIPLE_SELECTION && !GetCurEntry() )
2796 0 : SetCurEntry( pEdEntry );
2797 : }
2798 0 : }
2799 :
2800 0 : SvTreeListEntry* SvTreeListBox::GetDropTarget( const Point& rPos )
2801 : {
2802 : // scroll
2803 0 : if( rPos.Y() < 12 )
2804 : {
2805 0 : ImplShowTargetEmphasis(pTargetEntry, false);
2806 0 : ScrollOutputArea( +1 );
2807 : }
2808 : else
2809 : {
2810 0 : Size aSize( pImp->GetOutputSize() );
2811 0 : if( rPos.Y() > aSize.Height() - 12 )
2812 : {
2813 0 : ImplShowTargetEmphasis(pTargetEntry, false);
2814 0 : ScrollOutputArea( -1 );
2815 : }
2816 : }
2817 :
2818 0 : SvTreeListEntry* pTarget = pImp->GetEntry( rPos );
2819 : // when dropping in a vacant space, use the last entry
2820 0 : if( !pTarget )
2821 0 : return (SvTreeListEntry*)LastVisible();
2822 0 : else if( (GetDragDropMode() & SV_DRAGDROP_ENABLE_TOP) &&
2823 0 : pTarget == First() && rPos.Y() < 6 )
2824 0 : return 0;
2825 :
2826 0 : return pTarget;
2827 : }
2828 :
2829 :
2830 0 : SvTreeListEntry* SvTreeListBox::GetEntry( const Point& rPos, bool bHit ) const
2831 : {
2832 0 : SvTreeListEntry* pEntry = pImp->GetEntry( rPos );
2833 0 : if( pEntry && bHit )
2834 : {
2835 0 : long nLine = pImp->GetEntryLine( pEntry );
2836 0 : if( !(pImp->EntryReallyHit( pEntry, rPos, nLine)) )
2837 0 : return 0;
2838 : }
2839 0 : return pEntry;
2840 : }
2841 :
2842 0 : SvTreeListEntry* SvTreeListBox::GetCurEntry() const
2843 : {
2844 0 : return pImp->GetCurEntry();
2845 : }
2846 :
2847 0 : void SvTreeListBox::ImplInitStyle()
2848 : {
2849 :
2850 0 : const WinBits nWindowStyle = GetStyle();
2851 :
2852 0 : nTreeFlags |= TREEFLAG_RECALCTABS;
2853 0 : if( nWindowStyle & WB_SORT )
2854 : {
2855 0 : GetModel()->SetSortMode( SortAscending );
2856 0 : GetModel()->SetCompareHdl( LINK(this,SvTreeListBox,DefaultCompare));
2857 : }
2858 : else
2859 : {
2860 0 : GetModel()->SetSortMode( SortNone );
2861 0 : GetModel()->SetCompareHdl( Link() );
2862 : }
2863 0 : pImp->SetStyle( nWindowStyle );
2864 0 : pImp->Resize();
2865 0 : Invalidate();
2866 0 : }
2867 :
2868 0 : void SvTreeListBox::PaintEntry( SvTreeListEntry* pEntry )
2869 : {
2870 : DBG_ASSERT(pEntry,"PaintEntry:No Entry");
2871 0 : if( pEntry )
2872 0 : pImp->PaintEntry( pEntry );
2873 0 : }
2874 :
2875 0 : void SvTreeListBox::InvalidateEntry( SvTreeListEntry* pEntry )
2876 : {
2877 : DBG_ASSERT(pEntry,"InvalidateEntry:No Entry");
2878 0 : if( pEntry )
2879 : {
2880 0 : GetModel()->InvalidateEntry( pEntry );
2881 : }
2882 0 : }
2883 :
2884 0 : long SvTreeListBox::PaintEntry(SvTreeListEntry* pEntry,long nLine,sal_uInt16 nTabFlags)
2885 : {
2886 0 : return PaintEntry1(pEntry,nLine,nTabFlags);
2887 : }
2888 :
2889 0 : long SvTreeListBox::PaintEntry1(SvTreeListEntry* pEntry,long nLine,sal_uInt16 nTabFlags,
2890 : bool bHasClipRegion )
2891 : {
2892 :
2893 0 : Rectangle aRect; // multi purpose
2894 :
2895 0 : bool bHorSBar = pImp->HasHorScrollBar();
2896 0 : PreparePaint( pEntry );
2897 :
2898 0 : pImp->UpdateContextBmpWidthMax( pEntry );
2899 :
2900 0 : if( nTreeFlags & TREEFLAG_RECALCTABS )
2901 0 : SetTabs();
2902 :
2903 0 : short nTempEntryHeight = GetEntryHeight();
2904 0 : long nWidth = pImp->GetOutputSize().Width();
2905 :
2906 : // Did we turn on the scrollbar within PreparePaints? If yes, we have to set
2907 : // the ClipRegion anew.
2908 0 : if( !bHorSBar && pImp->HasHorScrollBar() )
2909 0 : SetClipRegion( Region(pImp->GetClipRegionRect()) );
2910 :
2911 0 : Point aEntryPos( GetMapMode().GetOrigin() );
2912 0 : aEntryPos.X() *= -1; // conversion document coordinates
2913 0 : long nMaxRight = nWidth + aEntryPos.X() - 1;
2914 :
2915 0 : Color aBackupTextColor( GetTextColor() );
2916 0 : Font aBackupFont( GetFont() );
2917 0 : Color aBackupColor = GetFillColor();
2918 :
2919 0 : bool bCurFontIsSel = false;
2920 0 : bool bInUse = pEntry->HasInUseEmphasis();
2921 : // if a ClipRegion was set from outside, we don't have to reset it
2922 0 : const WinBits nWindowStyle = GetStyle();
2923 0 : const bool bResetClipRegion = !bHasClipRegion;
2924 0 : const bool bHideSelection = (nWindowStyle & WB_HIDESELECTION) !=0 && !HasFocus();
2925 0 : const StyleSettings& rSettings = GetSettings().GetStyleSettings();
2926 :
2927 0 : Font aHighlightFont( GetFont() );
2928 0 : const Color aHighlightTextColor( rSettings.GetHighlightTextColor() );
2929 0 : aHighlightFont.SetColor( aHighlightTextColor );
2930 :
2931 0 : Size aRectSize( 0, nTempEntryHeight );
2932 :
2933 0 : if( !bHasClipRegion && nWindowStyle & WB_HSCROLL )
2934 : {
2935 0 : SetClipRegion( Region(pImp->GetClipRegionRect()) );
2936 0 : bHasClipRegion = true;
2937 : }
2938 :
2939 0 : SvViewDataEntry* pViewDataEntry = GetViewDataEntry( pEntry );
2940 :
2941 0 : sal_uInt16 nTabCount = aTabs.size();
2942 0 : sal_uInt16 nItemCount = pEntry->ItemCount();
2943 0 : sal_uInt16 nCurTab = 0;
2944 0 : sal_uInt16 nCurItem = 0;
2945 :
2946 0 : while( nCurTab < nTabCount && nCurItem < nItemCount )
2947 : {
2948 0 : SvLBoxTab* pTab = aTabs[ nCurTab ];
2949 0 : sal_uInt16 nNextTab = nCurTab + 1;
2950 0 : SvLBoxTab* pNextTab = nNextTab < nTabCount ? aTabs[nNextTab] : 0;
2951 0 : SvLBoxItem* pItem = nCurItem < nItemCount ? pEntry->GetItem(nCurItem) : 0;
2952 :
2953 0 : sal_uInt16 nFlags = pTab->nFlags;
2954 0 : Size aSize( pItem->GetSize( pViewDataEntry, nCurItem ));
2955 0 : long nTabPos = GetTabPos( pEntry, pTab );
2956 :
2957 : long nNextTabPos;
2958 0 : if( pNextTab )
2959 0 : nNextTabPos = GetTabPos( pEntry, pNextTab );
2960 : else
2961 : {
2962 0 : nNextTabPos = nMaxRight;
2963 0 : if( nTabPos > nMaxRight )
2964 0 : nNextTabPos += 50;
2965 : }
2966 :
2967 : long nX;
2968 0 : if( pTab->nFlags & SV_LBOXTAB_ADJUST_RIGHT )
2969 : // avoid cutting the right edge off the tab separation
2970 0 : nX = nTabPos + pTab->CalcOffset(aSize.Width(), (nNextTabPos-SV_TAB_BORDER-1) -nTabPos);
2971 : else
2972 0 : nX = nTabPos + pTab->CalcOffset(aSize.Width(), nNextTabPos-nTabPos);
2973 :
2974 0 : if( nFlags & nTabFlags )
2975 : {
2976 0 : if( !bHasClipRegion && nX + aSize.Width() >= nMaxRight )
2977 : {
2978 0 : SetClipRegion( Region(pImp->GetClipRegionRect()) );
2979 0 : bHasClipRegion = true;
2980 : }
2981 0 : aEntryPos.X() = nX;
2982 0 : aEntryPos.Y() = nLine;
2983 :
2984 : // set background pattern/color
2985 :
2986 0 : Wallpaper aWallpaper = GetBackground();
2987 :
2988 0 : int bSelTab = nFlags & SV_LBOXTAB_SHOW_SELECTION;
2989 0 : sal_uInt16 nItemType = pItem->GetType();
2990 :
2991 0 : if (pViewDataEntry->IsHighlighted() && bSelTab && !pViewDataEntry->IsCursored())
2992 : {
2993 0 : Color aNewWallColor = rSettings.GetHighlightColor();
2994 0 : if ( !bInUse || nItemType != SV_ITEM_ID_LBOXCONTEXTBMP )
2995 : {
2996 : // if the face color is bright then the deactive color is also bright
2997 : // -> so you can't see any deactive selection
2998 0 : if ( bHideSelection && !rSettings.GetFaceColor().IsBright() &&
2999 0 : aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright() )
3000 0 : aNewWallColor = rSettings.GetDeactiveColor();
3001 : // set font color to highlight
3002 0 : if ( !bCurFontIsSel )
3003 : {
3004 0 : SetTextColor( aHighlightTextColor );
3005 0 : Control::SetFont( aHighlightFont );
3006 0 : bCurFontIsSel = true;
3007 : }
3008 : }
3009 0 : aWallpaper.SetColor( aNewWallColor );
3010 : }
3011 : else // no selection
3012 : {
3013 0 : if( bInUse && nItemType == SV_ITEM_ID_LBOXCONTEXTBMP )
3014 0 : aWallpaper.SetColor( rSettings.GetFieldColor() );
3015 0 : else if( bCurFontIsSel )
3016 : {
3017 0 : bCurFontIsSel = false;
3018 0 : SetTextColor( aBackupTextColor );
3019 0 : Control::SetFont( aBackupFont );
3020 : }
3021 : }
3022 :
3023 : // draw background
3024 0 : if( !(nTreeFlags & TREEFLAG_USESEL))
3025 : {
3026 : // only draw the area that is used by the item
3027 0 : aRectSize.Width() = aSize.Width();
3028 0 : aRect.SetPos( aEntryPos );
3029 0 : aRect.SetSize( aRectSize );
3030 : }
3031 : else
3032 : {
3033 : // draw from the current to the next tab
3034 0 : if( nCurTab != 0 )
3035 0 : aRect.Left() = nTabPos;
3036 : else
3037 : // if we're in the 0th tab, always draw from column 0 --
3038 : // else we get problems with centered tabs
3039 0 : aRect.Left() = 0;
3040 0 : aRect.Top() = nLine;
3041 0 : aRect.Bottom() = nLine + nTempEntryHeight - 1;
3042 0 : if( pNextTab )
3043 : {
3044 : long nRight;
3045 0 : nRight = GetTabPos(pEntry,pNextTab)-1;
3046 0 : if( nRight > nMaxRight )
3047 0 : nRight = nMaxRight;
3048 0 : aRect.Right() = nRight;
3049 : }
3050 : else
3051 0 : aRect.Right() = nMaxRight;
3052 : }
3053 : // A custom selection that starts at a tab position > 0, do not fill
3054 : // the background of the 0th item, else e.g. we might not be able to
3055 : // realize tab listboxes with lines.
3056 0 : if( !(nCurTab==0 && (nTreeFlags & TREEFLAG_USESEL) && nFirstSelTab) )
3057 : {
3058 0 : SetFillColor( aWallpaper.GetColor() );
3059 : // this case may occur for smaller horizontal resizes
3060 0 : if( aRect.Left() < aRect.Right() )
3061 0 : DrawRect( aRect );
3062 : }
3063 : // draw item
3064 : // center vertically
3065 0 : aEntryPos.Y() += ( nTempEntryHeight - aSize.Height() ) / 2;
3066 0 : pItem->Paint(aEntryPos, *this, pViewDataEntry, pEntry);
3067 :
3068 : // division line between tabs
3069 0 : if (pNextTab && pItem->GetType() == SV_ITEM_ID_LBOXSTRING &&
3070 : // not at the right edge of the window!
3071 0 : aRect.Right() < nMaxRight)
3072 : {
3073 0 : aRect.Left() = aRect.Right() - SV_TAB_BORDER;
3074 0 : DrawRect( aRect );
3075 : }
3076 :
3077 0 : SetFillColor( aBackupColor );
3078 : }
3079 0 : nCurItem++;
3080 0 : nCurTab++;
3081 : }
3082 0 : if( pViewDataEntry->IsCursored() && !HasFocus() )
3083 : {
3084 : // cursor emphasis
3085 0 : SetFillColor();
3086 0 : Color aOldLineColor = GetLineColor();
3087 0 : SetLineColor( Color( COL_BLACK ) );
3088 0 : aRect = GetFocusRect( pEntry, nLine );
3089 0 : aRect.Top()++;
3090 0 : aRect.Bottom()--;
3091 0 : DrawRect( aRect );
3092 0 : SetLineColor( aOldLineColor );
3093 0 : SetFillColor( aBackupColor );
3094 : }
3095 :
3096 0 : if( bCurFontIsSel )
3097 : {
3098 0 : SetTextColor( aBackupTextColor );
3099 0 : Control::SetFont( aBackupFont );
3100 : }
3101 :
3102 : sal_uInt16 nFirstDynTabPos;
3103 0 : SvLBoxTab* pFirstDynamicTab = GetFirstDynamicTab( nFirstDynTabPos );
3104 0 : long nDynTabPos = GetTabPos( pEntry, pFirstDynamicTab );
3105 0 : nDynTabPos += pImp->nNodeBmpTabDistance;
3106 0 : nDynTabPos += pImp->nNodeBmpWidth / 2;
3107 0 : nDynTabPos += 4; // 4 pixels of buffer, so the node bitmap is not too close
3108 : // to the next tab
3109 :
3110 0 : if( (!(pEntry->GetFlags() & SV_ENTRYFLAG_NO_NODEBMP)) &&
3111 0 : (nWindowStyle & WB_HASBUTTONS) && pFirstDynamicTab &&
3112 0 : ( pEntry->HasChildren() || pEntry->HasChildrenOnDemand() ) )
3113 : {
3114 : // find first tab and check if the node bitmap extends into it
3115 0 : sal_uInt16 nNextTab = nFirstDynTabPos;
3116 : SvLBoxTab* pNextTab;
3117 0 : do
3118 : {
3119 0 : nNextTab++;
3120 0 : pNextTab = nNextTab < nTabCount ? aTabs[nNextTab] : 0;
3121 0 : } while( pNextTab && pNextTab->IsDynamic() );
3122 :
3123 0 : if( !pNextTab || (GetTabPos( pEntry, pNextTab ) > nDynTabPos) )
3124 : {
3125 0 : if((nWindowStyle & WB_HASBUTTONSATROOT) || pModel->GetDepth(pEntry) > 0)
3126 : {
3127 0 : Point aPos( GetTabPos(pEntry,pFirstDynamicTab), nLine );
3128 0 : aPos.X() += pImp->nNodeBmpTabDistance;
3129 :
3130 0 : const Image* pImg = 0;
3131 :
3132 0 : if( IsExpanded(pEntry) )
3133 0 : pImg = &pImp->GetExpandedNodeBmp( );
3134 : else
3135 : {
3136 0 : if( (!pEntry->HasChildren()) && pEntry->HasChildrenOnDemand() &&
3137 0 : (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
3138 0 : pImp->GetDontKnowNodeBmp().GetSizePixel().Width() )
3139 0 : pImg = &pImp->GetDontKnowNodeBmp( );
3140 : else
3141 0 : pImg = &pImp->GetCollapsedNodeBmp( );
3142 : }
3143 0 : aPos.Y() += (nTempEntryHeight - pImg->GetSizePixel().Height()) / 2;
3144 :
3145 0 : sal_uInt16 nStyle = 0;
3146 0 : if ( !IsEnabled() )
3147 0 : nStyle |= IMAGE_DRAW_DISABLE;
3148 :
3149 : //native
3150 0 : bool bNativeOK = false;
3151 0 : if ( IsNativeControlSupported( CTRL_LISTNODE, PART_ENTIRE_CONTROL) )
3152 : {
3153 0 : ImplControlValue aControlValue;
3154 0 : Rectangle aCtrlRegion( aPos, pImg->GetSizePixel() );
3155 0 : ControlState nState = 0;
3156 :
3157 0 : if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED;
3158 :
3159 0 : if ( IsExpanded(pEntry) )
3160 0 : aControlValue.setTristateVal( BUTTONVALUE_ON );//expanded node
3161 : else
3162 : {
3163 0 : if( (!pEntry->HasChildren() ) &&
3164 0 : pEntry->HasChildrenOnDemand() &&
3165 0 : (!(pEntry->GetFlags() & SV_ENTRYFLAG_HAD_CHILDREN)) &&
3166 0 : pImp->GetDontKnowNodeBmp().GetSizePixel().Width()
3167 : )
3168 0 : aControlValue.setTristateVal( BUTTONVALUE_DONTKNOW ); //dont know
3169 : else
3170 0 : aControlValue.setTristateVal( BUTTONVALUE_OFF ); //collapsed node
3171 : }
3172 :
3173 : bNativeOK = DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL,
3174 0 : aCtrlRegion, nState, aControlValue, OUString() );
3175 : }
3176 :
3177 0 : if( !bNativeOK) {
3178 0 : DrawImage( aPos, *pImg ,nStyle);
3179 : }
3180 : }
3181 : }
3182 : }
3183 :
3184 :
3185 0 : if( bHasClipRegion && bResetClipRegion )
3186 0 : SetClipRegion();
3187 0 : return 0; // nRowLen;
3188 : }
3189 :
3190 0 : void SvTreeListBox::PreparePaint( SvTreeListEntry* )
3191 : {
3192 0 : }
3193 :
3194 0 : Rectangle SvTreeListBox::GetFocusRect( SvTreeListEntry* pEntry, long nLine )
3195 : {
3196 0 : Size aSize;
3197 0 : Rectangle aRect;
3198 0 : aRect.Top() = nLine;
3199 0 : aSize.Height() = GetEntryHeight();
3200 :
3201 0 : long nRealWidth = pImp->GetOutputSize().Width();
3202 0 : nRealWidth -= GetMapMode().GetOrigin().X();
3203 :
3204 : sal_uInt16 nCurTab;
3205 0 : SvLBoxTab* pTab = GetFirstTab( SV_LBOXTAB_SHOW_SELECTION, nCurTab );
3206 0 : long nTabPos = 0;
3207 0 : if( pTab )
3208 0 : nTabPos = GetTabPos( pEntry, pTab );
3209 : long nNextTabPos;
3210 0 : if( pTab && nCurTab < aTabs.size() - 1 )
3211 : {
3212 0 : SvLBoxTab* pNextTab = aTabs[ nCurTab + 1 ];
3213 0 : nNextTabPos = GetTabPos( pEntry, pNextTab );
3214 : }
3215 : else
3216 : {
3217 0 : nNextTabPos = nRealWidth;
3218 0 : if( nTabPos > nRealWidth )
3219 0 : nNextTabPos += 50;
3220 : }
3221 :
3222 0 : bool bUserSelection = ( nTreeFlags & TREEFLAG_USESEL ) != 0;
3223 0 : if( !bUserSelection )
3224 : {
3225 0 : if( pTab && nCurTab < pEntry->ItemCount() )
3226 : {
3227 0 : SvLBoxItem* pItem = pEntry->GetItem( nCurTab );
3228 0 : aSize.Width() = pItem->GetSize( this, pEntry ).Width();
3229 0 : if( !aSize.Width() )
3230 0 : aSize.Width() = 15;
3231 0 : long nX = nTabPos; //GetTabPos( pEntry, pTab );
3232 : // alignment
3233 0 : nX += pTab->CalcOffset( aSize.Width(), nNextTabPos - nTabPos );
3234 0 : aRect.Left() = nX;
3235 : // make sure that first and last letter aren't cut off slightly
3236 0 : aRect.SetSize( aSize );
3237 0 : if( aRect.Left() > 0 )
3238 0 : aRect.Left()--;
3239 0 : aRect.Right()++;
3240 : }
3241 : }
3242 : else
3243 : {
3244 : // if SelTab != 0, we have to calculate also
3245 0 : if( nFocusWidth == -1 || nFirstSelTab )
3246 : {
3247 0 : SvLBoxTab* pLastTab = NULL; // default to select whole width
3248 :
3249 : sal_uInt16 nLastTab;
3250 0 : GetLastTab(SV_LBOXTAB_SHOW_SELECTION,nLastTab);
3251 0 : nLastTab++;
3252 0 : if( nLastTab < aTabs.size() ) // is there another one?
3253 0 : pLastTab = aTabs[ nLastTab ];
3254 :
3255 0 : aSize.Width() = pLastTab ? pLastTab->GetPos() : 0x0fffffff;
3256 0 : nFocusWidth = (short)aSize.Width();
3257 0 : if( pTab )
3258 0 : nFocusWidth = nFocusWidth - (short)nTabPos; //pTab->GetPos();
3259 : }
3260 : else
3261 : {
3262 0 : aSize.Width() = nFocusWidth;
3263 0 : if( pTab )
3264 : {
3265 0 : if( nCurTab )
3266 0 : aSize.Width() += nTabPos;
3267 : else
3268 0 : aSize.Width() += pTab->GetPos(); // Tab0 always from the leftmost position
3269 : }
3270 : }
3271 : // if selection starts with 0th tab, draw from column 0 on
3272 0 : if( nCurTab != 0 )
3273 : {
3274 0 : aRect.Left() = nTabPos;
3275 0 : aSize.Width() -= nTabPos;
3276 : }
3277 0 : aRect.SetSize( aSize );
3278 : }
3279 : // adjust right edge because of clipping
3280 0 : if( aRect.Right() >= nRealWidth )
3281 : {
3282 0 : aRect.Right() = nRealWidth-1;
3283 0 : nFocusWidth = (short)aRect.GetWidth();
3284 : }
3285 0 : return aRect;
3286 : }
3287 :
3288 :
3289 0 : sal_IntPtr SvTreeListBox::GetTabPos( SvTreeListEntry* pEntry, SvLBoxTab* pTab)
3290 : {
3291 : DBG_ASSERT(pTab,"No Tab");
3292 0 : sal_IntPtr nPos = pTab->GetPos();
3293 0 : if( pTab->IsDynamic() )
3294 : {
3295 0 : sal_uInt16 nDepth = pModel->GetDepth( pEntry );
3296 0 : nDepth = nDepth * (sal_uInt16)nIndent;
3297 0 : nPos += (sal_IntPtr)nDepth;
3298 : }
3299 0 : return nPos;
3300 : }
3301 :
3302 0 : SvLBoxItem* SvTreeListBox::GetItem_Impl( SvTreeListEntry* pEntry, long nX,
3303 : SvLBoxTab** ppTab, sal_uInt16 nEmptyWidth )
3304 : {
3305 0 : SvLBoxItem* pItemClicked = 0;
3306 0 : sal_uInt16 nTabCount = aTabs.size();
3307 0 : sal_uInt16 nItemCount = pEntry->ItemCount();
3308 0 : SvLBoxTab* pTab = aTabs.front();
3309 0 : SvLBoxItem* pItem = pEntry->GetItem(0);
3310 0 : sal_uInt16 nNextItem = 1;
3311 0 : nX -= GetMapMode().GetOrigin().X();
3312 0 : long nRealWidth = pImp->GetOutputSize().Width();
3313 0 : nRealWidth -= GetMapMode().GetOrigin().X();
3314 :
3315 : while( true )
3316 : {
3317 0 : SvLBoxTab* pNextTab=nNextItem<nTabCount ? aTabs[nNextItem] : 0;
3318 0 : long nStart = GetTabPos( pEntry, pTab );
3319 :
3320 : long nNextTabPos;
3321 0 : if( pNextTab )
3322 0 : nNextTabPos = GetTabPos( pEntry, pNextTab );
3323 : else
3324 : {
3325 0 : nNextTabPos = nRealWidth;
3326 0 : if( nStart > nRealWidth )
3327 0 : nNextTabPos += 50;
3328 : }
3329 :
3330 0 : Size aItemSize( pItem->GetSize(this, pEntry));
3331 0 : nStart += pTab->CalcOffset( aItemSize.Width(), nNextTabPos - nStart );
3332 0 : long nLen = aItemSize.Width();
3333 0 : if( pNextTab )
3334 : {
3335 0 : long nTabWidth = GetTabPos( pEntry, pNextTab ) - nStart;
3336 0 : if( nTabWidth < nLen )
3337 0 : nLen = nTabWidth;
3338 : }
3339 :
3340 0 : if( !nLen )
3341 0 : nLen = nEmptyWidth;
3342 :
3343 0 : if( nX >= nStart && nX < (nStart+nLen ) )
3344 : {
3345 0 : pItemClicked = pItem;
3346 0 : if( ppTab )
3347 : {
3348 0 : *ppTab = pTab;
3349 0 : break;
3350 : }
3351 : }
3352 0 : if( nNextItem >= nItemCount || nNextItem >= nTabCount)
3353 : break;
3354 0 : pTab = aTabs[ nNextItem ];
3355 0 : pItem = pEntry->GetItem( nNextItem );
3356 0 : nNextItem++;
3357 : }
3358 0 : return pItemClicked;
3359 : }
3360 :
3361 0 : long SvTreeListBox::getPreferredDimensions(std::vector<long> &rWidths) const
3362 : {
3363 0 : long nHeight = 0;
3364 0 : rWidths.clear();
3365 0 : SvTreeListEntry* pEntry = First();
3366 0 : while (pEntry)
3367 : {
3368 0 : sal_uInt16 nCount = pEntry->ItemCount();
3369 0 : sal_uInt16 nCurPos = 0;
3370 0 : if (nCount > rWidths.size())
3371 0 : rWidths.resize(nCount);
3372 0 : while (nCurPos < nCount)
3373 : {
3374 0 : SvLBoxItem* pItem = pEntry->GetItem( nCurPos );
3375 0 : long nWidth = pItem->GetSize(this, pEntry).Width();
3376 0 : if (nWidth)
3377 : {
3378 0 : nWidth += SV_TAB_BORDER * 2;
3379 0 : if (nWidth > rWidths[nCurPos])
3380 0 : rWidths[nCurPos] = nWidth;
3381 : }
3382 0 : ++nCurPos;
3383 : }
3384 0 : pEntry = Next( pEntry );
3385 0 : nHeight += GetEntryHeight();
3386 : }
3387 0 : return nHeight;
3388 : }
3389 :
3390 0 : Size SvTreeListBox::GetOptimalSize() const
3391 : {
3392 0 : std::vector<long> aWidths;
3393 0 : Size aRet(0, getPreferredDimensions(aWidths));
3394 0 : for (size_t i = 0; i < aWidths.size(); ++i)
3395 0 : aRet.Width() += aWidths[i];
3396 0 : if (GetStyle() & WB_BORDER)
3397 : {
3398 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
3399 0 : aRet.Width() += rStyleSettings.GetBorderSize() * 2;
3400 0 : aRet.Height() += rStyleSettings.GetBorderSize() * 2;
3401 : }
3402 0 : long nMinWidth = nMinWidthInChars * approximate_char_width();
3403 0 : aRet.Width() = std::max(aRet.Width(), nMinWidth);
3404 0 : return aRet;
3405 : }
3406 :
3407 0 : SvLBoxItem* SvTreeListBox::GetItem(SvTreeListEntry* pEntry,long nX,SvLBoxTab** ppTab)
3408 : {
3409 0 : return GetItem_Impl( pEntry, nX, ppTab, 0 );
3410 : }
3411 :
3412 0 : SvLBoxItem* SvTreeListBox::GetItem(SvTreeListEntry* pEntry,long nX )
3413 : {
3414 : SvLBoxTab* pDummyTab;
3415 0 : return GetItem_Impl( pEntry, nX, &pDummyTab, 0 );
3416 : }
3417 :
3418 0 : void SvTreeListBox::AddTab(long nTabPos,sal_uInt16 nFlags,void* pUserData )
3419 : {
3420 0 : nFocusWidth = -1;
3421 0 : SvLBoxTab* pTab = new SvLBoxTab( nTabPos, nFlags );
3422 0 : pTab->SetUserData( pUserData );
3423 0 : aTabs.push_back( pTab );
3424 0 : if( nTreeFlags & TREEFLAG_USESEL )
3425 : {
3426 0 : sal_uInt16 nPos = aTabs.size() - 1;
3427 0 : if( nPos >= nFirstSelTab && nPos <= nLastSelTab )
3428 0 : pTab->nFlags |= SV_LBOXTAB_SHOW_SELECTION;
3429 : else
3430 : // string items usually have to be selected -- turn this off
3431 : // explicitly
3432 0 : pTab->nFlags &= ~SV_LBOXTAB_SHOW_SELECTION;
3433 : }
3434 0 : }
3435 :
3436 :
3437 :
3438 0 : SvLBoxTab* SvTreeListBox::GetFirstDynamicTab( sal_uInt16& rPos ) const
3439 : {
3440 0 : sal_uInt16 nCurTab = 0;
3441 0 : sal_uInt16 nTabCount = aTabs.size();
3442 0 : while( nCurTab < nTabCount )
3443 : {
3444 0 : SvLBoxTab* pTab = aTabs[nCurTab];
3445 0 : if( pTab->nFlags & SV_LBOXTAB_DYNAMIC )
3446 : {
3447 0 : rPos = nCurTab;
3448 0 : return pTab;
3449 : }
3450 0 : nCurTab++;
3451 : }
3452 0 : return 0;
3453 : }
3454 :
3455 0 : SvLBoxTab* SvTreeListBox::GetFirstDynamicTab() const
3456 : {
3457 : sal_uInt16 nDummy;
3458 0 : return GetFirstDynamicTab( nDummy );
3459 : }
3460 :
3461 0 : SvLBoxTab* SvTreeListBox::GetTab( SvTreeListEntry* pEntry, SvLBoxItem* pItem) const
3462 : {
3463 0 : sal_uInt16 nPos = pEntry->GetPos( pItem );
3464 0 : return aTabs[ nPos ];
3465 : }
3466 :
3467 0 : void SvTreeListBox::ClearTabList()
3468 : {
3469 0 : sal_uInt16 nTabCount = aTabs.size();
3470 0 : while( nTabCount )
3471 : {
3472 0 : nTabCount--;
3473 0 : SvLBoxTab* pDelTab = aTabs[ nTabCount ];
3474 0 : delete pDelTab;
3475 : }
3476 0 : aTabs.clear();
3477 0 : }
3478 :
3479 :
3480 0 : Size SvTreeListBox::GetOutputSizePixel() const
3481 : {
3482 0 : Size aSize = pImp->GetOutputSize();
3483 0 : return aSize;
3484 : }
3485 :
3486 0 : void SvTreeListBox::NotifyBeginScroll()
3487 : {
3488 0 : }
3489 :
3490 0 : void SvTreeListBox::NotifyEndScroll()
3491 : {
3492 0 : }
3493 :
3494 0 : void SvTreeListBox::NotifyScrolling( long )
3495 : {
3496 0 : }
3497 :
3498 0 : void SvTreeListBox::NotifyScrolled()
3499 : {
3500 0 : aScrolledHdl.Call( this );
3501 0 : }
3502 :
3503 0 : void SvTreeListBox::NotifyInvalidating()
3504 : {
3505 0 : }
3506 :
3507 0 : void SvTreeListBox::Invalidate( sal_uInt16 nInvalidateFlags )
3508 : {
3509 0 : if( nFocusWidth == -1 )
3510 : // to make sure that the control doesn't show the wrong focus rectangle
3511 : // after painting
3512 0 : pImp->RecalcFocusRect();
3513 0 : NotifyInvalidating();
3514 0 : Control::Invalidate( nInvalidateFlags );
3515 0 : pImp->Invalidate();
3516 0 : }
3517 :
3518 0 : void SvTreeListBox::Invalidate( const Rectangle& rRect, sal_uInt16 nInvalidateFlags )
3519 : {
3520 0 : if( nFocusWidth == -1 )
3521 : // to make sure that the control doesn't show the wrong focus rectangle
3522 : // after painting
3523 0 : pImp->RecalcFocusRect();
3524 0 : NotifyInvalidating();
3525 0 : Control::Invalidate( rRect, nInvalidateFlags );
3526 0 : }
3527 :
3528 :
3529 0 : void SvTreeListBox::SetHighlightRange( sal_uInt16 nStart, sal_uInt16 nEnd)
3530 : {
3531 :
3532 : sal_uInt16 nTemp;
3533 0 : nTreeFlags |= TREEFLAG_USESEL;
3534 0 : if( nStart > nEnd )
3535 : {
3536 0 : nTemp = nStart;
3537 0 : nStart = nEnd;
3538 0 : nEnd = nTemp;
3539 : }
3540 : // select all tabs that lie within the area
3541 0 : nTreeFlags |= TREEFLAG_RECALCTABS;
3542 0 : nFirstSelTab = nStart;
3543 0 : nLastSelTab = nEnd;
3544 0 : pImp->RecalcFocusRect();
3545 0 : }
3546 :
3547 0 : void SvTreeListBox::Command( const CommandEvent& rCEvt )
3548 : {
3549 : // FIXME gnumake2 resync to DEV300_m84
3550 0 : pImp->Command( rCEvt );
3551 0 : }
3552 :
3553 :
3554 0 : void SvTreeListBox::RemoveParentKeepChildren( SvTreeListEntry* pParent )
3555 : {
3556 : DBG_ASSERT(pParent,"RemoveParentKeepChildren:No Parent");
3557 0 : SvTreeListEntry* pNewParent = GetParent( pParent );
3558 0 : if( pParent->HasChildren())
3559 : {
3560 0 : SvTreeListEntry* pChild = FirstChild( pParent );
3561 0 : while( pChild )
3562 : {
3563 0 : pModel->Move( pChild, pNewParent, TREELIST_APPEND );
3564 0 : pChild = FirstChild( pParent );
3565 : }
3566 : }
3567 0 : pModel->Remove( pParent );
3568 0 : }
3569 :
3570 0 : SvLBoxTab* SvTreeListBox::GetFirstTab( sal_uInt16 nFlagMask, sal_uInt16& rPos )
3571 : {
3572 0 : sal_uInt16 nTabCount = aTabs.size();
3573 0 : for( sal_uInt16 nPos = 0; nPos < nTabCount; nPos++ )
3574 : {
3575 0 : SvLBoxTab* pTab = aTabs[ nPos ];
3576 0 : if( (pTab->nFlags & nFlagMask) )
3577 : {
3578 0 : rPos = nPos;
3579 0 : return pTab;
3580 : }
3581 : }
3582 0 : rPos = 0xffff;
3583 0 : return 0;
3584 : }
3585 :
3586 0 : SvLBoxTab* SvTreeListBox::GetLastTab( sal_uInt16 nFlagMask, sal_uInt16& rTabPos )
3587 : {
3588 0 : sal_uInt16 nPos = (sal_uInt16)aTabs.size();
3589 0 : while( nPos )
3590 : {
3591 0 : --nPos;
3592 0 : SvLBoxTab* pTab = aTabs[ nPos ];
3593 0 : if( (pTab->nFlags & nFlagMask) )
3594 : {
3595 0 : rTabPos = nPos;
3596 0 : return pTab;
3597 : }
3598 : }
3599 0 : rTabPos = 0xffff;
3600 0 : return 0;
3601 : }
3602 :
3603 0 : void SvTreeListBox::RequestHelp( const HelpEvent& rHEvt )
3604 : {
3605 0 : if( !pImp->RequestHelp( rHEvt ) )
3606 0 : Control::RequestHelp( rHEvt );
3607 0 : }
3608 :
3609 0 : void SvTreeListBox::CursorMoved( SvTreeListEntry* )
3610 : {
3611 0 : }
3612 :
3613 0 : IMPL_LINK( SvTreeListBox, DefaultCompare, SvSortData*, pData )
3614 : {
3615 0 : const SvTreeListEntry* pLeft = pData->pLeft;
3616 0 : const SvTreeListEntry* pRight = pData->pRight;
3617 0 : OUString aLeft( ((SvLBoxString*)(pLeft->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText());
3618 0 : OUString aRight( ((SvLBoxString*)(pRight->GetFirstItem(SV_ITEM_ID_LBOXSTRING)))->GetText());
3619 0 : pImp->UpdateStringSorter();
3620 0 : return pImp->m_pStringSorter->compare(aLeft, aRight);
3621 : }
3622 :
3623 0 : void SvTreeListBox::ModelNotification( sal_uInt16 nActionId, SvTreeListEntry* pEntry1,
3624 : SvTreeListEntry* pEntry2, sal_uLong nPos )
3625 : {
3626 0 : SolarMutexGuard aSolarGuard;
3627 :
3628 0 : if( nActionId == LISTACTION_CLEARING )
3629 0 : CancelTextEditing();
3630 :
3631 0 : SvListView::ModelNotification( nActionId, pEntry1, pEntry2, nPos );
3632 0 : switch( nActionId )
3633 : {
3634 : case LISTACTION_INSERTED:
3635 : {
3636 0 : SvTreeListEntry* pEntry( dynamic_cast< SvTreeListEntry* >( pEntry1 ) );
3637 0 : if ( !pEntry )
3638 : {
3639 : SAL_WARN( "svtools.contnr", "SvTreeListBox::ModelNotification: invalid entry!" );
3640 0 : break;
3641 : }
3642 :
3643 0 : SvLBoxContextBmp* pBmpItem = static_cast< SvLBoxContextBmp* >( pEntry->GetFirstItem( SV_ITEM_ID_LBOXCONTEXTBMP ) );
3644 0 : if ( !pBmpItem )
3645 0 : break;
3646 0 : const Image& rBitmap1( pBmpItem->GetBitmap1() );
3647 0 : const Image& rBitmap2( pBmpItem->GetBitmap2() );
3648 0 : short nMaxWidth = short( std::max( rBitmap1.GetSizePixel().Width(), rBitmap2.GetSizePixel().Width() ) );
3649 0 : nMaxWidth = pImp->UpdateContextBmpWidthVector( pEntry, nMaxWidth );
3650 0 : if( nMaxWidth > nContextBmpWidthMax )
3651 : {
3652 0 : nContextBmpWidthMax = nMaxWidth;
3653 0 : SetTabs();
3654 : }
3655 0 : if (get_width_request() == -1)
3656 0 : queue_resize();
3657 : }
3658 0 : break;
3659 :
3660 : case LISTACTION_RESORTING:
3661 0 : SetUpdateMode( false );
3662 0 : break;
3663 :
3664 : case LISTACTION_RESORTED:
3665 : // after a selection: show first entry and also keep the selection
3666 0 : MakeVisible( (SvTreeListEntry*)pModel->First(), true );
3667 0 : SetUpdateMode( true );
3668 0 : break;
3669 :
3670 : case LISTACTION_CLEARED:
3671 0 : if( IsUpdateMode() )
3672 0 : Update();
3673 0 : break;
3674 0 : }
3675 0 : }
3676 :
3677 0 : void SvTreeListBox::EndSelection()
3678 : {
3679 0 : pImp->EndSelection();
3680 0 : }
3681 :
3682 0 : void SvTreeListBox::RepaintScrollBars() const
3683 : {
3684 0 : ((SvTreeListBox*)this)->pImp->RepaintScrollBars();
3685 0 : }
3686 :
3687 0 : ScrollBar *SvTreeListBox::GetVScroll()
3688 : {
3689 0 : return &((SvTreeListBox*)this)->pImp->aVerSBar;
3690 : }
3691 :
3692 0 : ScrollBar *SvTreeListBox::GetHScroll()
3693 : {
3694 0 : return &((SvTreeListBox*)this)->pImp->aHorSBar;
3695 : }
3696 :
3697 0 : void SvTreeListBox::EnableAsyncDrag( bool b )
3698 : {
3699 0 : pImp->EnableAsyncDrag( b );
3700 0 : }
3701 :
3702 0 : SvTreeListEntry* SvTreeListBox::GetFirstEntryInView() const
3703 : {
3704 0 : Point aPos;
3705 0 : return GetEntry( aPos );
3706 : }
3707 :
3708 0 : SvTreeListEntry* SvTreeListBox::GetNextEntryInView(SvTreeListEntry* pEntry ) const
3709 : {
3710 0 : SvTreeListEntry* pNext = (SvTreeListEntry*)NextVisible( pEntry );
3711 0 : if( pNext )
3712 : {
3713 0 : Point aPos( GetEntryPosition(pNext) );
3714 0 : const Size& rSize = pImp->GetOutputSize();
3715 0 : if( aPos.Y() < 0 || aPos.Y() >= rSize.Height() )
3716 0 : return 0;
3717 : }
3718 0 : return pNext;
3719 : }
3720 :
3721 0 : SvTreeListEntry* SvTreeListBox::GetLastEntryInView() const
3722 : {
3723 0 : SvTreeListEntry* pEntry = GetFirstEntryInView();
3724 0 : SvTreeListEntry* pNext = 0;
3725 0 : while( pEntry )
3726 : {
3727 0 : pNext = (SvTreeListEntry*)NextVisible( pEntry );
3728 0 : if( pNext )
3729 : {
3730 0 : Point aPos( GetEntryPosition(pNext) );
3731 0 : const Size& rSize = pImp->GetOutputSize();
3732 0 : if( aPos.Y() < 0 || aPos.Y() + GetEntryHeight() >= rSize.Height() )
3733 0 : break;
3734 : else
3735 0 : pEntry = pNext;
3736 : }
3737 : else
3738 0 : break;
3739 : }
3740 0 : return pEntry;
3741 : }
3742 :
3743 0 : void SvTreeListBox::ShowFocusRect( const SvTreeListEntry* pEntry )
3744 : {
3745 0 : pImp->ShowFocusRect( pEntry );
3746 0 : }
3747 :
3748 0 : void SvTreeListBox::DataChanged( const DataChangedEvent& rDCEvt )
3749 : {
3750 0 : if( (rDCEvt.GetType()==DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
3751 : {
3752 0 : nEntryHeight = 0; // _together_ with true of 1. par (bFont) of InitSettings() a zero-height
3753 : // forces complete recalc of heights!
3754 0 : InitSettings( true, true, true );
3755 0 : Invalidate();
3756 : }
3757 : else
3758 0 : Control::DataChanged( rDCEvt );
3759 0 : }
3760 :
3761 0 : void SvTreeListBox::StateChanged( StateChangedType eType )
3762 : {
3763 0 : if( eType == STATE_CHANGE_ENABLE )
3764 0 : Invalidate( INVALIDATE_CHILDREN );
3765 :
3766 0 : Control::StateChanged( eType );
3767 :
3768 0 : if ( eType == STATE_CHANGE_STYLE )
3769 0 : ImplInitStyle();
3770 0 : }
3771 :
3772 0 : void SvTreeListBox::InitSettings(bool bFont, bool bForeground, bool bBackground)
3773 : {
3774 0 : const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
3775 0 : if( bFont )
3776 : {
3777 0 : Font aFont;
3778 0 : aFont = rStyleSettings.GetFieldFont();
3779 0 : aFont.SetColor( rStyleSettings.GetWindowTextColor() );
3780 0 : SetPointFont( aFont );
3781 0 : AdjustEntryHeightAndRecalc( aFont );
3782 : }
3783 :
3784 0 : if( bForeground || bFont )
3785 : {
3786 0 : SetTextColor( rStyleSettings.GetFieldTextColor() );
3787 0 : SetTextFillColor();
3788 : }
3789 :
3790 0 : if( bBackground )
3791 0 : SetBackground( rStyleSettings.GetFieldColor() );
3792 :
3793 : // always try to re-create default-SvLBoxButtonData
3794 0 : if( pCheckButtonData && pCheckButtonData->HasDefaultImages() )
3795 0 : pCheckButtonData->SetDefaultImages( this );
3796 0 : }
3797 :
3798 0 : bool SvTreeListBox::IsCellFocusEnabled() const
3799 : {
3800 0 : return pImp->IsCellFocusEnabled();
3801 : }
3802 :
3803 0 : bool SvTreeListBox::SetCurrentTabPos( sal_uInt16 _nNewPos )
3804 : {
3805 0 : return pImp->SetCurrentTabPos( _nNewPos );
3806 : }
3807 :
3808 0 : sal_uInt16 SvTreeListBox::GetCurrentTabPos() const
3809 : {
3810 0 : return pImp->GetCurrentTabPos();
3811 : }
3812 :
3813 0 : void SvTreeListBox::InitStartEntry()
3814 : {
3815 0 : if( !pImp->pStartEntry )
3816 0 : pImp->pStartEntry = GetModel()->First();
3817 0 : }
3818 :
3819 0 : PopupMenu* SvTreeListBox::CreateContextMenu( void )
3820 : {
3821 0 : return NULL;
3822 : }
3823 :
3824 0 : void SvTreeListBox::ExcecuteContextMenuAction( sal_uInt16 )
3825 : {
3826 : DBG_WARNING( "SvTreeListBox::ExcecuteContextMenuAction(): now there's happening nothing!" );
3827 0 : }
3828 :
3829 0 : void SvTreeListBox::EnableContextMenuHandling( void )
3830 : {
3831 : DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );
3832 :
3833 0 : pImp->bContextMenuHandling = true;
3834 0 : }
3835 :
3836 0 : void SvTreeListBox::EnableContextMenuHandling( bool b )
3837 : {
3838 : DBG_ASSERT( pImp, "-SvTreeListBox::EnableContextMenuHandling(): No implementation!" );
3839 :
3840 0 : pImp->bContextMenuHandling = b;
3841 0 : }
3842 :
3843 0 : bool SvTreeListBox::IsContextMenuHandlingEnabled( void ) const
3844 : {
3845 : DBG_ASSERT( pImp, "-SvTreeListBox::IsContextMenuHandlingEnabled(): No implementation!" );
3846 :
3847 0 : return pImp->bContextMenuHandling;
3848 : }
3849 :
3850 0 : void SvTreeListBox::EnableList( bool _bEnable )
3851 : {
3852 : // call base class method
3853 0 : Window::Enable( _bEnable != false );
3854 : // then paint immediately
3855 0 : Paint( Rectangle( Point(), GetSizePixel() ) );
3856 0 : }
3857 :
3858 0 : ::com::sun::star::uno::Reference< XAccessible > SvTreeListBox::CreateAccessible()
3859 : {
3860 0 : Window* pParent = GetAccessibleParentWindow();
3861 : DBG_ASSERT( pParent, "SvTreeListBox::CreateAccessible - accessible parent not found" );
3862 :
3863 0 : ::com::sun::star::uno::Reference< XAccessible > xAccessible;
3864 0 : if ( pParent )
3865 : {
3866 0 : ::com::sun::star::uno::Reference< XAccessible > xAccParent = pParent->GetAccessible();
3867 0 : if ( xAccParent.is() )
3868 : {
3869 : // need to be done here to get the vclxwindow later on in the accessbile
3870 0 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > xTemp(GetComponentInterface());
3871 0 : xAccessible = pImp->m_aFactoryAccess.getFactory().createAccessibleTreeListBox( *this, xAccParent );
3872 0 : }
3873 : }
3874 0 : return xAccessible;
3875 : }
3876 :
3877 0 : void SvTreeListBox::FillAccessibleEntryStateSet( SvTreeListEntry* pEntry, ::utl::AccessibleStateSetHelper& rStateSet ) const
3878 : {
3879 : DBG_ASSERT( pEntry, "SvTreeListBox::FillAccessibleEntryStateSet: invalid entry" );
3880 :
3881 0 : if ( pEntry->HasChildrenOnDemand() || pEntry->HasChildren() )
3882 : {
3883 0 : rStateSet.AddState( AccessibleStateType::EXPANDABLE );
3884 0 : if ( IsExpanded( pEntry ) )
3885 0 : rStateSet.AddState( (sal_Int16)AccessibleStateType::EXPANDED );
3886 : }
3887 :
3888 0 : if ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED )
3889 0 : rStateSet.AddState( AccessibleStateType::CHECKED );
3890 0 : if ( IsEntryVisible( pEntry ) )
3891 0 : rStateSet.AddState( AccessibleStateType::VISIBLE );
3892 0 : if ( IsSelected( pEntry ) )
3893 0 : rStateSet.AddState( AccessibleStateType::SELECTED );
3894 0 : if ( IsEnabled() )
3895 : {
3896 0 : rStateSet.AddState( AccessibleStateType::ENABLED );
3897 0 : rStateSet.AddState( AccessibleStateType::FOCUSABLE );
3898 0 : rStateSet.AddState( AccessibleStateType::SELECTABLE );
3899 0 : SvViewDataEntry* pViewDataNewCur = GetViewDataEntry(pEntry);
3900 0 : if (pViewDataNewCur && pViewDataNewCur->HasFocus())
3901 0 : rStateSet.AddState( AccessibleStateType::FOCUSED );
3902 : }
3903 0 : }
3904 :
3905 0 : Rectangle SvTreeListBox::GetBoundingRect( SvTreeListEntry* pEntry )
3906 : {
3907 0 : Point aPos = GetEntryPosition( pEntry );
3908 0 : Rectangle aRect = GetFocusRect( pEntry, aPos.Y() );
3909 0 : return aRect;
3910 : }
3911 :
3912 0 : void SvTreeListBox::EnableCellFocus()
3913 : {
3914 0 : pImp->EnableCellFocus();
3915 0 : }
3916 :
3917 0 : void SvTreeListBox::CallImplEventListeners(sal_uLong nEvent, void* pData)
3918 : {
3919 0 : CallEventListeners(nEvent, pData);
3920 0 : }
3921 :
3922 0 : void SvTreeListBox::FillAccessibleStateSet( ::utl::AccessibleStateSetHelper& /*rStateSet*/ ) const
3923 : {
3924 0 : }
3925 :
3926 0 : void SvTreeListBox::set_min_width_in_chars(sal_Int32 nChars)
3927 : {
3928 0 : nMinWidthInChars = nChars;
3929 0 : queue_resize();
3930 0 : }
3931 :
3932 0 : bool SvTreeListBox::set_property(const OString &rKey, const OString &rValue)
3933 : {
3934 0 : if (rKey == "min-width-chars")
3935 : {
3936 0 : set_min_width_in_chars(rValue.toInt32());
3937 : }
3938 : else
3939 0 : return Control::set_property(rKey, rValue);
3940 0 : return true;
3941 : }
3942 :
3943 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|