/src/libreoffice/toolkit/source/controls/tree/treecontrolpeer.cxx
Line | Count | Source |
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 | | #include <com/sun/star/graphic/GraphicProvider.hpp> |
22 | | #include <com/sun/star/lang/DisposedException.hpp> |
23 | | #include <com/sun/star/view/SelectionType.hpp> |
24 | | #include <com/sun/star/util/VetoException.hpp> |
25 | | #include <o3tl/any.hxx> |
26 | | #include <helper/property.hxx> |
27 | | |
28 | | #include <com/sun/star/awt/tree/XMutableTreeNode.hpp> |
29 | | #include <controls/treecontrolpeer.hxx> |
30 | | #include <comphelper/processfactory.hxx> |
31 | | #include <comphelper/propertyvalue.hxx> |
32 | | |
33 | | #include <cppuhelper/implbase.hxx> |
34 | | #include <rtl/ref.hxx> |
35 | | #include <vcl/graph.hxx> |
36 | | #include <vcl/svapp.hxx> |
37 | | #include <vcl/toolkit/treelistbox.hxx> |
38 | | #include <vcl/toolkit/treelistentry.hxx> |
39 | | #include <vcl/toolkit/viewdataentry.hxx> |
40 | | #include <vcl/toolkit/svlbitm.hxx> |
41 | | #include <vcl/unohelp.hxx> |
42 | | |
43 | | #include <map> |
44 | | #include <memory> |
45 | | #include <list> |
46 | | |
47 | | using namespace ::com::sun::star; |
48 | | using namespace css::uno; |
49 | | using namespace css::lang; |
50 | | using namespace css::awt::tree; |
51 | | using namespace css::beans; |
52 | | using namespace css::view; |
53 | | using namespace css::container; |
54 | | using namespace css::util; |
55 | | using namespace css::graphic; |
56 | | |
57 | | namespace { |
58 | | |
59 | | struct LockGuard |
60 | | { |
61 | | public: |
62 | | explicit LockGuard( sal_Int32& rLock ) |
63 | 0 | : mrLock( rLock ) |
64 | 0 | { |
65 | 0 | rLock++; |
66 | 0 | } |
67 | | |
68 | | ~LockGuard() |
69 | 0 | { |
70 | 0 | mrLock--; |
71 | 0 | } |
72 | | |
73 | | sal_Int32& mrLock; |
74 | | }; |
75 | | |
76 | | |
77 | | class ImplContextGraphicItem : public SvLBoxContextBmp |
78 | | { |
79 | | public: |
80 | | ImplContextGraphicItem( Image const & rI1, Image const & rI2, bool bExpanded) |
81 | 0 | : SvLBoxContextBmp(rI1, rI2, bExpanded) {} |
82 | | |
83 | | OUString msExpandedGraphicURL; |
84 | | OUString msCollapsedGraphicURL; |
85 | | }; |
86 | | |
87 | | |
88 | | } |
89 | | |
90 | | class UnoTreeListBoxImpl : public SvTreeListBox |
91 | | { |
92 | | public: |
93 | | UnoTreeListBoxImpl( TreeControlPeer* pPeer, vcl::Window* pParent, WinBits nWinStyle ); |
94 | | virtual ~UnoTreeListBoxImpl() override; |
95 | | virtual void dispose() override; |
96 | | |
97 | | void insert( SvTreeListEntry* pEntry, SvTreeListEntry* pParent, sal_uInt32 nPos ); |
98 | | |
99 | | virtual void RequestingChildren( SvTreeListEntry* pParent ) override; |
100 | | |
101 | | virtual bool EditingEntry( SvTreeListEntry* pEntry ) override; |
102 | | virtual bool EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText ) override; |
103 | | |
104 | | DECL_LINK(OnSelectionChangeHdl, SvTreeListBox*, void); |
105 | | DECL_LINK(OnExpandingHdl, SvTreeListBox*, bool); |
106 | | DECL_LINK(OnExpandedHdl, SvTreeListBox*, void); |
107 | | |
108 | | private: |
109 | | rtl::Reference< TreeControlPeer > mxPeer; |
110 | | }; |
111 | | |
112 | | |
113 | | namespace { |
114 | | |
115 | | class UnoTreeListItem : public SvLBoxString |
116 | | { |
117 | | public: |
118 | | UnoTreeListItem(); |
119 | | |
120 | | void InitViewData( SvTreeListBox*,SvTreeListEntry*,SvViewDataItem * = nullptr ) override; |
121 | | void SetImage( const Image& rImage ); |
122 | 0 | const OUString& GetGraphicURL() const { return maGraphicURL;} |
123 | | void SetGraphicURL( const OUString& rGraphicURL ); |
124 | | virtual void Paint(const Point& rPos, SvTreeListBox& rOutDev, vcl::RenderContext& rRenderContext, |
125 | | const SvViewDataEntry* pView, const SvTreeListEntry& rEntry) override; |
126 | | std::unique_ptr<SvLBoxItem> Clone( SvLBoxItem const * pSource ) const override; |
127 | | |
128 | | private: |
129 | | OUString maGraphicURL; |
130 | | Image maImage; |
131 | | }; |
132 | | |
133 | | } |
134 | | |
135 | | class UnoTreeListEntry : public SvTreeListEntry |
136 | | { |
137 | | public: |
138 | | UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer ); |
139 | | virtual ~UnoTreeListEntry() override; |
140 | | |
141 | | Reference< XTreeNode > mxNode; |
142 | | TreeControlPeer* mpPeer; |
143 | | }; |
144 | | |
145 | | TreeControlPeer::TreeControlPeer() |
146 | 0 | : maSelectionListeners( *this ) |
147 | 0 | , maTreeExpansionListeners( *this ) |
148 | 0 | , maTreeEditListeners( *this ) |
149 | 0 | , mbIsRootDisplayed(false) |
150 | 0 | , mpTreeImpl( nullptr ) |
151 | 0 | , mnEditLock( 0 ) |
152 | 0 | { |
153 | 0 | } |
154 | | |
155 | | |
156 | | TreeControlPeer::~TreeControlPeer() |
157 | 0 | { |
158 | 0 | if( mpTreeImpl ) |
159 | 0 | mpTreeImpl->Clear(); |
160 | 0 | } |
161 | | |
162 | | |
163 | | void TreeControlPeer::addEntry( UnoTreeListEntry* pEntry ) |
164 | 0 | { |
165 | 0 | if( pEntry && pEntry->mxNode.is() ) |
166 | 0 | { |
167 | 0 | if( !mpTreeNodeMap ) |
168 | 0 | { |
169 | 0 | mpTreeNodeMap.reset( new TreeNodeMap ); |
170 | 0 | } |
171 | |
|
172 | 0 | (*mpTreeNodeMap)[ pEntry->mxNode ] = pEntry; |
173 | 0 | } |
174 | 0 | } |
175 | | |
176 | | |
177 | | void TreeControlPeer::removeEntry( UnoTreeListEntry const * pEntry ) |
178 | 0 | { |
179 | 0 | if( mpTreeNodeMap && pEntry && pEntry->mxNode.is() ) |
180 | 0 | { |
181 | 0 | TreeNodeMap::iterator aIter( mpTreeNodeMap->find( pEntry->mxNode ) ); |
182 | 0 | if( aIter != mpTreeNodeMap->end() ) |
183 | 0 | { |
184 | 0 | mpTreeNodeMap->erase( aIter ); |
185 | 0 | } |
186 | 0 | } |
187 | 0 | } |
188 | | |
189 | | |
190 | | UnoTreeListEntry* TreeControlPeer::getEntry( const Reference< XTreeNode >& xNode, bool bThrow /* = true */ ) |
191 | 0 | { |
192 | 0 | if( mpTreeNodeMap ) |
193 | 0 | { |
194 | 0 | TreeNodeMap::iterator aIter( mpTreeNodeMap->find( xNode ) ); |
195 | 0 | if( aIter != mpTreeNodeMap->end() ) |
196 | 0 | return (*aIter).second; |
197 | 0 | } |
198 | | |
199 | 0 | if( bThrow ) |
200 | 0 | throw IllegalArgumentException(); |
201 | | |
202 | 0 | return nullptr; |
203 | 0 | } |
204 | | |
205 | | |
206 | | vcl::Window* TreeControlPeer::createVclControl( vcl::Window* pParent, sal_Int64 nWinStyle ) |
207 | 0 | { |
208 | 0 | mpTreeImpl = VclPtr<UnoTreeListBoxImpl>::Create( this, pParent, nWinStyle ); |
209 | 0 | return mpTreeImpl; |
210 | 0 | } |
211 | | |
212 | | |
213 | | /** called from the UnoTreeListBoxImpl when it gets deleted */ |
214 | | void TreeControlPeer::disposeControl() |
215 | 0 | { |
216 | 0 | mpTreeNodeMap.reset(); |
217 | 0 | mpTreeImpl = nullptr; |
218 | 0 | } |
219 | | |
220 | | |
221 | | UnoTreeListEntry* TreeControlPeer::createEntry( const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParent, sal_uInt32 nPos /* = TREELIST_APPEND */ ) |
222 | 0 | { |
223 | 0 | UnoTreeListEntry* pEntry = nullptr; |
224 | 0 | if( mpTreeImpl ) |
225 | 0 | { |
226 | 0 | Image aImage; |
227 | 0 | pEntry = new UnoTreeListEntry( xNode, this ); |
228 | 0 | pEntry->AddItem(std::make_unique<ImplContextGraphicItem>(aImage, aImage, true)); |
229 | |
|
230 | 0 | std::unique_ptr<UnoTreeListItem> pUnoItem(new UnoTreeListItem); |
231 | |
|
232 | 0 | if( !xNode->getNodeGraphicURL().isEmpty() ) |
233 | 0 | { |
234 | 0 | pUnoItem->SetGraphicURL( xNode->getNodeGraphicURL() ); |
235 | 0 | Image aNodeImage; |
236 | 0 | loadImage( xNode->getNodeGraphicURL(), aNodeImage ); |
237 | 0 | pUnoItem->SetImage( aNodeImage ); |
238 | 0 | mpTreeImpl->AdjustEntryHeight( aNodeImage ); |
239 | 0 | } |
240 | |
|
241 | 0 | pEntry->AddItem(std::move(pUnoItem)); |
242 | |
|
243 | 0 | mpTreeImpl->insert( pEntry, pParent, nPos ); |
244 | |
|
245 | 0 | if( !msDefaultExpandedGraphicURL.isEmpty() ) |
246 | 0 | mpTreeImpl->SetExpandedEntryBmp( pEntry, maDefaultExpandedImage ); |
247 | |
|
248 | 0 | if( !msDefaultCollapsedGraphicURL.isEmpty() ) |
249 | 0 | mpTreeImpl->SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage ); |
250 | |
|
251 | 0 | updateEntry( pEntry ); |
252 | 0 | } |
253 | 0 | return pEntry; |
254 | 0 | } |
255 | | |
256 | | |
257 | | void TreeControlPeer::updateEntry( UnoTreeListEntry* pEntry ) |
258 | 0 | { |
259 | 0 | bool bChanged = false; |
260 | 0 | if( !(pEntry && pEntry->mxNode.is() && mpTreeImpl) ) |
261 | 0 | return; |
262 | | |
263 | 0 | const OUString aValue( getEntryString( pEntry->mxNode->getDisplayValue() ) ); |
264 | 0 | UnoTreeListItem* pUnoItem = dynamic_cast< UnoTreeListItem* >( &pEntry->GetItem( 1 ) ); |
265 | 0 | if( pUnoItem ) |
266 | 0 | { |
267 | 0 | if( aValue != pUnoItem->GetText() ) |
268 | 0 | { |
269 | 0 | pUnoItem->SetText( aValue ); |
270 | 0 | bChanged = true; |
271 | 0 | } |
272 | |
|
273 | 0 | if( pUnoItem->GetGraphicURL() != pEntry->mxNode->getNodeGraphicURL() ) |
274 | 0 | { |
275 | 0 | Image aImage; |
276 | 0 | if( loadImage( pEntry->mxNode->getNodeGraphicURL(), aImage ) ) |
277 | 0 | { |
278 | 0 | pUnoItem->SetGraphicURL( pEntry->mxNode->getNodeGraphicURL() ); |
279 | 0 | pUnoItem->SetImage( aImage ); |
280 | 0 | mpTreeImpl->AdjustEntryHeight( aImage ); |
281 | 0 | bChanged = true; |
282 | 0 | } |
283 | 0 | } |
284 | 0 | } |
285 | |
|
286 | 0 | if( bool(pEntry->mxNode->hasChildrenOnDemand()) != pEntry->HasChildrenOnDemand() ) |
287 | 0 | { |
288 | 0 | pEntry->EnableChildrenOnDemand( pEntry->mxNode->hasChildrenOnDemand() ); |
289 | 0 | bChanged = true; |
290 | 0 | } |
291 | |
|
292 | 0 | ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( &pEntry->GetItem( 0 ) ); |
293 | 0 | if( pContextGraphicItem ) |
294 | 0 | { |
295 | 0 | if( pContextGraphicItem->msExpandedGraphicURL != pEntry->mxNode->getExpandedGraphicURL() ) |
296 | 0 | { |
297 | 0 | Image aImage; |
298 | 0 | if( loadImage( pEntry->mxNode->getExpandedGraphicURL(), aImage ) ) |
299 | 0 | { |
300 | 0 | pContextGraphicItem->msExpandedGraphicURL = pEntry->mxNode->getExpandedGraphicURL(); |
301 | 0 | mpTreeImpl->SetExpandedEntryBmp( pEntry, aImage ); |
302 | 0 | bChanged = true; |
303 | 0 | } |
304 | 0 | } |
305 | 0 | if( pContextGraphicItem->msCollapsedGraphicURL != pEntry->mxNode->getCollapsedGraphicURL() ) |
306 | 0 | { |
307 | 0 | Image aImage; |
308 | 0 | if( loadImage( pEntry->mxNode->getCollapsedGraphicURL(), aImage ) ) |
309 | 0 | { |
310 | 0 | pContextGraphicItem->msCollapsedGraphicURL = pEntry->mxNode->getCollapsedGraphicURL(); |
311 | 0 | mpTreeImpl->SetCollapsedEntryBmp( pEntry, aImage ); |
312 | 0 | bChanged = true; |
313 | 0 | } |
314 | 0 | } |
315 | 0 | } |
316 | |
|
317 | 0 | if( bChanged ) |
318 | 0 | mpTreeImpl->GetModel()->InvalidateEntry( pEntry ); |
319 | 0 | } |
320 | | |
321 | | |
322 | | void TreeControlPeer::onSelectionChanged() |
323 | 0 | { |
324 | 0 | Reference< XInterface > xSource( getXWeak() ); |
325 | 0 | EventObject aEvent( xSource ); |
326 | 0 | maSelectionListeners.selectionChanged( aEvent ); |
327 | 0 | } |
328 | | |
329 | | |
330 | | void TreeControlPeer::onRequestChildNodes( const Reference< XTreeNode >& xNode ) |
331 | 0 | { |
332 | 0 | try |
333 | 0 | { |
334 | 0 | Reference< XInterface > xSource( getXWeak() ); |
335 | 0 | TreeExpansionEvent aEvent( xSource, xNode ); |
336 | 0 | maTreeExpansionListeners.requestChildNodes( aEvent ); |
337 | 0 | } |
338 | 0 | catch( Exception& ) |
339 | 0 | { |
340 | 0 | } |
341 | 0 | } |
342 | | |
343 | | |
344 | | bool TreeControlPeer::onExpanding( const Reference< XTreeNode >& xNode, bool bExpanding ) |
345 | 0 | { |
346 | 0 | try |
347 | 0 | { |
348 | 0 | Reference< XInterface > xSource( getXWeak() ); |
349 | 0 | TreeExpansionEvent aEvent( xSource, xNode ); |
350 | 0 | if( bExpanding ) |
351 | 0 | { |
352 | 0 | maTreeExpansionListeners.treeExpanding( aEvent ); |
353 | 0 | } |
354 | 0 | else |
355 | 0 | { |
356 | 0 | maTreeExpansionListeners.treeCollapsing( aEvent ); |
357 | 0 | } |
358 | 0 | } |
359 | 0 | catch( Exception& ) |
360 | 0 | { |
361 | 0 | return false; |
362 | 0 | } |
363 | 0 | return true; |
364 | 0 | } |
365 | | |
366 | | |
367 | | void TreeControlPeer::onExpanded( const Reference< XTreeNode >& xNode, bool bExpanding ) |
368 | 0 | { |
369 | 0 | try |
370 | 0 | { |
371 | 0 | Reference< XInterface > xSource( getXWeak() ); |
372 | 0 | TreeExpansionEvent aEvent( xSource, xNode ); |
373 | |
|
374 | 0 | if( bExpanding ) |
375 | 0 | { |
376 | 0 | maTreeExpansionListeners.treeExpanded( aEvent ); |
377 | 0 | } |
378 | 0 | else |
379 | 0 | { |
380 | 0 | maTreeExpansionListeners.treeCollapsed( aEvent ); |
381 | 0 | } |
382 | 0 | } |
383 | 0 | catch( Exception& ) |
384 | 0 | { |
385 | 0 | } |
386 | 0 | } |
387 | | |
388 | | |
389 | | void TreeControlPeer::fillTree( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel ) |
390 | 0 | { |
391 | 0 | rTree.Clear(); |
392 | |
|
393 | 0 | if( !xDataModel.is() ) |
394 | 0 | return; |
395 | | |
396 | 0 | Reference< XTreeNode > xRootNode( xDataModel->getRoot() ); |
397 | 0 | if( !xRootNode.is() ) |
398 | 0 | return; |
399 | | |
400 | 0 | if( mbIsRootDisplayed ) |
401 | 0 | { |
402 | 0 | addNode( rTree, xRootNode, nullptr ); |
403 | 0 | } |
404 | 0 | else |
405 | 0 | { |
406 | 0 | const sal_Int32 nChildCount = xRootNode->getChildCount(); |
407 | 0 | for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) |
408 | 0 | addNode( rTree, xRootNode->getChildAt( nChild ), nullptr ); |
409 | 0 | } |
410 | 0 | } |
411 | | |
412 | | |
413 | | void TreeControlPeer::addNode( UnoTreeListBoxImpl& rTree, const Reference< XTreeNode >& xNode, UnoTreeListEntry* pParentEntry ) |
414 | 0 | { |
415 | 0 | if( xNode.is() ) |
416 | 0 | { |
417 | 0 | UnoTreeListEntry* pEntry = createEntry( xNode, pParentEntry, TREELIST_APPEND ); |
418 | 0 | const sal_Int32 nChildCount = xNode->getChildCount(); |
419 | 0 | for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) |
420 | 0 | addNode( rTree, xNode->getChildAt( nChild ), pEntry ); |
421 | 0 | } |
422 | 0 | } |
423 | | |
424 | | |
425 | | UnoTreeListBoxImpl& TreeControlPeer::getTreeListBoxOrThrow() const |
426 | 0 | { |
427 | 0 | if( !mpTreeImpl ) |
428 | 0 | throw DisposedException(); |
429 | 0 | return *mpTreeImpl; |
430 | 0 | } |
431 | | |
432 | | |
433 | | void TreeControlPeer::ChangeNodesSelection( const Any& rSelection, bool bSelect, bool bSetSelection ) |
434 | 0 | { |
435 | 0 | SolarMutexGuard aGuard; |
436 | |
|
437 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
438 | |
|
439 | 0 | Reference< XTreeNode > xTempNode; |
440 | |
|
441 | 0 | Sequence<Reference<XTreeNode>> pNodes; |
442 | 0 | sal_Int32 nCount = 0; |
443 | |
|
444 | 0 | if( rSelection.hasValue() ) |
445 | 0 | { |
446 | 0 | switch( rSelection.getValueTypeClass() ) |
447 | 0 | { |
448 | 0 | case TypeClass_INTERFACE: |
449 | 0 | { |
450 | 0 | rSelection >>= xTempNode; |
451 | 0 | if( xTempNode.is() ) |
452 | 0 | { |
453 | 0 | nCount = 1; |
454 | 0 | pNodes = {xTempNode}; |
455 | 0 | } |
456 | 0 | break; |
457 | 0 | } |
458 | 0 | case TypeClass_SEQUENCE: |
459 | 0 | { |
460 | 0 | if( auto rSeq = o3tl::tryAccess<Sequence<Reference<XTreeNode>>>( |
461 | 0 | rSelection) ) |
462 | 0 | { |
463 | 0 | nCount = rSeq->getLength(); |
464 | 0 | pNodes = *rSeq; |
465 | 0 | } |
466 | 0 | break; |
467 | 0 | } |
468 | 0 | default: |
469 | 0 | break; |
470 | 0 | } |
471 | | |
472 | 0 | if( nCount == 0 ) |
473 | 0 | throw IllegalArgumentException(); |
474 | 0 | } |
475 | | |
476 | 0 | if( bSetSelection ) |
477 | 0 | rTree.SelectAll( false ); |
478 | |
|
479 | 0 | for( sal_Int32 i = 0; i != nCount; ++i ) |
480 | 0 | { |
481 | 0 | UnoTreeListEntry* pEntry = getEntry( pNodes[i] ); |
482 | 0 | rTree.Select( pEntry, bSelect ); |
483 | 0 | } |
484 | 0 | } |
485 | | |
486 | | |
487 | | // css::view::XSelectionSupplier |
488 | | |
489 | | |
490 | | sal_Bool SAL_CALL TreeControlPeer::select( const Any& rSelection ) |
491 | 0 | { |
492 | 0 | SolarMutexGuard aGuard; |
493 | 0 | ChangeNodesSelection( rSelection, true, true ); |
494 | 0 | return true; |
495 | 0 | } |
496 | | |
497 | | |
498 | | Any SAL_CALL TreeControlPeer::getSelection() |
499 | 0 | { |
500 | 0 | SolarMutexGuard aGuard; |
501 | |
|
502 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
503 | |
|
504 | 0 | Any aRet; |
505 | |
|
506 | 0 | sal_uInt32 nSelectionCount = rTree.GetSelectionCount(); |
507 | 0 | if( nSelectionCount == 1 ) |
508 | 0 | { |
509 | 0 | UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); |
510 | 0 | if( pEntry && pEntry->mxNode.is() ) |
511 | 0 | aRet <<= pEntry->mxNode; |
512 | 0 | } |
513 | 0 | else if( nSelectionCount > 1 ) |
514 | 0 | { |
515 | 0 | Sequence< Reference< XTreeNode > > aSelection( nSelectionCount ); |
516 | 0 | Reference< XTreeNode >* pNodes = aSelection.getArray(); |
517 | 0 | UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); |
518 | 0 | while( pEntry && nSelectionCount ) |
519 | 0 | { |
520 | 0 | *pNodes++ = pEntry->mxNode; |
521 | 0 | pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); |
522 | 0 | --nSelectionCount; |
523 | 0 | } |
524 | |
|
525 | 0 | OSL_ASSERT( (pEntry == nullptr) && (nSelectionCount == 0) ); |
526 | 0 | aRet <<= aSelection; |
527 | 0 | } |
528 | |
|
529 | 0 | return aRet; |
530 | 0 | } |
531 | | |
532 | | |
533 | | void SAL_CALL TreeControlPeer::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) |
534 | 0 | { |
535 | 0 | maSelectionListeners.addInterface( xListener ); |
536 | 0 | } |
537 | | |
538 | | |
539 | | void SAL_CALL TreeControlPeer::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) |
540 | 0 | { |
541 | 0 | maSelectionListeners.removeInterface( xListener ); |
542 | 0 | } |
543 | | |
544 | | |
545 | | // css::view::XMultiSelectionSupplier |
546 | | |
547 | | |
548 | | sal_Bool SAL_CALL TreeControlPeer::addSelection( const Any& rSelection ) |
549 | 0 | { |
550 | 0 | ChangeNodesSelection( rSelection, true, false ); |
551 | 0 | return true; |
552 | 0 | } |
553 | | |
554 | | |
555 | | void SAL_CALL TreeControlPeer::removeSelection( const Any& rSelection ) |
556 | 0 | { |
557 | 0 | ChangeNodesSelection( rSelection, false, false ); |
558 | 0 | } |
559 | | |
560 | | |
561 | | void SAL_CALL TreeControlPeer::clearSelection() |
562 | 0 | { |
563 | 0 | SolarMutexGuard aGuard; |
564 | 0 | getTreeListBoxOrThrow().SelectAll( false ); |
565 | 0 | } |
566 | | |
567 | | |
568 | | sal_Int32 SAL_CALL TreeControlPeer::getSelectionCount() |
569 | 0 | { |
570 | 0 | SolarMutexGuard aGuard; |
571 | 0 | return getTreeListBoxOrThrow().GetSelectionCount(); |
572 | 0 | } |
573 | | |
574 | | namespace { |
575 | | |
576 | | class TreeSelectionEnumeration : public ::cppu::WeakImplHelper< XEnumeration > |
577 | | { |
578 | | public: |
579 | | explicit TreeSelectionEnumeration( std::list< Any >& rSelection ); |
580 | | virtual sal_Bool SAL_CALL hasMoreElements() override; |
581 | | virtual Any SAL_CALL nextElement() override; |
582 | | |
583 | | std::list< Any > maSelection; |
584 | | std::list< Any >::iterator maIter; |
585 | | }; |
586 | | |
587 | | } |
588 | | |
589 | | TreeSelectionEnumeration::TreeSelectionEnumeration( std::list< Any >& rSelection ) |
590 | 0 | { |
591 | 0 | maSelection.swap( rSelection ); |
592 | 0 | maIter = maSelection.begin(); |
593 | 0 | } |
594 | | |
595 | | |
596 | | sal_Bool SAL_CALL TreeSelectionEnumeration::hasMoreElements() |
597 | 0 | { |
598 | 0 | return maIter != maSelection.end(); |
599 | 0 | } |
600 | | |
601 | | |
602 | | Any SAL_CALL TreeSelectionEnumeration::nextElement() |
603 | 0 | { |
604 | 0 | if( maIter == maSelection.end() ) |
605 | 0 | throw NoSuchElementException(); |
606 | | |
607 | 0 | return (*maIter++); |
608 | 0 | } |
609 | | |
610 | | |
611 | | Reference< XEnumeration > SAL_CALL TreeControlPeer::createSelectionEnumeration() |
612 | 0 | { |
613 | 0 | SolarMutexGuard aGuard; |
614 | |
|
615 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
616 | |
|
617 | 0 | sal_uInt32 nSelectionCount = rTree.GetSelectionCount(); |
618 | 0 | std::list< Any > aSelection( nSelectionCount ); |
619 | |
|
620 | 0 | UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); |
621 | 0 | while( pEntry && nSelectionCount ) |
622 | 0 | { |
623 | 0 | aSelection.emplace_back( pEntry->mxNode ); |
624 | 0 | pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); |
625 | 0 | --nSelectionCount; |
626 | 0 | } |
627 | |
|
628 | 0 | OSL_ASSERT( (pEntry == nullptr) && (nSelectionCount == 0) ); |
629 | |
|
630 | 0 | return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) ); |
631 | 0 | } |
632 | | |
633 | | |
634 | | Reference< XEnumeration > SAL_CALL TreeControlPeer::createReverseSelectionEnumeration() |
635 | 0 | { |
636 | 0 | SolarMutexGuard aGuard; |
637 | |
|
638 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
639 | |
|
640 | 0 | sal_uInt32 nSelectionCount = rTree.GetSelectionCount(); |
641 | 0 | std::list< Any > aSelection; |
642 | |
|
643 | 0 | UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.FirstSelected() ); |
644 | 0 | while( pEntry && nSelectionCount ) |
645 | 0 | { |
646 | 0 | aSelection.push_front( Any( pEntry->mxNode ) ); |
647 | 0 | pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.NextSelected( pEntry ) ); |
648 | 0 | --nSelectionCount; |
649 | 0 | } |
650 | |
|
651 | 0 | OSL_ASSERT( (pEntry == nullptr) && (nSelectionCount == 0) ); |
652 | |
|
653 | 0 | return Reference< XEnumeration >( new TreeSelectionEnumeration( aSelection ) ); |
654 | 0 | } |
655 | | |
656 | | |
657 | | // css::awt::XTreeControl |
658 | | |
659 | | |
660 | | OUString SAL_CALL TreeControlPeer::getDefaultExpandedGraphicURL() |
661 | 0 | { |
662 | 0 | SolarMutexGuard aGuard; |
663 | 0 | return msDefaultExpandedGraphicURL; |
664 | 0 | } |
665 | | |
666 | | |
667 | | void SAL_CALL TreeControlPeer::setDefaultExpandedGraphicURL( const OUString& sDefaultExpandedGraphicURL ) |
668 | 0 | { |
669 | 0 | SolarMutexGuard aGuard; |
670 | 0 | if( msDefaultExpandedGraphicURL == sDefaultExpandedGraphicURL ) |
671 | 0 | return; |
672 | | |
673 | 0 | if( !sDefaultExpandedGraphicURL.isEmpty() ) |
674 | 0 | loadImage( sDefaultExpandedGraphicURL, maDefaultExpandedImage ); |
675 | 0 | else |
676 | 0 | maDefaultExpandedImage = Image(); |
677 | |
|
678 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
679 | |
|
680 | 0 | SvTreeListEntry* pEntry = rTree.First(); |
681 | 0 | while( pEntry ) |
682 | 0 | { |
683 | 0 | ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( &pEntry->GetItem( 0 ) ); |
684 | 0 | if( pContextGraphicItem ) |
685 | 0 | { |
686 | 0 | if( pContextGraphicItem->msExpandedGraphicURL.isEmpty() ) |
687 | 0 | rTree.SetExpandedEntryBmp( pEntry, maDefaultExpandedImage ); |
688 | 0 | } |
689 | 0 | pEntry = rTree.Next( pEntry ); |
690 | 0 | } |
691 | |
|
692 | 0 | msDefaultExpandedGraphicURL = sDefaultExpandedGraphicURL; |
693 | 0 | } |
694 | | |
695 | | |
696 | | OUString SAL_CALL TreeControlPeer::getDefaultCollapsedGraphicURL() |
697 | 0 | { |
698 | 0 | SolarMutexGuard aGuard; |
699 | 0 | return msDefaultCollapsedGraphicURL; |
700 | 0 | } |
701 | | |
702 | | |
703 | | void SAL_CALL TreeControlPeer::setDefaultCollapsedGraphicURL( const OUString& sDefaultCollapsedGraphicURL ) |
704 | 0 | { |
705 | 0 | SolarMutexGuard aGuard; |
706 | 0 | if( msDefaultCollapsedGraphicURL == sDefaultCollapsedGraphicURL ) |
707 | 0 | return; |
708 | | |
709 | 0 | if( !sDefaultCollapsedGraphicURL.isEmpty() ) |
710 | 0 | loadImage( sDefaultCollapsedGraphicURL, maDefaultCollapsedImage ); |
711 | 0 | else |
712 | 0 | maDefaultCollapsedImage = Image(); |
713 | |
|
714 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
715 | |
|
716 | 0 | SvTreeListEntry* pEntry = rTree.First(); |
717 | 0 | while( pEntry ) |
718 | 0 | { |
719 | 0 | ImplContextGraphicItem* pContextGraphicItem = dynamic_cast< ImplContextGraphicItem* >( &pEntry->GetItem( 0 ) ); |
720 | 0 | if( pContextGraphicItem ) |
721 | 0 | { |
722 | 0 | if( pContextGraphicItem->msCollapsedGraphicURL.isEmpty() ) |
723 | 0 | rTree.SetCollapsedEntryBmp( pEntry, maDefaultCollapsedImage ); |
724 | 0 | } |
725 | 0 | pEntry = rTree.Next( pEntry ); |
726 | 0 | } |
727 | |
|
728 | 0 | msDefaultCollapsedGraphicURL = sDefaultCollapsedGraphicURL; |
729 | 0 | } |
730 | | |
731 | | |
732 | | sal_Bool SAL_CALL TreeControlPeer::isNodeExpanded( const Reference< XTreeNode >& xNode ) |
733 | 0 | { |
734 | 0 | SolarMutexGuard aGuard; |
735 | |
|
736 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
737 | 0 | UnoTreeListEntry* pEntry = getEntry( xNode ); |
738 | 0 | return pEntry && rTree.IsExpanded( pEntry ); |
739 | 0 | } |
740 | | |
741 | | |
742 | | sal_Bool SAL_CALL TreeControlPeer::isNodeCollapsed( const Reference< XTreeNode >& xNode ) |
743 | 0 | { |
744 | 0 | SolarMutexGuard aGuard; |
745 | 0 | return !isNodeExpanded( xNode ); |
746 | 0 | } |
747 | | |
748 | | |
749 | | void SAL_CALL TreeControlPeer::makeNodeVisible( const Reference< XTreeNode >& xNode ) |
750 | 0 | { |
751 | 0 | SolarMutexGuard aGuard; |
752 | |
|
753 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
754 | 0 | UnoTreeListEntry* pEntry = getEntry( xNode ); |
755 | 0 | if( pEntry ) |
756 | 0 | rTree.MakeVisible( pEntry ); |
757 | 0 | } |
758 | | |
759 | | |
760 | | sal_Bool SAL_CALL TreeControlPeer::isNodeVisible( const Reference< XTreeNode >& xNode ) |
761 | 0 | { |
762 | 0 | SolarMutexGuard aGuard; |
763 | |
|
764 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
765 | 0 | UnoTreeListEntry* pEntry = getEntry( xNode ); |
766 | 0 | return pEntry && rTree.IsEntryVisible( pEntry ); |
767 | 0 | } |
768 | | |
769 | | |
770 | | void SAL_CALL TreeControlPeer::expandNode( const Reference< XTreeNode >& xNode ) |
771 | 0 | { |
772 | 0 | SolarMutexGuard aGuard; |
773 | |
|
774 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
775 | 0 | UnoTreeListEntry* pEntry = getEntry( xNode ); |
776 | 0 | if( pEntry ) |
777 | 0 | rTree.Expand( pEntry ); |
778 | 0 | } |
779 | | |
780 | | |
781 | | void SAL_CALL TreeControlPeer::collapseNode( const Reference< XTreeNode >& xNode ) |
782 | 0 | { |
783 | 0 | SolarMutexGuard aGuard; |
784 | |
|
785 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
786 | 0 | UnoTreeListEntry* pEntry = getEntry( xNode ); |
787 | 0 | if( pEntry ) |
788 | 0 | rTree.Collapse( pEntry ); |
789 | 0 | } |
790 | | |
791 | | |
792 | | void SAL_CALL TreeControlPeer::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) |
793 | 0 | { |
794 | 0 | maTreeExpansionListeners.addInterface( xListener ); |
795 | 0 | } |
796 | | |
797 | | |
798 | | void SAL_CALL TreeControlPeer::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) |
799 | 0 | { |
800 | 0 | maTreeExpansionListeners.removeInterface( xListener ); |
801 | 0 | } |
802 | | |
803 | | |
804 | | Reference< XTreeNode > SAL_CALL TreeControlPeer::getNodeForLocation( sal_Int32 x, sal_Int32 y ) |
805 | 0 | { |
806 | 0 | SolarMutexGuard aGuard; |
807 | |
|
808 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
809 | |
|
810 | 0 | Reference< XTreeNode > xNode; |
811 | |
|
812 | 0 | const Point aPos( x, y ); |
813 | 0 | UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, true ) ); |
814 | 0 | if( pEntry ) |
815 | 0 | xNode = pEntry->mxNode; |
816 | |
|
817 | 0 | return xNode; |
818 | 0 | } |
819 | | |
820 | | |
821 | | Reference< XTreeNode > SAL_CALL TreeControlPeer::getClosestNodeForLocation( sal_Int32 x, sal_Int32 y ) |
822 | 0 | { |
823 | 0 | SolarMutexGuard aGuard; |
824 | |
|
825 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
826 | |
|
827 | 0 | Reference< XTreeNode > xNode; |
828 | |
|
829 | 0 | const Point aPos( x, y ); |
830 | 0 | UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( rTree.GetEntry( aPos, true ) ); |
831 | 0 | if( pEntry ) |
832 | 0 | xNode = pEntry->mxNode; |
833 | |
|
834 | 0 | return xNode; |
835 | 0 | } |
836 | | |
837 | | |
838 | | awt::Rectangle SAL_CALL TreeControlPeer::getNodeRect( const Reference< XTreeNode >& i_Node ) |
839 | 0 | { |
840 | 0 | SolarMutexGuard aGuard; |
841 | |
|
842 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
843 | 0 | UnoTreeListEntry* pEntry = getEntry( i_Node ); |
844 | |
|
845 | 0 | ::tools::Rectangle aEntryRect( rTree.GetFocusRect( pEntry, rTree.GetEntryPosition( pEntry ).Y() ) ); |
846 | 0 | return vcl::unohelper::ConvertToAWTRect( aEntryRect ); |
847 | 0 | } |
848 | | |
849 | | |
850 | | sal_Bool SAL_CALL TreeControlPeer::isEditing( ) |
851 | 0 | { |
852 | 0 | SolarMutexGuard aGuard; |
853 | |
|
854 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
855 | 0 | return rTree.IsEditingActive(); |
856 | 0 | } |
857 | | |
858 | | |
859 | | sal_Bool SAL_CALL TreeControlPeer::stopEditing() |
860 | 0 | { |
861 | 0 | SolarMutexGuard aGuard; |
862 | |
|
863 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
864 | 0 | if( rTree.IsEditingActive() ) |
865 | 0 | { |
866 | 0 | rTree.EndEditing(); |
867 | 0 | return true; |
868 | 0 | } |
869 | 0 | else |
870 | 0 | { |
871 | 0 | return false; |
872 | 0 | } |
873 | 0 | } |
874 | | |
875 | | |
876 | | void SAL_CALL TreeControlPeer::cancelEditing( ) |
877 | 0 | { |
878 | 0 | SolarMutexGuard aGuard; |
879 | |
|
880 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
881 | 0 | rTree.EndEditing(); |
882 | 0 | } |
883 | | |
884 | | |
885 | | void SAL_CALL TreeControlPeer::startEditingAtNode( const Reference< XTreeNode >& xNode ) |
886 | 0 | { |
887 | 0 | SolarMutexGuard aGuard; |
888 | |
|
889 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
890 | 0 | UnoTreeListEntry* pEntry = getEntry( xNode ); |
891 | 0 | rTree.EditEntry( pEntry ); |
892 | 0 | } |
893 | | |
894 | | void SAL_CALL TreeControlPeer::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) |
895 | 0 | { |
896 | 0 | maTreeEditListeners.addInterface( xListener ); |
897 | 0 | } |
898 | | |
899 | | void SAL_CALL TreeControlPeer::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) |
900 | 0 | { |
901 | 0 | maTreeEditListeners.removeInterface( xListener ); |
902 | 0 | } |
903 | | |
904 | | bool TreeControlPeer::onEditingEntry( UnoTreeListEntry const * pEntry ) |
905 | 0 | { |
906 | 0 | if( mpTreeImpl && pEntry && pEntry->mxNode.is() && (maTreeEditListeners.getLength() > 0) ) |
907 | 0 | { |
908 | 0 | try |
909 | 0 | { |
910 | 0 | maTreeEditListeners.nodeEditing( pEntry->mxNode ); |
911 | 0 | } |
912 | 0 | catch( VetoException& ) |
913 | 0 | { |
914 | 0 | return false; |
915 | 0 | } |
916 | 0 | catch( Exception& ) |
917 | 0 | { |
918 | 0 | } |
919 | 0 | } |
920 | 0 | return true; |
921 | 0 | } |
922 | | |
923 | | bool TreeControlPeer::onEditedEntry( UnoTreeListEntry const * pEntry, const OUString& rNewText ) |
924 | 0 | { |
925 | 0 | if( mpTreeImpl && pEntry && pEntry->mxNode.is() ) try |
926 | 0 | { |
927 | 0 | LockGuard aLockGuard( mnEditLock ); |
928 | 0 | if( maTreeEditListeners.getLength() > 0 ) |
929 | 0 | { |
930 | 0 | maTreeEditListeners.nodeEdited( pEntry->mxNode, rNewText ); |
931 | 0 | return false; |
932 | 0 | } |
933 | 0 | else |
934 | 0 | { |
935 | 0 | Reference< XMutableTreeNode > xMutableNode( pEntry->mxNode, UNO_QUERY ); |
936 | 0 | if( xMutableNode.is() ) |
937 | 0 | xMutableNode->setDisplayValue( Any( rNewText ) ); |
938 | 0 | else |
939 | 0 | return false; |
940 | 0 | } |
941 | |
|
942 | 0 | } |
943 | 0 | catch( Exception& ) |
944 | 0 | { |
945 | 0 | } |
946 | | |
947 | 0 | return true; |
948 | 0 | } |
949 | | |
950 | | |
951 | | // css::awt::tree::TreeDataModelListener |
952 | | |
953 | | |
954 | | void SAL_CALL TreeControlPeer::treeNodesChanged( const css::awt::tree::TreeDataModelEvent& rEvent ) |
955 | 0 | { |
956 | 0 | SolarMutexGuard aGuard; |
957 | |
|
958 | 0 | if( mnEditLock != 0 ) |
959 | 0 | return; |
960 | | |
961 | 0 | updateTree( rEvent ); |
962 | 0 | } |
963 | | |
964 | | void SAL_CALL TreeControlPeer::treeNodesInserted( const css::awt::tree::TreeDataModelEvent& rEvent ) |
965 | 0 | { |
966 | 0 | SolarMutexGuard aGuard; |
967 | |
|
968 | 0 | if( mnEditLock != 0 ) |
969 | 0 | return; |
970 | | |
971 | 0 | updateTree( rEvent ); |
972 | 0 | } |
973 | | |
974 | | void SAL_CALL TreeControlPeer::treeNodesRemoved( const css::awt::tree::TreeDataModelEvent& rEvent ) |
975 | 0 | { |
976 | 0 | SolarMutexGuard aGuard; |
977 | |
|
978 | 0 | if( mnEditLock != 0 ) |
979 | 0 | return; |
980 | | |
981 | 0 | updateTree( rEvent ); |
982 | 0 | } |
983 | | |
984 | | void SAL_CALL TreeControlPeer::treeStructureChanged( const css::awt::tree::TreeDataModelEvent& rEvent ) |
985 | 0 | { |
986 | 0 | SolarMutexGuard aGuard; |
987 | |
|
988 | 0 | if( mnEditLock != 0 ) |
989 | 0 | return; |
990 | | |
991 | 0 | updateTree( rEvent ); |
992 | 0 | } |
993 | | |
994 | | void TreeControlPeer::updateTree( const css::awt::tree::TreeDataModelEvent& rEvent ) |
995 | 0 | { |
996 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
997 | |
|
998 | 0 | Sequence< Reference< XTreeNode > > Nodes; |
999 | 0 | Reference< XTreeNode > xNode( rEvent.ParentNode ); |
1000 | 0 | if( !xNode.is() && Nodes.hasElements() ) |
1001 | 0 | { |
1002 | 0 | xNode = Nodes[0]; |
1003 | 0 | } |
1004 | |
|
1005 | 0 | if( xNode.is() ) |
1006 | 0 | updateNode( rTree, xNode ); |
1007 | 0 | } |
1008 | | |
1009 | | void TreeControlPeer::updateNode( UnoTreeListBoxImpl const & rTree, const Reference< XTreeNode >& xNode ) |
1010 | 0 | { |
1011 | 0 | if( !xNode.is() ) |
1012 | 0 | return; |
1013 | | |
1014 | 0 | UnoTreeListEntry* pNodeEntry = getEntry( xNode, false ); |
1015 | |
|
1016 | 0 | if( !pNodeEntry ) |
1017 | 0 | { |
1018 | 0 | Reference< XTreeNode > xParentNode( xNode->getParent() ); |
1019 | 0 | UnoTreeListEntry* pParentEntry = nullptr; |
1020 | 0 | sal_uInt32 nChild = TREELIST_APPEND; |
1021 | |
|
1022 | 0 | if( xParentNode.is() ) |
1023 | 0 | { |
1024 | 0 | pParentEntry = getEntry( xParentNode ); |
1025 | 0 | nChild = xParentNode->getIndex( xNode ); |
1026 | 0 | } |
1027 | |
|
1028 | 0 | pNodeEntry = createEntry( xNode, pParentEntry, nChild ); |
1029 | 0 | } |
1030 | |
|
1031 | 0 | updateChildNodes( rTree, xNode, pNodeEntry ); |
1032 | 0 | } |
1033 | | |
1034 | | void TreeControlPeer::updateChildNodes( UnoTreeListBoxImpl const & rTree, const Reference< XTreeNode >& xParentNode, UnoTreeListEntry* pParentEntry ) |
1035 | 0 | { |
1036 | 0 | if( !(xParentNode.is() && pParentEntry) ) |
1037 | 0 | return; |
1038 | | |
1039 | 0 | UnoTreeListEntry* pCurrentChild = dynamic_cast< UnoTreeListEntry* >( rTree.FirstChild( pParentEntry ) ); |
1040 | |
|
1041 | 0 | const sal_Int32 nChildCount = xParentNode->getChildCount(); |
1042 | 0 | for( sal_Int32 nChild = 0; nChild < nChildCount; nChild++ ) |
1043 | 0 | { |
1044 | 0 | Reference< XTreeNode > xNode( xParentNode->getChildAt( nChild ) ); |
1045 | 0 | if( !pCurrentChild || ( pCurrentChild->mxNode != xNode ) ) |
1046 | 0 | { |
1047 | 0 | UnoTreeListEntry* pNodeEntry = getEntry( xNode, false ); |
1048 | 0 | if( pNodeEntry == nullptr ) |
1049 | 0 | { |
1050 | | // child node is not yet part of the tree, add it |
1051 | 0 | pCurrentChild = createEntry( xNode, pParentEntry, nChild ); |
1052 | 0 | } |
1053 | 0 | else if( pNodeEntry != pCurrentChild ) |
1054 | 0 | { |
1055 | | // node is already part of the tree, but not on the correct position |
1056 | 0 | rTree.GetModel()->Move( pNodeEntry, pParentEntry, nChild ); |
1057 | 0 | pCurrentChild = pNodeEntry; |
1058 | 0 | updateEntry( pCurrentChild ); |
1059 | 0 | } |
1060 | 0 | } |
1061 | 0 | else |
1062 | 0 | { |
1063 | | // child node has entry and entry is equal to current entry, |
1064 | | // so no structural changes happened |
1065 | 0 | updateEntry( pCurrentChild ); |
1066 | 0 | } |
1067 | |
|
1068 | 0 | pCurrentChild = dynamic_cast< UnoTreeListEntry* >( pCurrentChild->NextSibling() ); |
1069 | 0 | } |
1070 | | |
1071 | | // check if we have entries without nodes left, we need to remove them |
1072 | 0 | while( pCurrentChild ) |
1073 | 0 | { |
1074 | 0 | UnoTreeListEntry* pNextChild = dynamic_cast< UnoTreeListEntry* >( pCurrentChild->NextSibling() ); |
1075 | 0 | rTree.GetModel()->Remove( pCurrentChild ); |
1076 | 0 | pCurrentChild = pNextChild; |
1077 | 0 | } |
1078 | 0 | } |
1079 | | |
1080 | | OUString TreeControlPeer::getEntryString( const Any& rValue ) |
1081 | 0 | { |
1082 | 0 | OUString sValue; |
1083 | 0 | if( rValue.hasValue() ) |
1084 | 0 | { |
1085 | 0 | switch( rValue.getValueTypeClass() ) |
1086 | 0 | { |
1087 | 0 | case TypeClass_SHORT: |
1088 | 0 | case TypeClass_LONG: |
1089 | 0 | { |
1090 | 0 | sal_Int32 nValue = 0; |
1091 | 0 | if( rValue >>= nValue ) |
1092 | 0 | sValue = OUString::number( nValue ); |
1093 | 0 | break; |
1094 | 0 | } |
1095 | 0 | case TypeClass_BYTE: |
1096 | 0 | case TypeClass_UNSIGNED_SHORT: |
1097 | 0 | case TypeClass_UNSIGNED_LONG: |
1098 | 0 | { |
1099 | 0 | sal_uInt32 nValue = 0; |
1100 | 0 | if( rValue >>= nValue ) |
1101 | 0 | sValue = OUString::number( nValue ); |
1102 | 0 | break; |
1103 | 0 | } |
1104 | 0 | case TypeClass_HYPER: |
1105 | 0 | { |
1106 | 0 | sal_Int64 nValue = 0; |
1107 | 0 | if( rValue >>= nValue ) |
1108 | 0 | sValue = OUString::number( nValue ); |
1109 | 0 | break; |
1110 | 0 | } |
1111 | 0 | case TypeClass_UNSIGNED_HYPER: |
1112 | 0 | { |
1113 | 0 | sal_uInt64 nValue = 0; |
1114 | 0 | if( rValue >>= nValue ) |
1115 | 0 | sValue = OUString::number( nValue ); |
1116 | 0 | break; |
1117 | 0 | } |
1118 | 0 | case TypeClass_FLOAT: |
1119 | 0 | case TypeClass_DOUBLE: |
1120 | 0 | { |
1121 | 0 | double fValue = 0.0; |
1122 | 0 | if( rValue >>= fValue ) |
1123 | 0 | sValue = OUString::number( fValue ); |
1124 | 0 | break; |
1125 | 0 | } |
1126 | 0 | case TypeClass_STRING: |
1127 | 0 | rValue >>= sValue; |
1128 | 0 | break; |
1129 | | /* |
1130 | | case TypeClass_INTERFACE: |
1131 | | // @todo |
1132 | | break; |
1133 | | case TypeClass_SEQUENCE: |
1134 | | { |
1135 | | Sequence< Any > aValues; |
1136 | | if( aValue >>= aValues ) |
1137 | | { |
1138 | | updateEntry( SvTreeListEntry& rEntry, aValues ); |
1139 | | return; |
1140 | | } |
1141 | | } |
1142 | | break; |
1143 | | */ |
1144 | 0 | default: |
1145 | 0 | break; |
1146 | 0 | } |
1147 | 0 | } |
1148 | 0 | return sValue; |
1149 | 0 | } |
1150 | | |
1151 | | // XEventListener |
1152 | | void SAL_CALL TreeControlPeer::disposing( const css::lang::EventObject& ) |
1153 | 0 | { |
1154 | | // model is disposed, so we clear our tree |
1155 | 0 | SolarMutexGuard aGuard; |
1156 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
1157 | 0 | rTree.Clear(); |
1158 | 0 | mxDataModel.clear(); |
1159 | 0 | } |
1160 | | |
1161 | | void TreeControlPeer::onChangeDataModel( UnoTreeListBoxImpl& rTree, const Reference< XTreeDataModel >& xDataModel ) |
1162 | 0 | { |
1163 | 0 | if( xDataModel.is() && (mxDataModel == xDataModel) ) |
1164 | 0 | return; // do nothing |
1165 | | |
1166 | 0 | Reference< XTreeDataModelListener > xListener( this ); |
1167 | |
|
1168 | 0 | if( mxDataModel.is() ) |
1169 | 0 | mxDataModel->removeTreeDataModelListener( xListener ); |
1170 | |
|
1171 | 0 | mxDataModel = xDataModel; |
1172 | |
|
1173 | 0 | fillTree( rTree, mxDataModel ); |
1174 | |
|
1175 | 0 | if( mxDataModel.is() ) |
1176 | 0 | mxDataModel->addTreeDataModelListener( xListener ); |
1177 | 0 | } |
1178 | | |
1179 | | |
1180 | | // css::awt::XLayoutConstrains |
1181 | | |
1182 | | |
1183 | | css::awt::Size TreeControlPeer::getMinimumSize() |
1184 | 0 | { |
1185 | 0 | SolarMutexGuard aGuard; |
1186 | |
|
1187 | 0 | css::awt::Size aSz; |
1188 | | /* todo |
1189 | | MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); |
1190 | | if ( pEdit ) |
1191 | | aSz = vcl::unohelper::ConvertToAWTSize(pEdit->CalcMinimumSize()); |
1192 | | */ |
1193 | 0 | return aSz; |
1194 | 0 | } |
1195 | | |
1196 | | css::awt::Size TreeControlPeer::getPreferredSize() |
1197 | 0 | { |
1198 | 0 | return getMinimumSize(); |
1199 | 0 | } |
1200 | | |
1201 | | css::awt::Size TreeControlPeer::calcAdjustedSize( const css::awt::Size& rNewSize ) |
1202 | 0 | { |
1203 | 0 | SolarMutexGuard aGuard; |
1204 | |
|
1205 | 0 | css::awt::Size aSz = rNewSize; |
1206 | | /* todo |
1207 | | MultiLineEdit* pEdit = (MultiLineEdit*) GetWindow(); |
1208 | | if ( pEdit ) |
1209 | | aSz = vcl::unohelper::ConvertToAWTSize(pEdit->CalcAdjustedSize(vcl::unohelper::ConvertToVCLSize(rNewSize))); |
1210 | | */ |
1211 | 0 | return aSz; |
1212 | 0 | } |
1213 | | |
1214 | | |
1215 | | // css::awt::XVclWindowPeer |
1216 | | |
1217 | | |
1218 | | void TreeControlPeer::setProperty( const OUString& PropertyName, const Any& aValue) |
1219 | 0 | { |
1220 | 0 | SolarMutexGuard aGuard; |
1221 | |
|
1222 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
1223 | |
|
1224 | 0 | switch( GetPropertyId( PropertyName ) ) |
1225 | 0 | { |
1226 | 0 | case BASEPROPERTY_HIDEINACTIVESELECTION: |
1227 | 0 | { |
1228 | 0 | bool bEnabled = false; |
1229 | 0 | if ( aValue >>= bEnabled ) |
1230 | 0 | { |
1231 | 0 | WinBits nStyle = rTree.GetStyle(); |
1232 | 0 | if ( bEnabled ) |
1233 | 0 | nStyle |= WB_HIDESELECTION; |
1234 | 0 | else |
1235 | 0 | nStyle &= ~WB_HIDESELECTION; |
1236 | 0 | rTree.SetStyle( nStyle ); |
1237 | 0 | } |
1238 | 0 | } |
1239 | 0 | break; |
1240 | | |
1241 | 0 | case BASEPROPERTY_TREE_SELECTIONTYPE: |
1242 | 0 | { |
1243 | 0 | SelectionType eSelectionType; |
1244 | 0 | if( aValue >>= eSelectionType ) |
1245 | 0 | { |
1246 | 0 | SelectionMode eSelMode; |
1247 | 0 | switch( eSelectionType ) |
1248 | 0 | { |
1249 | 0 | case SelectionType_SINGLE: eSelMode = SelectionMode::Single; break; |
1250 | 0 | case SelectionType_RANGE: eSelMode = SelectionMode::Range; break; |
1251 | 0 | case SelectionType_MULTI: eSelMode = SelectionMode::Multiple; break; |
1252 | | // case SelectionType_NONE: |
1253 | 0 | default: eSelMode = SelectionMode::NONE; break; |
1254 | 0 | } |
1255 | 0 | if( rTree.GetSelectionMode() != eSelMode ) |
1256 | 0 | rTree.SetSelectionMode( eSelMode ); |
1257 | 0 | } |
1258 | 0 | break; |
1259 | 0 | } |
1260 | | |
1261 | 0 | case BASEPROPERTY_TREE_DATAMODEL: |
1262 | 0 | onChangeDataModel( rTree, Reference< XTreeDataModel >( aValue, UNO_QUERY ) ); |
1263 | 0 | break; |
1264 | 0 | case BASEPROPERTY_ROW_HEIGHT: |
1265 | 0 | { |
1266 | 0 | sal_Int32 nHeight = 0; |
1267 | 0 | if( aValue >>= nHeight ) |
1268 | 0 | rTree.SetEntryHeight( static_cast<short>(nHeight) ); |
1269 | 0 | break; |
1270 | 0 | } |
1271 | 0 | case BASEPROPERTY_TREE_EDITABLE: |
1272 | 0 | { |
1273 | 0 | bool bEnabled = false; |
1274 | 0 | if( aValue >>= bEnabled ) |
1275 | 0 | rTree.EnableInplaceEditing( bEnabled ); |
1276 | 0 | break; |
1277 | 0 | } |
1278 | 0 | case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: |
1279 | 0 | break; // @todo |
1280 | 0 | case BASEPROPERTY_TREE_ROOTDISPLAYED: |
1281 | 0 | { |
1282 | 0 | bool bDisplayed = false; |
1283 | 0 | if( (aValue >>= bDisplayed) && ( bDisplayed != mbIsRootDisplayed) ) |
1284 | 0 | { |
1285 | 0 | onChangeRootDisplayed(bDisplayed); |
1286 | 0 | } |
1287 | 0 | break; |
1288 | 0 | } |
1289 | 0 | case BASEPROPERTY_TREE_SHOWSHANDLES: |
1290 | 0 | { |
1291 | 0 | bool bEnabled = false; |
1292 | 0 | if( aValue >>= bEnabled ) |
1293 | 0 | { |
1294 | 0 | WinBits nBits = rTree.GetStyle() & (~WB_HASLINES); |
1295 | 0 | if( bEnabled ) |
1296 | 0 | nBits |= WB_HASLINES; |
1297 | 0 | if( nBits != rTree.GetStyle() ) |
1298 | 0 | rTree.SetStyle( nBits ); |
1299 | 0 | } |
1300 | 0 | break; |
1301 | 0 | } |
1302 | 0 | case BASEPROPERTY_TREE_SHOWSROOTHANDLES: |
1303 | 0 | { |
1304 | 0 | bool bEnabled = false; |
1305 | 0 | if( aValue >>= bEnabled ) |
1306 | 0 | { |
1307 | 0 | WinBits nBits = rTree.GetStyle() & (~WB_HASLINESATROOT); |
1308 | 0 | if( bEnabled ) |
1309 | 0 | nBits |= WB_HASLINESATROOT; |
1310 | 0 | if( nBits != rTree.GetStyle() ) |
1311 | 0 | rTree.SetStyle( nBits ); |
1312 | 0 | } |
1313 | 0 | break; |
1314 | 0 | } |
1315 | 0 | default: |
1316 | 0 | VCLXWindow::setProperty( PropertyName, aValue ); |
1317 | 0 | break; |
1318 | 0 | } |
1319 | 0 | } |
1320 | | |
1321 | | Any TreeControlPeer::getProperty( const OUString& PropertyName ) |
1322 | 0 | { |
1323 | 0 | SolarMutexGuard aGuard; |
1324 | |
|
1325 | 0 | const sal_uInt16 nPropId = GetPropertyId( PropertyName ); |
1326 | 0 | if( (nPropId >= BASEPROPERTY_TREE_START) && (nPropId <= BASEPROPERTY_TREE_END) ) |
1327 | 0 | { |
1328 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
1329 | 0 | switch(nPropId) |
1330 | 0 | { |
1331 | 0 | case BASEPROPERTY_TREE_SELECTIONTYPE: |
1332 | 0 | { |
1333 | 0 | SelectionType eSelectionType; |
1334 | |
|
1335 | 0 | SelectionMode eSelMode = rTree.GetSelectionMode(); |
1336 | 0 | switch( eSelMode ) |
1337 | 0 | { |
1338 | 0 | case SelectionMode::Single: eSelectionType = SelectionType_SINGLE; break; |
1339 | 0 | case SelectionMode::Range: eSelectionType = SelectionType_RANGE; break; |
1340 | 0 | case SelectionMode::Multiple:eSelectionType = SelectionType_MULTI; break; |
1341 | | // case SelectionMode::NONE: |
1342 | 0 | default: eSelectionType = SelectionType_NONE; break; |
1343 | 0 | } |
1344 | 0 | return Any( eSelectionType ); |
1345 | 0 | } |
1346 | 0 | case BASEPROPERTY_ROW_HEIGHT: |
1347 | 0 | return Any( static_cast<sal_Int32>(rTree.GetEntryHeight()) ); |
1348 | 0 | case BASEPROPERTY_TREE_DATAMODEL: |
1349 | 0 | return Any( mxDataModel ); |
1350 | 0 | case BASEPROPERTY_TREE_EDITABLE: |
1351 | 0 | return Any( rTree.IsInplaceEditingEnabled() ); |
1352 | 0 | case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING: |
1353 | 0 | return Any( true ); // @todo |
1354 | 0 | case BASEPROPERTY_TREE_ROOTDISPLAYED: |
1355 | 0 | return Any( mbIsRootDisplayed ); |
1356 | 0 | case BASEPROPERTY_TREE_SHOWSHANDLES: |
1357 | 0 | return Any( (rTree.GetStyle() & WB_HASLINES) != 0 ); |
1358 | 0 | case BASEPROPERTY_TREE_SHOWSROOTHANDLES: |
1359 | 0 | return Any( (rTree.GetStyle() & WB_HASLINESATROOT) != 0 ); |
1360 | 0 | } |
1361 | 0 | } |
1362 | 0 | return VCLXWindow::getProperty( PropertyName ); |
1363 | 0 | } |
1364 | | |
1365 | | void TreeControlPeer::onChangeRootDisplayed( bool bIsRootDisplayed ) |
1366 | 0 | { |
1367 | 0 | if( mbIsRootDisplayed == bIsRootDisplayed ) |
1368 | 0 | return; |
1369 | | |
1370 | 0 | mbIsRootDisplayed = bIsRootDisplayed; |
1371 | |
|
1372 | 0 | UnoTreeListBoxImpl& rTree = getTreeListBoxOrThrow(); |
1373 | |
|
1374 | 0 | if( rTree.GetEntryCount() == 0 ) |
1375 | 0 | return; |
1376 | | |
1377 | | // todo |
1378 | 0 | fillTree( rTree, mxDataModel ); |
1379 | 0 | } |
1380 | | |
1381 | | bool TreeControlPeer::loadImage( const OUString& rURL, Image& rImage ) |
1382 | 0 | { |
1383 | 0 | if( !mxGraphicProvider.is() ) |
1384 | 0 | { |
1385 | 0 | mxGraphicProvider = graphic::GraphicProvider::create( |
1386 | 0 | comphelper::getProcessComponentContext()); |
1387 | 0 | } |
1388 | |
|
1389 | 0 | try |
1390 | 0 | { |
1391 | 0 | css::beans::PropertyValues aProps{ comphelper::makePropertyValue(u"URL"_ustr, rURL) }; |
1392 | 0 | Reference< XGraphic > xGraphic( mxGraphicProvider->queryGraphic( aProps ) ); |
1393 | |
|
1394 | 0 | Graphic aGraphic( xGraphic ); |
1395 | 0 | rImage = Image(aGraphic.GetBitmap()); |
1396 | 0 | return true; |
1397 | 0 | } |
1398 | 0 | catch( Exception& ) |
1399 | 0 | { |
1400 | 0 | } |
1401 | | |
1402 | 0 | return false; |
1403 | 0 | } |
1404 | | |
1405 | | |
1406 | | |
1407 | | |
1408 | | UnoTreeListBoxImpl::UnoTreeListBoxImpl( TreeControlPeer* pPeer, vcl::Window* pParent, WinBits nWinStyle ) |
1409 | 0 | : SvTreeListBox( pParent, nWinStyle ) |
1410 | 0 | , mxPeer( pPeer ) |
1411 | 0 | { |
1412 | 0 | SetStyle( WB_BORDER | WB_HASLINES |WB_HASBUTTONS | WB_HASLINESATROOT | WB_HASBUTTONSATROOT | WB_HSCROLL ); |
1413 | 0 | SetNodeDefaultImages(); |
1414 | 0 | SetSelectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) ); |
1415 | 0 | SetDeselectHdl( LINK(this, UnoTreeListBoxImpl, OnSelectionChangeHdl) ); |
1416 | |
|
1417 | 0 | SetExpandingHdl( LINK(this, UnoTreeListBoxImpl, OnExpandingHdl) ); |
1418 | 0 | SetExpandedHdl( LINK(this, UnoTreeListBoxImpl, OnExpandedHdl) ); |
1419 | |
|
1420 | 0 | } Unexecuted instantiation: UnoTreeListBoxImpl::UnoTreeListBoxImpl(TreeControlPeer*, vcl::Window*, long) Unexecuted instantiation: UnoTreeListBoxImpl::UnoTreeListBoxImpl(TreeControlPeer*, vcl::Window*, long) |
1421 | | |
1422 | | |
1423 | | UnoTreeListBoxImpl::~UnoTreeListBoxImpl() |
1424 | 0 | { |
1425 | 0 | disposeOnce(); |
1426 | 0 | } |
1427 | | |
1428 | | void UnoTreeListBoxImpl::dispose() |
1429 | 0 | { |
1430 | 0 | if( mxPeer.is() ) |
1431 | 0 | mxPeer->disposeControl(); |
1432 | 0 | mxPeer.clear(); |
1433 | 0 | SvTreeListBox::dispose(); |
1434 | 0 | } |
1435 | | |
1436 | | |
1437 | | IMPL_LINK_NOARG(UnoTreeListBoxImpl, OnSelectionChangeHdl, SvTreeListBox*, void) |
1438 | 0 | { |
1439 | 0 | if( mxPeer.is() ) |
1440 | 0 | mxPeer->onSelectionChanged(); |
1441 | 0 | } |
1442 | | |
1443 | | |
1444 | | IMPL_LINK_NOARG(UnoTreeListBoxImpl, OnExpandingHdl, SvTreeListBox*, bool) |
1445 | 0 | { |
1446 | 0 | UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() ); |
1447 | |
|
1448 | 0 | if( pEntry && mxPeer.is() ) |
1449 | 0 | { |
1450 | 0 | return mxPeer->onExpanding( pEntry->mxNode, !IsExpanded( pEntry ) ); |
1451 | 0 | } |
1452 | 0 | return false; |
1453 | 0 | } |
1454 | | |
1455 | | |
1456 | | IMPL_LINK_NOARG(UnoTreeListBoxImpl, OnExpandedHdl, SvTreeListBox*, void) |
1457 | 0 | { |
1458 | 0 | UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( GetHdlEntry() ); |
1459 | 0 | if( pEntry && mxPeer.is() ) |
1460 | 0 | { |
1461 | 0 | mxPeer->onExpanded( pEntry->mxNode, IsExpanded( pEntry ) ); |
1462 | 0 | } |
1463 | 0 | } |
1464 | | |
1465 | | |
1466 | | void UnoTreeListBoxImpl::insert( SvTreeListEntry* pEntry,SvTreeListEntry* pParent,sal_uInt32 nPos ) |
1467 | 0 | { |
1468 | 0 | if( pParent ) |
1469 | 0 | SvTreeListBox::Insert( pEntry, pParent, nPos ); |
1470 | 0 | else |
1471 | 0 | SvTreeListBox::Insert( pEntry, nPos ); |
1472 | 0 | } |
1473 | | |
1474 | | |
1475 | | void UnoTreeListBoxImpl::RequestingChildren( SvTreeListEntry* pParent ) |
1476 | 0 | { |
1477 | 0 | UnoTreeListEntry* pEntry = dynamic_cast< UnoTreeListEntry* >( pParent ); |
1478 | 0 | if( pEntry && pEntry->mxNode.is() && mxPeer.is() ) |
1479 | 0 | mxPeer->onRequestChildNodes( pEntry->mxNode ); |
1480 | 0 | } |
1481 | | |
1482 | | |
1483 | | bool UnoTreeListBoxImpl::EditingEntry( SvTreeListEntry* pEntry ) |
1484 | 0 | { |
1485 | 0 | return mxPeer.is() && mxPeer->onEditingEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ) ); |
1486 | 0 | } |
1487 | | |
1488 | | |
1489 | | bool UnoTreeListBoxImpl::EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText ) |
1490 | 0 | { |
1491 | 0 | return mxPeer.is() && mxPeer->onEditedEntry( dynamic_cast< UnoTreeListEntry* >( pEntry ), rNewText ); |
1492 | 0 | } |
1493 | | |
1494 | | |
1495 | | |
1496 | | |
1497 | | UnoTreeListItem::UnoTreeListItem() |
1498 | 0 | : SvLBoxString(OUString()) |
1499 | 0 | { |
1500 | 0 | } |
1501 | | |
1502 | | void UnoTreeListItem::Paint( |
1503 | | const Point& rPos, SvTreeListBox& rDev, vcl::RenderContext& rRenderContext, const SvViewDataEntry* /*pView*/, const SvTreeListEntry& rEntry) |
1504 | 0 | { |
1505 | 0 | Point aPos(rPos); |
1506 | 0 | Size aSize(GetWidth(&rDev, &rEntry), GetHeight(&rDev, &rEntry)); |
1507 | 0 | if (!!maImage) |
1508 | 0 | { |
1509 | 0 | rRenderContext.DrawImage(aPos, maImage, rDev.IsEnabled() ? DrawImageFlags::NONE : DrawImageFlags::Disable); |
1510 | 0 | int nWidth = maImage.GetSizePixel().Width() + 6; |
1511 | 0 | aPos.AdjustX(nWidth ); |
1512 | 0 | aSize.AdjustWidth( -nWidth ); |
1513 | 0 | } |
1514 | 0 | rRenderContext.DrawText(tools::Rectangle(aPos,aSize),maText, rDev.IsEnabled() ? DrawTextFlags::NONE : DrawTextFlags::Disable); |
1515 | 0 | } |
1516 | | |
1517 | | |
1518 | | std::unique_ptr<SvLBoxItem> UnoTreeListItem::Clone(SvLBoxItem const * pSource) const |
1519 | 0 | { |
1520 | 0 | std::unique_ptr<UnoTreeListItem> pNew(new UnoTreeListItem); |
1521 | 0 | UnoTreeListItem const * pSourceItem = static_cast< UnoTreeListItem const * >( pSource ); |
1522 | 0 | pNew->maText = pSourceItem->maText; |
1523 | 0 | pNew->maImage = pSourceItem->maImage; |
1524 | 0 | return std::unique_ptr<SvLBoxItem>(pNew.release()); |
1525 | 0 | } |
1526 | | |
1527 | | |
1528 | | void UnoTreeListItem::SetImage( const Image& rImage ) |
1529 | 0 | { |
1530 | 0 | maImage = rImage; |
1531 | 0 | } |
1532 | | |
1533 | | |
1534 | | void UnoTreeListItem::SetGraphicURL( const OUString& rGraphicURL ) |
1535 | 0 | { |
1536 | 0 | maGraphicURL = rGraphicURL; |
1537 | 0 | } |
1538 | | |
1539 | | |
1540 | | void UnoTreeListItem::InitViewData( SvTreeListBox* pView,SvTreeListEntry* pEntry, SvViewDataItem* pViewData) |
1541 | 0 | { |
1542 | 0 | if( !pViewData ) |
1543 | 0 | pViewData = pView->GetViewDataItem( pEntry, this ); |
1544 | |
|
1545 | 0 | Size aSize(maImage.GetSizePixel()); |
1546 | 0 | pViewData->mnWidth = aSize.Width(); |
1547 | 0 | pViewData->mnHeight = aSize.Height(); |
1548 | |
|
1549 | 0 | const Size aTextSize(pView->GetTextWidth( maText ), pView->GetTextHeight()); |
1550 | 0 | if( pViewData->mnWidth ) |
1551 | 0 | { |
1552 | 0 | pViewData->mnWidth += (6 + aTextSize.Width()); |
1553 | 0 | if( pViewData->mnHeight < aTextSize.Height() ) |
1554 | 0 | pViewData->mnHeight = aTextSize.Height(); |
1555 | 0 | } |
1556 | 0 | else |
1557 | 0 | { |
1558 | 0 | pViewData->mnWidth = aTextSize.Width(); |
1559 | 0 | pViewData->mnHeight = aTextSize.Height(); |
1560 | 0 | } |
1561 | 0 | } |
1562 | | |
1563 | | |
1564 | | UnoTreeListEntry::UnoTreeListEntry( const Reference< XTreeNode >& xNode, TreeControlPeer* pPeer ) |
1565 | 0 | : mxNode( xNode ) |
1566 | 0 | , mpPeer( pPeer ) |
1567 | 0 | { |
1568 | 0 | if( mpPeer ) |
1569 | 0 | mpPeer->addEntry( this ); |
1570 | 0 | } |
1571 | | |
1572 | | |
1573 | | UnoTreeListEntry::~UnoTreeListEntry() |
1574 | 0 | { |
1575 | 0 | if( mpPeer ) |
1576 | 0 | mpPeer->removeEntry( this ); |
1577 | 0 | } |
1578 | | |
1579 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |