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