1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <Navigator.hxx>
22 #include <strings.hxx>
23 #include <bitmaps.hlst>
24 #include <ReportController.hxx>
25 #include <UITools.hxx>
26 #include <RptUndo.hxx>
27 #include <reportformula.hxx>
28 #include <com/sun/star/container/XContainerListener.hpp>
29 #include <com/sun/star/report/XReportDefinition.hpp>
30 #include <com/sun/star/report/XFixedText.hpp>
31 #include <com/sun/star/report/XFixedLine.hpp>
32 #include <com/sun/star/report/XFormattedField.hpp>
33 #include <com/sun/star/report/XImageControl.hpp>
34 #include <com/sun/star/report/XShape.hpp>
36 #include <strings.hrc>
37 #include <rptui_slotid.hrc>
38 #include <comphelper/propmultiplex.hxx>
39 #include <comphelper/containermultiplexer.hxx>
40 #include <cppuhelper/basemutex.hxx>
41 #include <comphelper/SelectionMultiplex.hxx>
42 #include <vcl/treelistbox.hxx>
43 #include <vcl/treelistentry.hxx>
44 #include <vcl/commandevent.hxx>
45 #include <svl/solar.hrc>
46 #include <ReportVisitor.hxx>
47 #include <core_resource.hxx>
48 #include <rtl/ref.hxx>
53 #define DROP_ACTION_TIMER_INITIAL_TICKS 10
54 #define DROP_ACTION_TIMER_SCROLL_TICKS 3
55 #define DROP_ACTION_TIMER_TICK_BASE 10
59 using namespace ::com::sun::star
;
61 using namespace ::comphelper
;
63 static OUString
lcl_getImageId(const uno::Reference
< report::XReportComponent
>& _xElement
)
66 uno::Reference
< report::XFixedLine
> xFixedLine(_xElement
,uno::UNO_QUERY
);
67 if ( uno::Reference
< report::XFixedText
>(_xElement
,uno::UNO_QUERY
).is() )
68 sId
= RID_SVXBMP_FM_FIXEDTEXT
;
69 else if ( xFixedLine
.is() )
70 sId
= xFixedLine
->getOrientation() ? OUStringLiteral(RID_SVXBMP_INSERT_VFIXEDLINE
) : OUStringLiteral(RID_SVXBMP_INSERT_HFIXEDLINE
);
71 else if ( uno::Reference
< report::XFormattedField
>(_xElement
,uno::UNO_QUERY
).is() )
72 sId
= RID_SVXBMP_FM_EDIT
;
73 else if ( uno::Reference
< report::XImageControl
>(_xElement
,uno::UNO_QUERY
).is() )
74 sId
= RID_SVXBMP_FM_IMAGECONTROL
;
75 else if ( uno::Reference
< report::XShape
>(_xElement
,uno::UNO_QUERY
).is() )
76 sId
= RID_SVXBMP_DRAWTBX_CS_BASIC
;
80 static OUString
lcl_getName(const uno::Reference
< beans::XPropertySet
>& _xElement
)
82 OSL_ENSURE(_xElement
.is(),"Found report element which is NULL!");
84 _xElement
->getPropertyValue(PROPERTY_NAME
) >>= sTempName
;
85 OUStringBuffer sName
= sTempName
;
86 uno::Reference
< report::XFixedText
> xFixedText(_xElement
,uno::UNO_QUERY
);
87 uno::Reference
< report::XReportControlModel
> xReportModel(_xElement
,uno::UNO_QUERY
);
88 if ( xFixedText
.is() )
91 sName
.append(xFixedText
->getLabel());
93 else if ( xReportModel
.is() && _xElement
->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD
) )
95 ReportFormula
aFormula( xReportModel
->getDataField() );
96 if ( aFormula
.isValid() )
99 sName
.append( aFormula
.getUndecoratedContent() );
102 return sName
.makeStringAndClear();
106 class NavigatorTree
: public ::cppu::BaseMutex
107 , public SvTreeListBox
108 , public reportdesign::ITraverseReport
109 , public comphelper::OSelectionChangeListener
110 , public ::comphelper::OPropertyChangeListener
113 friend class UserData
;
114 class UserData
: public ::cppu::BaseMutex
115 ,public ::comphelper::OPropertyChangeListener
116 ,public ::comphelper::OContainerListener
118 uno::Reference
< uno::XInterface
> m_xContent
;
119 ::rtl::Reference
< comphelper::OPropertyChangeMultiplexer
> m_pListener
;
120 ::rtl::Reference
< comphelper::OContainerListenerAdapter
> m_pContainerListener
;
121 VclPtr
<NavigatorTree
> m_pTree
;
123 UserData(NavigatorTree
* _pTree
,const uno::Reference
<uno::XInterface
>& _xContent
);
124 virtual ~UserData() override
;
126 const uno::Reference
< uno::XInterface
>& getContent() const { return m_xContent
; }
127 void setContent(const uno::Reference
< uno::XInterface
>& _xContent
) { m_xContent
= _xContent
; }
130 // OPropertyChangeListener
131 virtual void _propertyChanged(const beans::PropertyChangeEvent
& _rEvent
) override
;
133 // OContainerListener
134 virtual void _elementInserted( const container::ContainerEvent
& _rEvent
) override
;
135 virtual void _elementRemoved( const container::ContainerEvent
& Event
) override
;
136 virtual void _elementReplaced( const container::ContainerEvent
& _rEvent
) override
;
137 virtual void _disposing(const lang::EventObject
& _rSource
) override
;
140 enum DROP_ACTION
{ DA_SCROLLUP
, DA_SCROLLDOWN
, DA_EXPANDNODE
};
141 AutoTimer m_aDropActionTimer
;
142 Point m_aTimerTriggered
; // position at which the DropTimer started
143 DROP_ACTION m_aDropActionType
;
144 OReportController
& m_rController
;
145 SvTreeListEntry
* m_pMasterReport
;
146 SvTreeListEntry
* m_pDragedEntry
;
147 ::rtl::Reference
< comphelper::OPropertyChangeMultiplexer
> m_pReportListener
;
148 ::rtl::Reference
< comphelper::OSelectionChangeMultiplexer
> m_pSelectionListener
;
149 unsigned short m_nTimerCounter
;
151 SvTreeListEntry
* insertEntry(const OUString
& _sName
,SvTreeListEntry
* _pParent
, const OUString
& rImageId
, sal_uLong _nPosition
,UserData
* _pData
);
152 void traverseSection(const uno::Reference
< report::XSection
>& _xSection
,SvTreeListEntry
* _pParent
, const OUString
& rImageId
, sal_uLong _nPosition
= TREELIST_APPEND
);
153 void traverseFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
,SvTreeListEntry
* _pParent
);
156 virtual void Command( const CommandEvent
& rEvt
) override
;
157 // DragSourceHelper overridables
158 virtual void StartDrag( sal_Int8 nAction
, const Point
& rPosPixel
) override
;
159 // DropTargetHelper overridables
160 virtual sal_Int8
AcceptDrop( const AcceptDropEvent
& _rEvt
) override
;
161 virtual sal_Int8
ExecuteDrop( const ExecuteDropEvent
& _rEvt
) override
;
163 // OSelectionChangeListener
164 virtual void _disposing(const lang::EventObject
& _rSource
) override
;
166 // OPropertyChangeListener
167 virtual void _propertyChanged(const beans::PropertyChangeEvent
& _rEvent
) override
;
169 // OContainerListener Helper
170 void _elementInserted( const container::ContainerEvent
& _rEvent
);
171 void _elementRemoved( const container::ContainerEvent
& Event
);
172 void _elementReplaced( const container::ContainerEvent
& _rEvent
);
175 NavigatorTree(vcl::Window
* pParent
,OReportController
& _rController
);
176 virtual ~NavigatorTree() override
;
177 virtual void dispose() override
;
179 DECL_LINK(OnEntrySelDesel
, SvTreeListBox
*, void);
180 DECL_LINK( OnDropActionTimer
, Timer
*, void );
182 virtual void _selectionChanged( const lang::EventObject
& aEvent
) override
;
185 virtual void traverseReport(const uno::Reference
< report::XReportDefinition
>& _xReport
) override
;
186 virtual void traverseReportFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
) override
;
187 virtual void traverseReportHeader(const uno::Reference
< report::XSection
>& _xSection
) override
;
188 virtual void traverseReportFooter(const uno::Reference
< report::XSection
>& _xSection
) override
;
189 virtual void traversePageHeader(const uno::Reference
< report::XSection
>& _xSection
) override
;
190 virtual void traversePageFooter(const uno::Reference
< report::XSection
>& _xSection
) override
;
192 virtual void traverseGroups(const uno::Reference
< report::XGroups
>& _xGroups
) override
;
193 virtual void traverseGroup(const uno::Reference
< report::XGroup
>& _xGroup
) override
;
194 virtual void traverseGroupFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
) override
;
195 virtual void traverseGroupHeader(const uno::Reference
< report::XSection
>& _xSection
) override
;
196 virtual void traverseGroupFooter(const uno::Reference
< report::XSection
>& _xSection
) override
;
198 virtual void traverseDetail(const uno::Reference
< report::XSection
>& _xSection
) override
;
200 SvTreeListEntry
* find(const uno::Reference
< uno::XInterface
>& _xContent
);
201 void removeEntry(SvTreeListEntry
* _pEntry
,bool _bRemove
= true);
203 virtual Size
GetOptimalSize() const override
;
205 using SvTreeListBox::ExecuteDrop
;
208 NavigatorTree::NavigatorTree( vcl::Window
* pParent
,OReportController
& _rController
)
209 :SvTreeListBox( pParent
, WB_TABSTOP
| WB_HASBUTTONS
|WB_HASLINES
|WB_BORDER
|WB_HSCROLL
|WB_HASBUTTONSATROOT
)
210 ,comphelper::OSelectionChangeListener()
211 ,OPropertyChangeListener(m_aMutex
)
212 ,m_aTimerTriggered(-1,-1)
213 ,m_aDropActionType( DA_SCROLLUP
)
214 ,m_rController(_rController
)
215 ,m_pMasterReport(nullptr)
216 ,m_pDragedEntry(nullptr)
217 ,m_nTimerCounter( DROP_ACTION_TIMER_INITIAL_TICKS
)
222 m_pReportListener
= new OPropertyChangeMultiplexer(this,m_rController
.getReportDefinition().get());
223 m_pReportListener
->addProperty(PROPERTY_PAGEHEADERON
);
224 m_pReportListener
->addProperty(PROPERTY_PAGEFOOTERON
);
225 m_pReportListener
->addProperty(PROPERTY_REPORTHEADERON
);
226 m_pReportListener
->addProperty(PROPERTY_REPORTFOOTERON
);
228 m_pSelectionListener
= new OSelectionChangeMultiplexer(this,&m_rController
);
230 SetHelpId( HID_REPORT_NAVIGATOR_TREE
);
233 Image(StockImage::Yes
, RID_SVXBMP_COLLAPSEDNODE
),
234 Image(StockImage::Yes
, RID_SVXBMP_EXPANDEDNODE
)
237 SetDragDropMode(DragDropMode::ALL
);
238 EnableInplaceEditing( false );
239 SetSelectionMode(SelectionMode::Multiple
);
242 m_aDropActionTimer
.SetInvokeHandler(LINK(this, NavigatorTree
, OnDropActionTimer
));
243 SetSelectHdl(LINK(this, NavigatorTree
, OnEntrySelDesel
));
244 SetDeselectHdl(LINK(this, NavigatorTree
, OnEntrySelDesel
));
247 NavigatorTree::~NavigatorTree()
252 void NavigatorTree::dispose()
254 SvTreeListEntry
* pCurrent
= First();
257 delete static_cast<UserData
*>(pCurrent
->GetUserData());
258 pCurrent
= Next(pCurrent
);
260 m_pReportListener
->dispose();
261 SvTreeListBox::dispose();
266 sal_uInt16
mapIdent(const OString
& rIdent
)
268 if (rIdent
== "sorting")
269 return SID_SORTINGANDGROUPING
;
270 else if (rIdent
== "page")
271 return SID_PAGEHEADERFOOTER
;
272 else if (rIdent
== "report")
273 return SID_REPORTHEADERFOOTER
;
274 else if (rIdent
== "function")
275 return SID_RPT_NEW_FUNCTION
;
276 else if (rIdent
== "properties")
277 return SID_SHOW_PROPERTYBROWSER
;
278 else if (rIdent
== "delete")
284 void NavigatorTree::Command( const CommandEvent
& rEvt
)
286 bool bHandled
= false;
287 switch( rEvt
.GetCommand())
289 case CommandEventId::ContextMenu
:
291 // the point that was clicked on
292 SvTreeListEntry
* ptClickedOn
= nullptr;
294 if (rEvt
.IsMouseEvent())
296 aWhere
= rEvt
.GetMousePosPixel();
297 ptClickedOn
= GetEntry(aWhere
);
298 if (ptClickedOn
== nullptr)
300 if ( !IsSelected(ptClickedOn
) )
304 SetCurEntry(ptClickedOn
);
309 ptClickedOn
= GetCurEntry();
312 aWhere
= GetEntryPosition(ptClickedOn
);
314 UserData
* pData
= static_cast<UserData
*>(ptClickedOn
->GetUserData());
315 uno::Reference
< report::XFunctionsSupplier
> xSupplier(pData
->getContent(),uno::UNO_QUERY
);
316 uno::Reference
< report::XFunctions
> xFunctions(pData
->getContent(),uno::UNO_QUERY
);
317 uno::Reference
< report::XGroup
> xGroup(pData
->getContent(),uno::UNO_QUERY
);
318 bool bDeleteAllowed
= m_rController
.isEditable() && (xGroup
.is() ||
319 uno::Reference
< report::XFunction
>(pData
->getContent(),uno::UNO_QUERY
).is());
321 VclBuilder
aBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "modules/dbreport/ui/navigatormenu.ui", "");
322 VclPtr
<PopupMenu
> aContextMenu(aBuilder
.get_menu("menu"));
324 sal_uInt16 nCount
= aContextMenu
->GetItemCount();
325 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
327 if ( MenuItemType::SEPARATOR
!= aContextMenu
->GetItemType(i
))
329 sal_uInt16 nMId
= aContextMenu
->GetItemId(i
);
330 sal_uInt16 nSId
= mapIdent(aContextMenu
->GetItemIdent(nMId
));
332 aContextMenu
->CheckItem(nMId
, m_rController
.isCommandChecked(nSId
));
333 bool bEnabled
= m_rController
.isCommandEnabled(nSId
);
334 if (nSId
== SID_RPT_NEW_FUNCTION
)
335 aContextMenu
->EnableItem(nMId
, m_rController
.isEditable() && (xSupplier
.is() || xFunctions
.is()));
336 // special condition, check for function and group
337 else if (nSId
== SID_DELETE
)
338 aContextMenu
->EnableItem(nMId
, bDeleteAllowed
);
340 aContextMenu
->EnableItem(nMId
, bEnabled
);
344 if (aContextMenu
->Execute(this, aWhere
))
346 sal_uInt16 nId
= mapIdent(aContextMenu
->GetCurItemIdent());
347 uno::Sequence
< beans::PropertyValue
> aArgs
;
348 if ( nId
== SID_RPT_NEW_FUNCTION
)
351 aArgs
[0].Value
<<= (xFunctions
.is() ? xFunctions
: xSupplier
->getFunctions());
353 else if ( nId
== SID_DELETE
)
356 nId
= SID_GROUP_REMOVE
;
358 aArgs
[0].Name
= PROPERTY_GROUP
;
359 aArgs
[0].Value
<<= pData
->getContent();
361 m_rController
.executeUnChecked(nId
,aArgs
);
371 SvTreeListBox::Command( rEvt
);
374 sal_Int8
NavigatorTree::AcceptDrop( const AcceptDropEvent
& _rEvt
)
376 ::Point aDropPos
= _rEvt
.maPosPixel
;
379 if (m_aDropActionTimer
.IsActive())
380 m_aDropActionTimer
.Stop();
384 bool bNeedTrigger
= false;
385 // At the first record?
386 if ((aDropPos
.Y() >= 0) && (aDropPos
.Y() < GetEntryHeight()))
388 m_aDropActionType
= DA_SCROLLUP
;
391 else if ((aDropPos
.Y() < GetSizePixel().Height()) && (aDropPos
.Y() >= GetSizePixel().Height() - GetEntryHeight()))
393 m_aDropActionType
= DA_SCROLLDOWN
;
398 SvTreeListEntry
* pDroppedOn
= GetEntry(aDropPos
);
399 if (pDroppedOn
&& (GetChildCount(pDroppedOn
) > 0) && !IsExpanded(pDroppedOn
))
401 m_aDropActionType
= DA_EXPANDNODE
;
406 if (bNeedTrigger
&& (m_aTimerTriggered
!= aDropPos
))
408 // again start counting
409 m_nTimerCounter
= DROP_ACTION_TIMER_INITIAL_TICKS
;
410 // remember the position, because I also get AcceptDrops, if the mouse does not move
411 m_aTimerTriggered
= aDropPos
;
413 if (!m_aDropActionTimer
.IsActive()) // Does the Timer already exists?
415 m_aDropActionTimer
.SetTimeout(DROP_ACTION_TIMER_TICK_BASE
);
416 m_aDropActionTimer
.Start();
419 else if (!bNeedTrigger
)
420 m_aDropActionTimer
.Stop();
423 return DND_ACTION_NONE
;
426 sal_Int8
NavigatorTree::ExecuteDrop( const ExecuteDropEvent
& /*_rEvt*/ )
428 return DND_ACTION_NONE
;
431 void NavigatorTree::StartDrag( sal_Int8
/*_nAction*/, const Point
& _rPosPixel
)
433 m_pDragedEntry
= GetEntry(_rPosPixel
);
434 if ( m_pDragedEntry
)
440 IMPL_LINK_NOARG(NavigatorTree
, OnDropActionTimer
, Timer
*, void)
442 if (--m_nTimerCounter
> 0)
445 switch ( m_aDropActionType
)
449 SvTreeListEntry
* pToExpand
= GetEntry(m_aTimerTriggered
);
450 if (pToExpand
&& (GetChildCount(pToExpand
) > 0) && !IsExpanded(pToExpand
))
452 m_aDropActionTimer
.Stop();
457 ScrollOutputArea( 1 );
458 m_nTimerCounter
= DROP_ACTION_TIMER_SCROLL_TICKS
;
462 ScrollOutputArea( -1 );
463 m_nTimerCounter
= DROP_ACTION_TIMER_SCROLL_TICKS
;
470 IMPL_LINK_NOARG(NavigatorTree
, OnEntrySelDesel
, SvTreeListBox
*, void)
472 if ( !m_pSelectionListener
->locked() )
474 m_pSelectionListener
->lock();
475 SvTreeListEntry
* pEntry
= GetCurEntry();
477 if ( IsSelected(pEntry
) )
478 aSelection
<<= static_cast<UserData
*>(pEntry
->GetUserData())->getContent();
479 m_rController
.select(aSelection
);
480 m_pSelectionListener
->unlock();
484 void NavigatorTree::_selectionChanged( const lang::EventObject
& aEvent
)
486 m_pSelectionListener
->lock();
487 uno::Reference
< view::XSelectionSupplier
> xSelectionSupplier(aEvent
.Source
,uno::UNO_QUERY
);
488 uno::Any aSec
= xSelectionSupplier
->getSelection();
489 uno::Sequence
< uno::Reference
< report::XReportComponent
> > aSelection
;
491 if ( !aSelection
.hasElements() )
493 uno::Reference
< uno::XInterface
> xSelection(aSec
,uno::UNO_QUERY
);
494 SvTreeListEntry
* pEntry
= find(xSelection
);
495 if ( pEntry
&& !IsSelected(pEntry
) )
501 SelectAll(false,false);
505 const uno::Reference
< report::XReportComponent
>* pIter
= aSelection
.getConstArray();
506 const uno::Reference
< report::XReportComponent
>* pEnd
= pIter
+ aSelection
.getLength();
507 for (; pIter
!= pEnd
; ++pIter
)
509 SvTreeListEntry
* pEntry
= find(*pIter
);
510 if ( pEntry
&& !IsSelected(pEntry
) )
517 m_pSelectionListener
->unlock();
520 SvTreeListEntry
* NavigatorTree::insertEntry(const OUString
& _sName
,SvTreeListEntry
* _pParent
, const OUString
& rImageId
, sal_uLong _nPosition
,UserData
* _pData
)
522 SvTreeListEntry
* pEntry
= nullptr;
523 if (!rImageId
.isEmpty())
525 const Image
aImage(StockImage::Yes
, rImageId
);
526 pEntry
= InsertEntry(_sName
,aImage
,aImage
,_pParent
,false,_nPosition
,_pData
);
529 pEntry
= InsertEntry(_sName
,_pParent
,false,_nPosition
,_pData
);
533 void NavigatorTree::traverseSection(const uno::Reference
< report::XSection
>& _xSection
,SvTreeListEntry
* _pParent
, const OUString
& rImageId
, sal_uLong _nPosition
)
535 SvTreeListEntry
* pSection
= insertEntry(_xSection
->getName(),_pParent
, rImageId
, _nPosition
,new UserData(this,_xSection
));
536 const sal_Int32 nCount
= _xSection
->getCount();
537 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
539 uno::Reference
< report::XReportComponent
> xElement(_xSection
->getByIndex(i
),uno::UNO_QUERY_THROW
);
540 insertEntry(lcl_getName(xElement
.get()),pSection
,lcl_getImageId(xElement
),TREELIST_APPEND
,new UserData(this,xElement
));
541 uno::Reference
< report::XReportDefinition
> xSubReport(xElement
,uno::UNO_QUERY
);
542 if ( xSubReport
.is() )
544 m_pMasterReport
= find(_xSection
->getReportDefinition());
545 reportdesign::OReportVisitor
aSubVisitor(this);
546 aSubVisitor
.start(xSubReport
);
551 void NavigatorTree::traverseFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
,SvTreeListEntry
* _pParent
)
553 SvTreeListEntry
* pFunctions
= insertEntry(RptResId(RID_STR_FUNCTIONS
), _pParent
, RID_SVXBMP_RPT_NEW_FUNCTION
, TREELIST_APPEND
, new UserData(this,_xFunctions
));
554 const sal_Int32 nCount
= _xFunctions
->getCount();
555 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
557 uno::Reference
< report::XFunction
> xElement(_xFunctions
->getByIndex(i
),uno::UNO_QUERY
);
558 insertEntry(xElement
->getName(),pFunctions
,RID_SVXBMP_RPT_NEW_FUNCTION
,TREELIST_APPEND
,new UserData(this,xElement
));
562 SvTreeListEntry
* NavigatorTree::find(const uno::Reference
< uno::XInterface
>& _xContent
)
564 SvTreeListEntry
* pRet
= nullptr;
565 if ( _xContent
.is() )
567 SvTreeListEntry
* pCurrent
= First();
570 UserData
* pData
= static_cast<UserData
*>(pCurrent
->GetUserData());
571 OSL_ENSURE(pData
,"No UserData set an entry!");
572 if ( pData
->getContent() == _xContent
)
577 pCurrent
= Next(pCurrent
);
585 void NavigatorTree::traverseReport(const uno::Reference
< report::XReportDefinition
>& _xReport
)
587 insertEntry(_xReport
->getName(),m_pMasterReport
,RID_SVXBMP_SELECT_REPORT
,TREELIST_APPEND
,new UserData(this,_xReport
));
590 void NavigatorTree::traverseReportFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
)
592 SvTreeListEntry
* pReport
= find(_xFunctions
->getParent());
593 traverseFunctions(_xFunctions
,pReport
);
596 void NavigatorTree::traverseReportHeader(const uno::Reference
< report::XSection
>& _xSection
)
598 SvTreeListEntry
* pReport
= find(_xSection
->getReportDefinition());
599 traverseSection(_xSection
,pReport
,RID_SVXBMP_REPORTHEADERFOOTER
);
602 void NavigatorTree::traverseReportFooter(const uno::Reference
< report::XSection
>& _xSection
)
604 SvTreeListEntry
* pReport
= find(_xSection
->getReportDefinition());
605 traverseSection(_xSection
,pReport
,RID_SVXBMP_REPORTHEADERFOOTER
);
608 void NavigatorTree::traversePageHeader(const uno::Reference
< report::XSection
>& _xSection
)
610 SvTreeListEntry
* pReport
= find(_xSection
->getReportDefinition());
611 traverseSection(_xSection
,pReport
,RID_SVXBMP_PAGEHEADERFOOTER
);
614 void NavigatorTree::traversePageFooter(const uno::Reference
< report::XSection
>& _xSection
)
616 SvTreeListEntry
* pReport
= find(_xSection
->getReportDefinition());
617 traverseSection(_xSection
,pReport
,RID_SVXBMP_PAGEHEADERFOOTER
);
620 void NavigatorTree::traverseGroups(const uno::Reference
< report::XGroups
>& _xGroups
)
622 SvTreeListEntry
* pReport
= find(_xGroups
->getReportDefinition());
623 insertEntry(RptResId(RID_STR_GROUPS
), pReport
, RID_SVXBMP_SORTINGANDGROUPING
, TREELIST_APPEND
, new UserData(this,_xGroups
));
626 void NavigatorTree::traverseGroup(const uno::Reference
< report::XGroup
>& _xGroup
)
628 uno::Reference
< report::XGroups
> xGroups(_xGroup
->getParent(),uno::UNO_QUERY
);
629 SvTreeListEntry
* pGroups
= find(xGroups
);
630 OSL_ENSURE(pGroups
,"No Groups inserted so far. Why!");
631 insertEntry(_xGroup
->getExpression(),pGroups
,RID_SVXBMP_GROUP
,rptui::getPositionInIndexAccess(xGroups
.get(),_xGroup
),new UserData(this,_xGroup
));
634 void NavigatorTree::traverseGroupFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
)
636 SvTreeListEntry
* pGroup
= find(_xFunctions
->getParent());
637 traverseFunctions(_xFunctions
,pGroup
);
640 void NavigatorTree::traverseGroupHeader(const uno::Reference
< report::XSection
>& _xSection
)
642 SvTreeListEntry
* pGroup
= find(_xSection
->getGroup());
643 OSL_ENSURE(pGroup
,"No group found");
644 traverseSection(_xSection
,pGroup
,RID_SVXBMP_GROUPHEADER
,1);
647 void NavigatorTree::traverseGroupFooter(const uno::Reference
< report::XSection
>& _xSection
)
649 SvTreeListEntry
* pGroup
= find(_xSection
->getGroup());
650 OSL_ENSURE(pGroup
,"No group found");
651 traverseSection(_xSection
,pGroup
,RID_SVXBMP_GROUPFOOTER
);
654 void NavigatorTree::traverseDetail(const uno::Reference
< report::XSection
>& _xSection
)
656 uno::Reference
< report::XReportDefinition
> xReport
= _xSection
->getReportDefinition();
657 SvTreeListEntry
* pParent
= find(xReport
);
658 traverseSection(_xSection
,pParent
,RID_SVXBMP_ICON_DETAIL
);
661 void NavigatorTree::_propertyChanged(const beans::PropertyChangeEvent
& _rEvent
)
663 uno::Reference
< report::XReportDefinition
> xReport(_rEvent
.Source
,uno::UNO_QUERY
);
666 bool bEnabled
= false;
667 _rEvent
.NewValue
>>= bEnabled
;
670 SvTreeListEntry
* pParent
= find(xReport
);
671 if ( _rEvent
.PropertyName
== PROPERTY_REPORTHEADERON
)
673 sal_uLong nPos
= xReport
->getReportHeaderOn() ? 2 : 1;
674 traverseSection(xReport
->getReportHeader(),pParent
,RID_SVXBMP_REPORTHEADERFOOTER
,nPos
);
676 else if ( _rEvent
.PropertyName
== PROPERTY_PAGEHEADERON
)
678 traverseSection(xReport
->getPageHeader(),pParent
, RID_SVXBMP_PAGEHEADERFOOTER
,1);
680 else if ( _rEvent
.PropertyName
== PROPERTY_PAGEFOOTERON
)
681 traverseSection(xReport
->getPageFooter(),pParent
, RID_SVXBMP_PAGEHEADERFOOTER
);
682 else if ( _rEvent
.PropertyName
== PROPERTY_REPORTFOOTERON
)
684 sal_uLong nPos
= xReport
->getPageFooterOn() ? (GetLevelChildCount(pParent
) - 1) : TREELIST_APPEND
;
685 traverseSection(xReport
->getReportFooter(),pParent
,RID_SVXBMP_REPORTHEADERFOOTER
,nPos
);
691 void NavigatorTree::_elementInserted( const container::ContainerEvent
& _rEvent
)
693 SvTreeListEntry
* pEntry
= find(_rEvent
.Source
);
694 uno::Reference
<beans::XPropertySet
> xProp(_rEvent
.Element
,uno::UNO_QUERY_THROW
);
696 uno::Reference
< beans::XPropertySetInfo
> xInfo
= xProp
->getPropertySetInfo();
699 if ( xInfo
->hasPropertyByName(PROPERTY_NAME
) )
700 xProp
->getPropertyValue(PROPERTY_NAME
) >>= sName
;
701 else if ( xInfo
->hasPropertyByName(PROPERTY_EXPRESSION
) )
702 xProp
->getPropertyValue(PROPERTY_EXPRESSION
) >>= sName
;
704 uno::Reference
< report::XGroup
> xGroup(xProp
,uno::UNO_QUERY
);
707 reportdesign::OReportVisitor
aSubVisitor(this);
708 aSubVisitor
.start(xGroup
);
712 uno::Reference
< report::XReportComponent
> xElement(xProp
,uno::UNO_QUERY
);
714 sName
= lcl_getName(xProp
);
715 insertEntry(sName
,pEntry
,(!xElement
.is() ? OUString(RID_SVXBMP_RPT_NEW_FUNCTION
) : lcl_getImageId(xElement
)),TREELIST_APPEND
,new UserData(this,xProp
));
717 if ( !IsExpanded(pEntry
) )
721 void NavigatorTree::_elementRemoved( const container::ContainerEvent
& _rEvent
)
723 uno::Reference
<beans::XPropertySet
> xProp(_rEvent
.Element
,uno::UNO_QUERY
);
724 SvTreeListEntry
* pEntry
= find(xProp
);
725 OSL_ENSURE(pEntry
,"NavigatorTree::_elementRemoved: No Entry found!");
734 void NavigatorTree::_elementReplaced( const container::ContainerEvent
& _rEvent
)
736 uno::Reference
<beans::XPropertySet
> xProp(_rEvent
.ReplacedElement
,uno::UNO_QUERY
);
737 SvTreeListEntry
* pEntry
= find(xProp
);
740 UserData
* pData
= static_cast<UserData
*>(pEntry
->GetUserData());
741 xProp
.set(_rEvent
.Element
,uno::UNO_QUERY
);
742 pData
->setContent(xProp
);
744 xProp
->getPropertyValue(PROPERTY_NAME
) >>= sName
;
745 SetEntryText(pEntry
,sName
);
749 void NavigatorTree::_disposing(const lang::EventObject
& _rSource
)
751 removeEntry(find(_rSource
.Source
));
754 void NavigatorTree::removeEntry(SvTreeListEntry
* _pEntry
,bool _bRemove
)
758 SvTreeListEntry
* pChild
= FirstChild(_pEntry
);
761 removeEntry(pChild
,false);
762 pChild
= pChild
->NextSibling();
764 delete static_cast<UserData
*>(_pEntry
->GetUserData());
766 GetModel()->Remove(_pEntry
);
770 NavigatorTree::UserData::UserData(NavigatorTree
* _pTree
,const uno::Reference
<uno::XInterface
>& _xContent
)
771 : OPropertyChangeListener(m_aMutex
)
772 , OContainerListener(m_aMutex
)
773 , m_xContent(_xContent
)
776 uno::Reference
<beans::XPropertySet
> xProp(m_xContent
,uno::UNO_QUERY
);
779 uno::Reference
< beans::XPropertySetInfo
> xInfo
= xProp
->getPropertySetInfo();
782 m_pListener
= new ::comphelper::OPropertyChangeMultiplexer(this,xProp
);
783 if ( xInfo
->hasPropertyByName(PROPERTY_NAME
) )
784 m_pListener
->addProperty(PROPERTY_NAME
);
785 else if ( xInfo
->hasPropertyByName(PROPERTY_EXPRESSION
) )
786 m_pListener
->addProperty(PROPERTY_EXPRESSION
);
787 if ( xInfo
->hasPropertyByName(PROPERTY_DATAFIELD
) )
788 m_pListener
->addProperty(PROPERTY_DATAFIELD
);
789 if ( xInfo
->hasPropertyByName(PROPERTY_LABEL
) )
790 m_pListener
->addProperty(PROPERTY_LABEL
);
791 if ( xInfo
->hasPropertyByName(PROPERTY_HEADERON
) )
792 m_pListener
->addProperty(PROPERTY_HEADERON
);
793 if ( xInfo
->hasPropertyByName(PROPERTY_FOOTERON
) )
794 m_pListener
->addProperty(PROPERTY_FOOTERON
);
797 uno::Reference
< container::XContainer
> xContainer(m_xContent
,uno::UNO_QUERY
);
798 if ( xContainer
.is() )
800 m_pContainerListener
= new ::comphelper::OContainerListenerAdapter(this,xContainer
);
804 NavigatorTree::UserData::~UserData()
806 if ( m_pContainerListener
.is() )
807 m_pContainerListener
->dispose();
808 if ( m_pListener
.is() )
809 m_pListener
->dispose();
812 // OPropertyChangeListener
813 void NavigatorTree::UserData::_propertyChanged(const beans::PropertyChangeEvent
& _rEvent
)
815 SvTreeListEntry
* pEntry
= m_pTree
->find(_rEvent
.Source
);
816 OSL_ENSURE(pEntry
,"No entry could be found! Why not!");
817 const bool bFooterOn
= (PROPERTY_FOOTERON
== _rEvent
.PropertyName
);
820 if ( bFooterOn
|| PROPERTY_HEADERON
== _rEvent
.PropertyName
)
823 uno::Reference
< report::XGroup
> xGroup(_rEvent
.Source
,uno::UNO_QUERY
);
824 ::std::function
<bool(OGroupHelper
*)> pIsOn
= ::std::mem_fn(&OGroupHelper::getHeaderOn
);
825 ::std::function
<uno::Reference
<report::XSection
>(OGroupHelper
*)> pMemFunSection
= ::std::mem_fn(&OGroupHelper::getHeader
);
828 pIsOn
= ::std::mem_fn(&OGroupHelper::getFooterOn
);
829 pMemFunSection
= ::std::mem_fn(&OGroupHelper::getFooter
);
830 nPos
= m_pTree
->GetChildCount(pEntry
) - 1;
833 OGroupHelper
aGroupHelper(xGroup
);
834 if ( pIsOn(&aGroupHelper
) )
838 m_pTree
->traverseSection(pMemFunSection(&aGroupHelper
),pEntry
,bFooterOn
? OUString(RID_SVXBMP_GROUPFOOTER
) : OUString(RID_SVXBMP_GROUPHEADER
),nPos
);
841 else if ( PROPERTY_EXPRESSION
== _rEvent
.PropertyName
)
844 _rEvent
.NewValue
>>= sNewName
;
845 m_pTree
->SetEntryText(pEntry
,sNewName
);
847 else if ( PROPERTY_DATAFIELD
== _rEvent
.PropertyName
|| PROPERTY_LABEL
== _rEvent
.PropertyName
|| PROPERTY_NAME
== _rEvent
.PropertyName
)
849 uno::Reference
<beans::XPropertySet
> xProp(_rEvent
.Source
,uno::UNO_QUERY
);
850 m_pTree
->SetEntryText(pEntry
,lcl_getName(xProp
));
853 catch(const uno::Exception
&)
857 void NavigatorTree::UserData::_elementInserted( const container::ContainerEvent
& _rEvent
)
859 m_pTree
->_elementInserted( _rEvent
);
862 void NavigatorTree::UserData::_elementRemoved( const container::ContainerEvent
& _rEvent
)
864 m_pTree
->_elementRemoved( _rEvent
);
867 void NavigatorTree::UserData::_elementReplaced( const container::ContainerEvent
& _rEvent
)
869 m_pTree
->_elementReplaced( _rEvent
);
872 void NavigatorTree::UserData::_disposing(const lang::EventObject
& _rSource
)
874 m_pTree
->_disposing( _rSource
);
877 Size
NavigatorTree::GetOptimalSize() const
879 return LogicToPixel(Size(100, 70), MapMode(MapUnit::MapAppFont
));
882 // class ONavigatorImpl
886 ONavigatorImpl(OReportController
& _rController
,ONavigator
* _pParent
);
887 ONavigatorImpl(const ONavigatorImpl
&) = delete;
888 ONavigatorImpl
& operator=(const ONavigatorImpl
&) = delete;
890 uno::Reference
< report::XReportDefinition
> m_xReport
;
891 ::rptui::OReportController
& m_rController
;
892 VclPtr
<NavigatorTree
> m_pNavigatorTree
;
895 ONavigatorImpl::ONavigatorImpl(OReportController
& _rController
,ONavigator
* _pParent
)
896 :m_xReport(_rController
.getReportDefinition())
897 ,m_rController(_rController
)
898 ,m_pNavigatorTree(VclPtr
<NavigatorTree
>::Create(_pParent
->get
<vcl::Window
>("box"),_rController
))
900 reportdesign::OReportVisitor
aVisitor(m_pNavigatorTree
.get());
901 aVisitor
.start(m_xReport
);
902 m_pNavigatorTree
->Expand(m_pNavigatorTree
->find(m_xReport
));
903 lang::EventObject
aEvent(m_rController
);
904 m_pNavigatorTree
->_selectionChanged(aEvent
);
908 ONavigator::ONavigator(vcl::Window
* _pParent
,OReportController
& _rController
)
909 : FloatingWindow( _pParent
, "FloatingNavigator", "modules/dbreport/ui/floatingnavigator.ui")
911 m_pImpl
.reset(new ONavigatorImpl(_rController
,this));
913 m_pImpl
->m_pNavigatorTree
->Show();
914 m_pImpl
->m_pNavigatorTree
->GrabFocus();
918 void ONavigator::GetFocus()
921 if ( m_pImpl
->m_pNavigatorTree
.get() )
922 m_pImpl
->m_pNavigatorTree
->GrabFocus();
925 void ONavigator::dispose()
927 m_pImpl
->m_pNavigatorTree
.disposeAndClear();
928 FloatingWindow::dispose();
934 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */