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