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