1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: Navigator.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
30 #include "precompiled_reportdesign.hxx"
32 #include "Navigator.hxx"
34 #include "uistrings.hrc"
35 #include "ReportController.hxx"
36 #include "UITools.hxx"
38 #include "reportformula.hxx"
39 #include <com/sun/star/container/XContainerListener.hpp>
40 #include <com/sun/star/report/XReportDefinition.hpp>
41 #include <com/sun/star/report/XFixedText.hpp>
42 #include <com/sun/star/report/XFixedLine.hpp>
43 #include <com/sun/star/report/XFormattedField.hpp>
44 #include <com/sun/star/report/XImageControl.hpp>
45 #include <com/sun/star/report/XShape.hpp>
46 #include <svx/globlmn.hrc>
47 #include <svx/svxids.hrc>
48 #include "helpids.hrc"
49 #include "RptResId.hrc"
50 #include "rptui_slotid.hrc"
51 #include <tools/debug.hxx>
52 #include <comphelper/propmultiplex.hxx>
53 #include <comphelper/containermultiplexer.hxx>
54 #include <comphelper/types.hxx>
55 #include "cppuhelper/basemutex.hxx"
56 #include "comphelper/SelectionMultiplex.hxx"
57 #include <svtools/svtreebx.hxx>
58 #include <svtools/solar.hrc>
59 #include "ReportVisitor.hxx"
60 #include "ModuleHelper.hxx"
61 #include <rtl/ref.hxx>
63 #include <boost/bind.hpp>
67 #define RID_SVXIMG_COLLAPSEDNODE (RID_FORMS_START + 2)
68 #define RID_SVXIMG_EXPANDEDNODE (RID_FORMS_START + 3)
69 #define DROP_ACTION_TIMER_INITIAL_TICKS 10
70 #define DROP_ACTION_TIMER_SCROLL_TICKS 3
71 #define DROP_ACTION_TIMER_TICK_BASE 10
75 using namespace ::com::sun::star
;
77 using namespace ::comphelper
;
79 USHORT
lcl_getImageId(const uno::Reference
< report::XReportComponent
>& _xElement
)
82 uno::Reference
< report::XFixedLine
> xFixedLine(_xElement
,uno::UNO_QUERY
);
83 if ( uno::Reference
< report::XFixedText
>(_xElement
,uno::UNO_QUERY
).is() )
84 nId
= SID_FM_FIXEDTEXT
;
85 else if ( xFixedLine
.is() )
86 nId
= xFixedLine
->getOrientation() ? SID_INSERT_VFIXEDLINE
: SID_INSERT_HFIXEDLINE
;
87 else if ( uno::Reference
< report::XFormattedField
>(_xElement
,uno::UNO_QUERY
).is() )
89 else if ( uno::Reference
< report::XImageControl
>(_xElement
,uno::UNO_QUERY
).is() )
90 nId
= SID_FM_IMAGECONTROL
;
91 else if ( uno::Reference
< report::XShape
>(_xElement
,uno::UNO_QUERY
).is() )
92 nId
= SID_DRAWTBX_CS_BASIC
;
95 // -----------------------------------------------------------------------------
96 ::rtl::OUString
lcl_getName(const uno::Reference
< beans::XPropertySet
>& _xElement
)
98 OSL_ENSURE(_xElement
.is(),"Found report element which is NULL!");
99 ::rtl::OUString sTempName
;
100 _xElement
->getPropertyValue(PROPERTY_NAME
) >>= sTempName
;
101 ::rtl::OUStringBuffer sName
= sTempName
;
102 uno::Reference
< report::XFixedText
> xFixedText(_xElement
,uno::UNO_QUERY
);
103 uno::Reference
< report::XReportControlModel
> xReportModel(_xElement
,uno::UNO_QUERY
);
104 if ( xFixedText
.is() )
106 sName
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : ")));
107 sName
.append(xFixedText
->getLabel());
109 else if ( xReportModel
.is() && _xElement
->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD
) )
111 ReportFormula
aFormula( xReportModel
->getDataField() );
112 if ( aFormula
.isValid() )
114 sName
.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : ")));
115 sName
.append( aFormula
.getUndecoratedContent() );
118 return sName
.makeStringAndClear();
120 // -----------------------------------------------------------------------------
122 class NavigatorTree
: public ::cppu::BaseMutex
123 , public SvTreeListBox
124 , public reportdesign::ITraverseReport
125 , public comphelper::OSelectionChangeListener
126 , public ::comphelper::OPropertyChangeListener
129 friend class UserData
;
130 class UserData
: public ::cppu::BaseMutex
131 ,public ::comphelper::OPropertyChangeListener
132 ,public ::comphelper::OContainerListener
134 uno::Reference
< uno::XInterface
> m_xContent
;
135 ::rtl::Reference
< comphelper::OPropertyChangeMultiplexer
> m_pListener
;
136 ::rtl::Reference
< comphelper::OContainerListenerAdapter
> m_pContainerListener
;
137 NavigatorTree
* m_pTree
;
139 UserData(NavigatorTree
* _pTree
,const uno::Reference
<uno::XInterface
>& _xContent
);
142 inline uno::Reference
< uno::XInterface
> getContent() const { return m_xContent
; }
143 inline void setContent(const uno::Reference
< uno::XInterface
>& _xContent
) { m_xContent
= _xContent
; }
145 // OPropertyChangeListener
146 virtual void _propertyChanged(const beans::PropertyChangeEvent
& _rEvent
) throw( uno::RuntimeException
);
148 // OContainerListener
149 virtual void _elementInserted( const container::ContainerEvent
& _rEvent
) throw(uno::RuntimeException
);
150 virtual void _elementRemoved( const container::ContainerEvent
& _Event
) throw(uno::RuntimeException
);
151 virtual void _elementReplaced( const container::ContainerEvent
& _rEvent
) throw(uno::RuntimeException
);
152 virtual void _disposing(const lang::EventObject
& _rSource
) throw( uno::RuntimeException
);
155 enum DROP_ACTION
{ DA_SCROLLUP
, DA_SCROLLDOWN
, DA_EXPANDNODE
};
156 AutoTimer m_aDropActionTimer
;
157 Timer m_aSynchronizeTimer
;
158 ImageList m_aNavigatorImages
;
159 ImageList m_aNavigatorImagesHC
;
160 Point m_aTimerTriggered
; // die Position, an der der DropTimer angeschaltet wurde
161 DROP_ACTION m_aDropActionType
;
162 OReportController
& m_rController
;
163 SvLBoxEntry
* m_pMasterReport
;
164 SvLBoxEntry
* m_pDragedEntry
;
165 ::rtl::Reference
< comphelper::OPropertyChangeMultiplexer
> m_pReportListener
;
166 ::rtl::Reference
< comphelper::OSelectionChangeMultiplexer
> m_pSelectionListener
;
167 unsigned short m_nTimerCounter
;
169 SvLBoxEntry
* insertEntry(const ::rtl::OUString
& _sName
,SvLBoxEntry
* _pParent
,USHORT _nImageId
,ULONG _nPosition
,UserData
* _pData
);
170 void traverseSection(const uno::Reference
< report::XSection
>& _xSection
,SvLBoxEntry
* _pParent
,USHORT _nImageId
,ULONG _nPosition
= LIST_APPEND
);
171 void traverseFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
,SvLBoxEntry
* _pParent
);
173 NavigatorTree(const NavigatorTree
&);
174 void operator =(const NavigatorTree
&);
176 virtual void Command( const CommandEvent
& rEvt
);
177 // DragSourceHelper overridables
178 virtual void StartDrag( sal_Int8 nAction
, const Point
& rPosPixel
);
179 // DropTargetHelper overridables
180 virtual sal_Int8
AcceptDrop( const AcceptDropEvent
& _rEvt
);
181 virtual sal_Int8
ExecuteDrop( const ExecuteDropEvent
& _rEvt
);
183 // OSelectionChangeListener
184 virtual void _disposing(const lang::EventObject
& _rSource
) throw( uno::RuntimeException
);
186 // OPropertyChangeListener
187 virtual void _propertyChanged(const beans::PropertyChangeEvent
& _rEvent
) throw( uno::RuntimeException
);
189 // OContainerListener Helper
190 void _elementInserted( const container::ContainerEvent
& _rEvent
);
191 void _elementRemoved( const container::ContainerEvent
& _Event
);
192 void _elementReplaced( const container::ContainerEvent
& _rEvent
);
195 NavigatorTree(Window
* pParent
,OReportController
& _rController
);
196 virtual ~NavigatorTree();
198 DECL_LINK(OnEntrySelDesel
, NavigatorTree
*);
199 DECL_LINK( OnDropActionTimer
, void* );
201 virtual void _selectionChanged( const lang::EventObject
& aEvent
) throw (uno::RuntimeException
);
204 virtual void traverseReport(const uno::Reference
< report::XReportDefinition
>& _xReport
);
205 virtual void traverseReportFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
);
206 virtual void traverseReportHeader(const uno::Reference
< report::XSection
>& _xSection
);
207 virtual void traverseReportFooter(const uno::Reference
< report::XSection
>& _xSection
);
208 virtual void traversePageHeader(const uno::Reference
< report::XSection
>& _xSection
);
209 virtual void traversePageFooter(const uno::Reference
< report::XSection
>& _xSection
);
211 virtual void traverseGroups(const uno::Reference
< report::XGroups
>& _xGroups
);
212 virtual void traverseGroup(const uno::Reference
< report::XGroup
>& _xGroup
);
213 virtual void traverseGroupFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
);
214 virtual void traverseGroupHeader(const uno::Reference
< report::XSection
>& _xSection
);
215 virtual void traverseGroupFooter(const uno::Reference
< report::XSection
>& _xSection
);
217 virtual void traverseDetail(const uno::Reference
< report::XSection
>& _xSection
);
219 SvLBoxEntry
* find(const uno::Reference
< uno::XInterface
>& _xContent
);
220 void removeEntry(SvLBoxEntry
* _pEntry
,bool _bRemove
= true);
222 using SvTreeListBox::ExecuteDrop
;
224 DBG_NAME(rpt_NavigatorTree
)
225 // -----------------------------------------------------------------------------
226 NavigatorTree::NavigatorTree( Window
* pParent
,OReportController
& _rController
)
227 :SvTreeListBox( pParent
, WB_TABSTOP
| WB_HASBUTTONS
|WB_HASLINES
|WB_BORDER
|WB_HSCROLL
|WB_HASBUTTONSATROOT
)
228 ,comphelper::OSelectionChangeListener(m_aMutex
)
229 ,OPropertyChangeListener(m_aMutex
)
230 ,m_aTimerTriggered(-1,-1)
231 ,m_aDropActionType( DA_SCROLLUP
)
232 ,m_rController(_rController
)
233 ,m_pMasterReport(NULL
)
234 ,m_pDragedEntry(NULL
)
235 ,m_nTimerCounter( DROP_ACTION_TIMER_INITIAL_TICKS
)
237 DBG_CTOR(rpt_NavigatorTree
,NULL
);
238 m_pReportListener
= new OPropertyChangeMultiplexer(this,m_rController
.getReportDefinition().get());
239 m_pReportListener
->addProperty(PROPERTY_PAGEHEADERON
);
240 m_pReportListener
->addProperty(PROPERTY_PAGEFOOTERON
);
241 m_pReportListener
->addProperty(PROPERTY_REPORTHEADERON
);
242 m_pReportListener
->addProperty(PROPERTY_REPORTFOOTERON
);
244 m_pSelectionListener
= new OSelectionChangeMultiplexer(this,&m_rController
);
246 SetHelpId( HID_REPORT_NAVIGATOR_TREE
);
248 m_aNavigatorImages
= ImageList( ModuleRes( RID_SVXIMGLIST_RPTEXPL
) );
249 m_aNavigatorImagesHC
= ImageList( ModuleRes( RID_SVXIMGLIST_RPTEXPL_HC
) );
252 m_aNavigatorImages
.GetImage( RID_SVXIMG_COLLAPSEDNODE
),
253 m_aNavigatorImages
.GetImage( RID_SVXIMG_EXPANDEDNODE
),
257 m_aNavigatorImagesHC
.GetImage( RID_SVXIMG_COLLAPSEDNODE
),
258 m_aNavigatorImagesHC
.GetImage( RID_SVXIMG_EXPANDEDNODE
),
259 BMP_COLOR_HIGHCONTRAST
262 SetDragDropMode(0xFFFF);
263 EnableInplaceEditing( sal_False
);
264 SetSelectionMode(MULTIPLE_SELECTION
);
267 m_aDropActionTimer
.SetTimeoutHdl(LINK(this, NavigatorTree
, OnDropActionTimer
));
268 SetSelectHdl(LINK(this, NavigatorTree
, OnEntrySelDesel
));
269 SetDeselectHdl(LINK(this, NavigatorTree
, OnEntrySelDesel
));
271 // -----------------------------------------------------------------------------
272 NavigatorTree::~NavigatorTree()
274 SvLBoxEntry
* pCurrent
= First();
277 delete static_cast<UserData
*>(pCurrent
->GetUserData());
278 pCurrent
= Next(pCurrent
);
280 m_pReportListener
->dispose();
281 m_pSelectionListener
->dispose();
282 DBG_DTOR(rpt_NavigatorTree
,NULL
);
284 //------------------------------------------------------------------------------
285 void NavigatorTree::Command( const CommandEvent
& rEvt
)
287 sal_Bool bHandled
= sal_False
;
288 switch( rEvt
.GetCommand() )
290 case COMMAND_CONTEXTMENU
:
292 // die Stelle, an der geklickt wurde
293 SvLBoxEntry
* ptClickedOn
= NULL
;
295 if (rEvt
.IsMouseEvent())
297 aWhere
= rEvt
.GetMousePosPixel();
298 ptClickedOn
= GetEntry(aWhere
);
299 if (ptClickedOn
== NULL
)
301 if ( !IsSelected(ptClickedOn
) )
303 SelectAll(sal_False
);
304 Select(ptClickedOn
, sal_True
);
305 SetCurEntry(ptClickedOn
);
310 ptClickedOn
= GetCurEntry();
313 aWhere
= GetEntryPosition(ptClickedOn
);
315 UserData
* pData
= static_cast<UserData
*>(ptClickedOn
->GetUserData());
316 uno::Reference
< report::XFunctionsSupplier
> xSupplier(pData
->getContent(),uno::UNO_QUERY
);
317 uno::Reference
< report::XFunctions
> xFunctions(pData
->getContent(),uno::UNO_QUERY
);
318 uno::Reference
< report::XGroup
> xGroup(pData
->getContent(),uno::UNO_QUERY
);
319 sal_Bool bDeleteAllowed
= m_rController
.isEditable() && (xGroup
.is() ||
320 uno::Reference
< report::XFunction
>(pData
->getContent(),uno::UNO_QUERY
).is());
321 PopupMenu
aContextMenu( ModuleRes( RID_MENU_NAVIGATOR
) );
323 USHORT nCount
= aContextMenu
.GetItemCount();
324 for (USHORT i
= 0; i
< nCount
; ++i
)
326 if ( MENUITEM_SEPARATOR
!= aContextMenu
.GetItemType(i
))
328 USHORT nId
= aContextMenu
.GetItemId(i
);
330 aContextMenu
.CheckItem(nId
,m_rController
.isCommandChecked(nId
));
331 sal_Bool bEnabled
= m_rController
.isCommandEnabled(nId
);
332 if ( nId
== SID_RPT_NEW_FUNCTION
)
333 aContextMenu
.EnableItem(nId
,m_rController
.isEditable() && (xSupplier
.is() || xFunctions
.is()) );
334 // special condition, check for function and group
335 else if ( nId
== SID_DELETE
)
336 aContextMenu
.EnableItem(SID_DELETE
,bDeleteAllowed
);
338 aContextMenu
.EnableItem(nId
,bEnabled
);
340 } // for (USHORT i = 0; i < nCount; ++i)
341 USHORT nId
= aContextMenu
.Execute(this, aWhere
);
344 uno::Sequence
< beans::PropertyValue
> aArgs
;
345 if ( nId
== SID_RPT_NEW_FUNCTION
)
348 aArgs
[0].Value
<<= (xFunctions
.is() ? xFunctions
: xSupplier
->getFunctions());
350 else if ( nId
== SID_DELETE
)
353 nId
= SID_GROUP_REMOVE
;
355 aArgs
[0].Name
= PROPERTY_GROUP
;
356 aArgs
[0].Value
<<= pData
->getContent();
358 m_rController
.executeUnChecked(nId
,aArgs
);
366 SvTreeListBox::Command( rEvt
);
368 // -----------------------------------------------------------------------------
369 sal_Int8
NavigatorTree::AcceptDrop( const AcceptDropEvent
& _rEvt
)
371 sal_Int8 nDropOption
= DND_ACTION_NONE
;
372 ::Point aDropPos
= _rEvt
.maPosPixel
;
375 if (m_aDropActionTimer
.IsActive())
376 m_aDropActionTimer
.Stop();
380 bool bNeedTrigger
= false;
381 // auf dem ersten Eintrag ?
382 if ((aDropPos
.Y() >= 0) && (aDropPos
.Y() < GetEntryHeight()))
384 m_aDropActionType
= DA_SCROLLUP
;
387 else if ((aDropPos
.Y() < GetSizePixel().Height()) && (aDropPos
.Y() >= GetSizePixel().Height() - GetEntryHeight()))
389 m_aDropActionType
= DA_SCROLLDOWN
;
394 SvLBoxEntry
* pDropppedOn
= GetEntry(aDropPos
);
395 if (pDropppedOn
&& (GetChildCount(pDropppedOn
) > 0) && !IsExpanded(pDropppedOn
))
397 m_aDropActionType
= DA_EXPANDNODE
;
402 if (bNeedTrigger
&& (m_aTimerTriggered
!= aDropPos
))
404 // neu anfangen zu zaehlen
405 m_nTimerCounter
= DROP_ACTION_TIMER_INITIAL_TICKS
;
406 // die Pos merken, da ich auch AcceptDrops bekomme, wenn sich die Maus gar nicht bewegt hat
407 m_aTimerTriggered
= aDropPos
;
409 if (!m_aDropActionTimer
.IsActive()) // gibt es den Timer schon ?
411 m_aDropActionTimer
.SetTimeout(DROP_ACTION_TIMER_TICK_BASE
);
412 m_aDropActionTimer
.Start();
415 else if (!bNeedTrigger
)
416 m_aDropActionTimer
.Stop();
421 // -------------------------------------------------------------------------
422 sal_Int8
NavigatorTree::ExecuteDrop( const ExecuteDropEvent
& /*_rEvt*/ )
425 return DND_ACTION_NONE
;
427 // -------------------------------------------------------------------------
428 void NavigatorTree::StartDrag( sal_Int8
/*_nAction*/, const Point
& _rPosPixel
)
430 m_pDragedEntry
= GetEntry(_rPosPixel
);
431 if ( m_pDragedEntry
)
436 //------------------------------------------------------------------------
437 IMPL_LINK( NavigatorTree
, OnDropActionTimer
, void*, EMPTYARG
)
439 if (--m_nTimerCounter
> 0)
442 switch ( m_aDropActionType
)
446 SvLBoxEntry
* pToExpand
= GetEntry(m_aTimerTriggered
);
447 if (pToExpand
&& (GetChildCount(pToExpand
) > 0) && !IsExpanded(pToExpand
))
448 // tja, eigentlich muesste ich noch testen, ob die Node nicht schon expandiert ist, aber ich
449 // habe dazu weder in den Basisklassen noch im Model eine Methode gefunden ...
450 // aber ich denke, die BK sollte es auch so vertragen
453 // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
454 m_aDropActionTimer
.Stop();
459 ScrollOutputArea( 1 );
460 m_nTimerCounter
= DROP_ACTION_TIMER_SCROLL_TICKS
;
464 ScrollOutputArea( -1 );
465 m_nTimerCounter
= DROP_ACTION_TIMER_SCROLL_TICKS
;
473 // -----------------------------------------------------------------------------
474 IMPL_LINK(NavigatorTree
, OnEntrySelDesel
, NavigatorTree
*, /*pThis*/)
476 if ( !m_pSelectionListener
->locked() )
478 m_pSelectionListener
->lock();
479 SvLBoxEntry
* pEntry
= GetCurEntry();
481 if ( IsSelected(pEntry
) )
482 aSelection
<<= static_cast<UserData
*>(pEntry
->GetUserData())->getContent();
483 m_rController
.select(aSelection
);
484 m_pSelectionListener
->unlock();
489 // -----------------------------------------------------------------------------
490 void NavigatorTree::_selectionChanged( const lang::EventObject
& aEvent
) throw (uno::RuntimeException
)
492 m_pSelectionListener
->lock();
493 uno::Reference
< view::XSelectionSupplier
> xSelectionSupplier(aEvent
.Source
,uno::UNO_QUERY
);
494 uno::Any aSec
= xSelectionSupplier
->getSelection();
495 uno::Sequence
< uno::Reference
< report::XReportComponent
> > aSelection
;
497 if ( !aSelection
.getLength() )
499 uno::Reference
< uno::XInterface
> xSelection(aSec
,uno::UNO_QUERY
);
500 SvLBoxEntry
* pEntry
= find(xSelection
);
501 if ( pEntry
&& !IsSelected(pEntry
) )
503 Select(pEntry
, sal_True
);
507 SelectAll(FALSE
,FALSE
);
511 const uno::Reference
< report::XReportComponent
>* pIter
= aSelection
.getConstArray();
512 const uno::Reference
< report::XReportComponent
>* pEnd
= pIter
+ aSelection
.getLength();
513 for (; pIter
!= pEnd
; ++pIter
)
515 SvLBoxEntry
* pEntry
= find(*pIter
);
516 if ( pEntry
&& !IsSelected(pEntry
) )
518 Select(pEntry
, sal_True
);
523 m_pSelectionListener
->unlock();
525 // -----------------------------------------------------------------------------
526 SvLBoxEntry
* NavigatorTree::insertEntry(const ::rtl::OUString
& _sName
,SvLBoxEntry
* _pParent
,USHORT _nImageId
,ULONG _nPosition
,UserData
* _pData
)
528 SvLBoxEntry
* pEntry
= NULL
;
531 const Image
aImage( m_aNavigatorImages
.GetImage( _nImageId
) );
532 pEntry
= InsertEntry(_sName
,aImage
,aImage
,_pParent
,FALSE
,_nPosition
,_pData
);
535 const Image
aImageHC( m_aNavigatorImagesHC
.GetImage( _nImageId
) );
536 SetExpandedEntryBmp( pEntry
, aImageHC
, BMP_COLOR_HIGHCONTRAST
);
537 SetCollapsedEntryBmp( pEntry
, aImageHC
, BMP_COLOR_HIGHCONTRAST
);
541 pEntry
= InsertEntry(_sName
,_pParent
,FALSE
,_nPosition
,_pData
);
544 // -----------------------------------------------------------------------------
545 void NavigatorTree::traverseSection(const uno::Reference
< report::XSection
>& _xSection
,SvLBoxEntry
* _pParent
,USHORT _nImageId
,ULONG _nPosition
)
547 SvLBoxEntry
* pSection
= insertEntry(_xSection
->getName(),_pParent
,_nImageId
,_nPosition
,new UserData(this,_xSection
));
548 const sal_Int32 nCount
= _xSection
->getCount();
549 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
551 uno::Reference
< report::XReportComponent
> xElement(_xSection
->getByIndex(i
),uno::UNO_QUERY_THROW
);
552 OSL_ENSURE(xElement
.is(),"Found report element which is NULL!");
553 insertEntry(lcl_getName(xElement
.get()),pSection
,lcl_getImageId(xElement
),LIST_APPEND
,new UserData(this,xElement
));
554 uno::Reference
< report::XReportDefinition
> xSubReport(xElement
,uno::UNO_QUERY
);
555 if ( xSubReport
.is() )
557 m_pMasterReport
= find(_xSection
->getReportDefinition());
558 reportdesign::OReportVisitor
aSubVisitor(this);
559 aSubVisitor
.start(xSubReport
);
563 // -----------------------------------------------------------------------------
564 void NavigatorTree::traverseFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
,SvLBoxEntry
* _pParent
)
566 SvLBoxEntry
* pFunctions
= insertEntry(String(ModuleRes(RID_STR_FUNCTIONS
)),_pParent
,SID_RPT_NEW_FUNCTION
,LIST_APPEND
,new UserData(this,_xFunctions
));
567 const sal_Int32 nCount
= _xFunctions
->getCount();
568 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
570 uno::Reference
< report::XFunction
> xElement(_xFunctions
->getByIndex(i
),uno::UNO_QUERY
);
571 insertEntry(xElement
->getName(),pFunctions
,SID_RPT_NEW_FUNCTION
,LIST_APPEND
,new UserData(this,xElement
));
574 // -----------------------------------------------------------------------------
575 SvLBoxEntry
* NavigatorTree::find(const uno::Reference
< uno::XInterface
>& _xContent
)
577 SvLBoxEntry
* pRet
= NULL
;
578 if ( _xContent
.is() )
580 SvLBoxEntry
* pCurrent
= First();
583 UserData
* pData
= static_cast<UserData
*>(pCurrent
->GetUserData());
584 OSL_ENSURE(pData
,"No UserData set an entry!");
585 if ( pData
->getContent() == _xContent
)
590 pCurrent
= Next(pCurrent
);
595 // -----------------------------------------------------------------------------
597 // -----------------------------------------------------------------------------
598 void NavigatorTree::traverseReport(const uno::Reference
< report::XReportDefinition
>& _xReport
)
600 insertEntry(_xReport
->getName(),m_pMasterReport
,SID_SELECT_REPORT
,LIST_APPEND
,new UserData(this,_xReport
));
602 // -----------------------------------------------------------------------------
603 void NavigatorTree::traverseReportFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
)
605 SvLBoxEntry
* pReport
= find(_xFunctions
->getParent());
606 traverseFunctions(_xFunctions
,pReport
);
608 // -----------------------------------------------------------------------------
609 void NavigatorTree::traverseReportHeader(const uno::Reference
< report::XSection
>& _xSection
)
611 SvLBoxEntry
* pReport
= find(_xSection
->getReportDefinition());
612 traverseSection(_xSection
,pReport
,SID_REPORTHEADERFOOTER
);
614 // -----------------------------------------------------------------------------
615 void NavigatorTree::traverseReportFooter(const uno::Reference
< report::XSection
>& _xSection
)
617 SvLBoxEntry
* pReport
= find(_xSection
->getReportDefinition());
618 traverseSection(_xSection
,pReport
,SID_REPORTHEADERFOOTER
);
620 // -----------------------------------------------------------------------------
621 void NavigatorTree::traversePageHeader(const uno::Reference
< report::XSection
>& _xSection
)
623 SvLBoxEntry
* pReport
= find(_xSection
->getReportDefinition());
624 traverseSection(_xSection
,pReport
,SID_PAGEHEADERFOOTER
);
626 // -----------------------------------------------------------------------------
627 void NavigatorTree::traversePageFooter(const uno::Reference
< report::XSection
>& _xSection
)
629 SvLBoxEntry
* pReport
= find(_xSection
->getReportDefinition());
630 traverseSection(_xSection
,pReport
,SID_PAGEHEADERFOOTER
);
632 // -----------------------------------------------------------------------------
633 void NavigatorTree::traverseGroups(const uno::Reference
< report::XGroups
>& _xGroups
)
635 SvLBoxEntry
* pReport
= find(_xGroups
->getReportDefinition());
636 insertEntry(String(ModuleRes(RID_STR_GROUPS
)),pReport
,SID_SORTINGANDGROUPING
,LIST_APPEND
,new UserData(this,_xGroups
));
638 // -----------------------------------------------------------------------------
639 void NavigatorTree::traverseGroup(const uno::Reference
< report::XGroup
>& _xGroup
)
641 uno::Reference
< report::XGroups
> xGroups(_xGroup
->getParent(),uno::UNO_QUERY
);
642 SvLBoxEntry
* pGroups
= find(xGroups
);
643 OSL_ENSURE(pGroups
,"No Groups inserted so far. Why!");
644 insertEntry(_xGroup
->getExpression(),pGroups
,SID_GROUP
,rptui::getPositionInIndexAccess(xGroups
.get(),_xGroup
),new UserData(this,_xGroup
));
646 // -----------------------------------------------------------------------------
647 void NavigatorTree::traverseGroupFunctions(const uno::Reference
< report::XFunctions
>& _xFunctions
)
649 SvLBoxEntry
* pGroup
= find(_xFunctions
->getParent());
650 traverseFunctions(_xFunctions
,pGroup
);
652 // -----------------------------------------------------------------------------
653 void NavigatorTree::traverseGroupHeader(const uno::Reference
< report::XSection
>& _xSection
)
655 SvLBoxEntry
* pGroup
= find(_xSection
->getGroup());
656 OSL_ENSURE(pGroup
,"No group found");
657 traverseSection(_xSection
,pGroup
,SID_GROUPHEADER
,1);
659 // -----------------------------------------------------------------------------
660 void NavigatorTree::traverseGroupFooter(const uno::Reference
< report::XSection
>& _xSection
)
662 SvLBoxEntry
* pGroup
= find(_xSection
->getGroup());
663 OSL_ENSURE(pGroup
,"No group found");
664 traverseSection(_xSection
,pGroup
,SID_GROUPFOOTER
);
666 // -----------------------------------------------------------------------------
667 void NavigatorTree::traverseDetail(const uno::Reference
< report::XSection
>& _xSection
)
669 uno::Reference
< report::XReportDefinition
> xReport
= _xSection
->getReportDefinition();
670 SvLBoxEntry
* pParent
= find(xReport
);
671 traverseSection(_xSection
,pParent
,SID_ICON_DETAIL
);
673 // -----------------------------------------------------------------------------
674 void NavigatorTree::_propertyChanged(const beans::PropertyChangeEvent
& _rEvent
) throw( uno::RuntimeException
)
676 uno::Reference
< report::XReportDefinition
> xReport(_rEvent
.Source
,uno::UNO_QUERY
);
679 sal_Bool bEnabled
= sal_False
;
680 _rEvent
.NewValue
>>= bEnabled
;
683 SvLBoxEntry
* pParent
= find(xReport
);
684 if ( _rEvent
.PropertyName
== PROPERTY_REPORTHEADERON
)
686 ULONG nPos
= xReport
->getReportHeaderOn() ? 2 : 1;
687 traverseSection(xReport
->getReportHeader(),pParent
,SID_REPORTHEADERFOOTER
,nPos
);
689 else if ( _rEvent
.PropertyName
== PROPERTY_PAGEHEADERON
)
691 traverseSection(xReport
->getPageHeader(),pParent
, SID_PAGEHEADERFOOTER
,1);
693 else if ( _rEvent
.PropertyName
== PROPERTY_PAGEFOOTERON
)
694 traverseSection(xReport
->getPageFooter(),pParent
, SID_PAGEHEADERFOOTER
);
695 else if ( _rEvent
.PropertyName
== PROPERTY_REPORTFOOTERON
)
697 ULONG nPos
= xReport
->getPageFooterOn() ? (GetLevelChildCount(pParent
) - 1) : LIST_APPEND
;
698 traverseSection(xReport
->getReportFooter(),pParent
,SID_REPORTHEADERFOOTER
,nPos
);
703 // -----------------------------------------------------------------------------
704 void NavigatorTree::_elementInserted( const container::ContainerEvent
& _rEvent
)
706 SvLBoxEntry
* pEntry
= find(_rEvent
.Source
);
707 uno::Reference
<beans::XPropertySet
> xProp(_rEvent
.Element
,uno::UNO_QUERY_THROW
);
708 ::rtl::OUString sName
;
709 uno::Reference
< beans::XPropertySetInfo
> xInfo
= xProp
->getPropertySetInfo();
712 if ( xInfo
->hasPropertyByName(PROPERTY_NAME
) )
713 xProp
->getPropertyValue(PROPERTY_NAME
) >>= sName
;
714 else if ( xInfo
->hasPropertyByName(PROPERTY_EXPRESSION
) )
715 xProp
->getPropertyValue(PROPERTY_EXPRESSION
) >>= sName
;
717 uno::Reference
< report::XGroup
> xGroup(xProp
,uno::UNO_QUERY
);
720 reportdesign::OReportVisitor
aSubVisitor(this);
721 aSubVisitor
.start(xGroup
);
725 uno::Reference
< report::XReportComponent
> xElement(xProp
,uno::UNO_QUERY
);
727 sName
= lcl_getName(xProp
);
728 insertEntry(sName
,pEntry
,(!xElement
.is() ? USHORT(SID_RPT_NEW_FUNCTION
) : lcl_getImageId(xElement
)),LIST_APPEND
,new UserData(this,xProp
));
730 if ( !IsExpanded(pEntry
) )
733 // -----------------------------------------------------------------------------
734 void NavigatorTree::_elementRemoved( const container::ContainerEvent
& _rEvent
)
736 uno::Reference
<beans::XPropertySet
> xProp(_rEvent
.Element
,uno::UNO_QUERY
);
737 SvLBoxEntry
* pEntry
= find(xProp
);
738 OSL_ENSURE(pEntry
,"NavigatorTree::_elementRemoved: No Entry found!");
742 SvLBoxEntry
* pParent
= GetParent(pEntry
);
747 // -----------------------------------------------------------------------------
748 void NavigatorTree::_elementReplaced( const container::ContainerEvent
& _rEvent
)
750 uno::Reference
<beans::XPropertySet
> xProp(_rEvent
.ReplacedElement
,uno::UNO_QUERY
);
751 SvLBoxEntry
* pEntry
= find(xProp
);
754 UserData
* pData
= static_cast<UserData
*>(pEntry
->GetUserData());
755 xProp
.set(_rEvent
.Element
,uno::UNO_QUERY
);
756 pData
->setContent(xProp
);
757 ::rtl::OUString sName
;
758 xProp
->getPropertyValue(PROPERTY_NAME
) >>= sName
;
759 SetEntryText(pEntry
,sName
);
762 // -----------------------------------------------------------------------------
763 void NavigatorTree::_disposing(const lang::EventObject
& _rSource
)throw( uno::RuntimeException
)
765 removeEntry(find(_rSource
.Source
));
767 // -----------------------------------------------------------------------------
768 void NavigatorTree::removeEntry(SvLBoxEntry
* _pEntry
,bool _bRemove
)
772 SvLBoxEntry
* pChild
= FirstChild(_pEntry
);
775 removeEntry(pChild
,false);
776 pChild
= NextSibling(pChild
);
778 delete static_cast<UserData
*>(_pEntry
->GetUserData());
780 GetModel()->Remove(_pEntry
);
783 DBG_NAME(rpt_NavigatorTree_UserData
)
784 // -----------------------------------------------------------------------------
785 NavigatorTree::UserData::UserData(NavigatorTree
* _pTree
,const uno::Reference
<uno::XInterface
>& _xContent
)
786 : OPropertyChangeListener(m_aMutex
)
787 , OContainerListener(m_aMutex
)
788 , m_xContent(_xContent
)
791 DBG_CTOR(rpt_NavigatorTree_UserData
,NULL
);
792 uno::Reference
<beans::XPropertySet
> xProp(m_xContent
,uno::UNO_QUERY
);
795 uno::Reference
< beans::XPropertySetInfo
> xInfo
= xProp
->getPropertySetInfo();
798 m_pListener
= new ::comphelper::OPropertyChangeMultiplexer(this,xProp
);
799 if ( xInfo
->hasPropertyByName(PROPERTY_NAME
) )
800 m_pListener
->addProperty(PROPERTY_NAME
);
801 else if ( xInfo
->hasPropertyByName(PROPERTY_EXPRESSION
) )
802 m_pListener
->addProperty(PROPERTY_EXPRESSION
);
803 if ( xInfo
->hasPropertyByName(PROPERTY_DATAFIELD
) )
804 m_pListener
->addProperty(PROPERTY_DATAFIELD
);
805 if ( xInfo
->hasPropertyByName(PROPERTY_LABEL
) )
806 m_pListener
->addProperty(PROPERTY_LABEL
);
807 if ( xInfo
->hasPropertyByName(PROPERTY_HEADERON
) )
808 m_pListener
->addProperty(PROPERTY_HEADERON
);
809 if ( xInfo
->hasPropertyByName(PROPERTY_FOOTERON
) )
810 m_pListener
->addProperty(PROPERTY_FOOTERON
);
813 uno::Reference
< container::XContainer
> xContainer(m_xContent
,uno::UNO_QUERY
);
814 if ( xContainer
.is() )
816 m_pContainerListener
= new ::comphelper::OContainerListenerAdapter(this,xContainer
);
819 // -----------------------------------------------------------------------------
820 NavigatorTree::UserData::~UserData()
822 DBG_DTOR(rpt_NavigatorTree_UserData
,NULL
);
823 if ( m_pContainerListener
.is() )
824 m_pContainerListener
->dispose();
825 if ( m_pListener
.is() )
826 m_pListener
->dispose();
828 // -----------------------------------------------------------------------------
829 // OPropertyChangeListener
830 void NavigatorTree::UserData::_propertyChanged(const beans::PropertyChangeEvent
& _rEvent
) throw( uno::RuntimeException
)
832 SvLBoxEntry
* pEntry
= m_pTree
->find(_rEvent
.Source
);
833 OSL_ENSURE(pEntry
,"No entry could be found! Why not!");
834 const bool bFooterOn
= (PROPERTY_FOOTERON
== _rEvent
.PropertyName
);
837 if ( bFooterOn
|| PROPERTY_HEADERON
== _rEvent
.PropertyName
)
840 uno::Reference
< report::XGroup
> xGroup(_rEvent
.Source
,uno::UNO_QUERY
);
841 ::std::mem_fun_t
< sal_Bool
,OGroupHelper
> pIsOn
= ::std::mem_fun(&OGroupHelper::getHeaderOn
);
842 ::std::mem_fun_t
< uno::Reference
<report::XSection
> ,OGroupHelper
> pMemFunSection
= ::std::mem_fun(&OGroupHelper::getHeader
);
845 pIsOn
= ::std::mem_fun(&OGroupHelper::getFooterOn
);
846 pMemFunSection
= ::std::mem_fun(&OGroupHelper::getFooter
);
847 nPos
= m_pTree
->GetChildCount(pEntry
) - 1;
850 OGroupHelper
aGroupHelper(xGroup
);
851 if ( pIsOn(&aGroupHelper
) )
855 m_pTree
->traverseSection(pMemFunSection(&aGroupHelper
),pEntry
,bFooterOn
? SID_GROUPFOOTER
: SID_GROUPHEADER
,nPos
);
858 // m_pTree->removeEntry(m_pTree->GetEntry(pEntry,nPos));
860 else if ( PROPERTY_EXPRESSION
== _rEvent
.PropertyName
)
862 ::rtl::OUString sNewName
;
863 _rEvent
.NewValue
>>= sNewName
;
864 m_pTree
->SetEntryText(pEntry
,sNewName
);
866 else if ( PROPERTY_DATAFIELD
== _rEvent
.PropertyName
|| PROPERTY_LABEL
== _rEvent
.PropertyName
|| PROPERTY_NAME
== _rEvent
.PropertyName
)
868 uno::Reference
<beans::XPropertySet
> xProp(_rEvent
.Source
,uno::UNO_QUERY
);
869 m_pTree
->SetEntryText(pEntry
,lcl_getName(xProp
));
872 catch(uno::Exception
)
875 // -----------------------------------------------------------------------------
876 void NavigatorTree::UserData::_elementInserted( const container::ContainerEvent
& _rEvent
) throw(uno::RuntimeException
)
878 m_pTree
->_elementInserted( _rEvent
);
880 // -----------------------------------------------------------------------------
881 void NavigatorTree::UserData::_elementRemoved( const container::ContainerEvent
& _rEvent
) throw(uno::RuntimeException
)
883 m_pTree
->_elementRemoved( _rEvent
);
885 // -----------------------------------------------------------------------------
886 void NavigatorTree::UserData::_elementReplaced( const container::ContainerEvent
& _rEvent
) throw(uno::RuntimeException
)
888 m_pTree
->_elementReplaced( _rEvent
);
890 // -----------------------------------------------------------------------------
891 void NavigatorTree::UserData::_disposing(const lang::EventObject
& _rSource
) throw( uno::RuntimeException
)
893 m_pTree
->_disposing( _rSource
);
895 // -----------------------------------------------------------------------------
896 // class ONavigatorImpl
897 // -----------------------------------------------------------------------------
900 ONavigatorImpl(const ONavigatorImpl
&);
901 void operator =(const ONavigatorImpl
&);
903 ONavigatorImpl(OReportController
& _rController
,ONavigator
* _pParent
);
904 virtual ~ONavigatorImpl();
906 uno::Reference
< report::XReportDefinition
> m_xReport
;
907 ::rptui::OReportController
& m_rController
;
908 ::std::auto_ptr
<NavigatorTree
> m_pNavigatorTree
;
911 ONavigatorImpl::ONavigatorImpl(OReportController
& _rController
,ONavigator
* _pParent
)
912 :m_xReport(_rController
.getReportDefinition())
913 ,m_rController(_rController
)
914 ,m_pNavigatorTree(new NavigatorTree(_pParent
,_rController
))
916 reportdesign::OReportVisitor
aVisitor(m_pNavigatorTree
.get());
917 aVisitor
.start(m_xReport
);
918 m_pNavigatorTree
->Expand(m_pNavigatorTree
->find(m_xReport
));
919 lang::EventObject
aEvent(m_rController
);
920 m_pNavigatorTree
->_selectionChanged(aEvent
);
922 //------------------------------------------------------------------------
923 ONavigatorImpl::~ONavigatorImpl()
926 // -----------------------------------------------------------------------------
927 DBG_NAME( rpt_ONavigator
)
928 const long STD_WIN_SIZE_X
= 210;
929 const long STD_WIN_SIZE_Y
= 280;
930 const long LISTBOX_BORDER
= 2;
931 //========================================================================
933 //========================================================================
934 ONavigator::ONavigator( Window
* _pParent
935 ,OReportController
& _rController
)
936 : FloatingWindow( _pParent
, ModuleRes(RID_NAVIGATOR
) )
938 DBG_CTOR( rpt_ONavigator
,NULL
);
940 m_pImpl
.reset(new ONavigatorImpl(_rController
,this));
942 //Size aSpace = LogicToPixel( Size( 7, 120), MAP_APPFONT );
943 //Size aOutSize(nMaxTextWidth + m_aHeader.GetSizePixel().Width() + 3*aSpace.Width(),aSpace.Height());
944 //SetMinOutputSizePixel(aOutSize);
945 //SetOutputSizePixel(aOutSize);
947 m_pImpl
->m_pNavigatorTree
->Show();
948 m_pImpl
->m_pNavigatorTree
->GrabFocus();
949 SetSizePixel(Size(STD_WIN_SIZE_X
,STD_WIN_SIZE_Y
));
953 // -----------------------------------------------------------------------------
955 //------------------------------------------------------------------------
956 ONavigator::~ONavigator()
958 DBG_DTOR( rpt_ONavigator
,NULL
);
960 //------------------------------------------------------------------------------
961 void ONavigator::Resize()
963 FloatingWindow::Resize();
965 Point
aPos(GetPosPixel());
966 Size
aSize( GetOutputSizePixel() );
968 //////////////////////////////////////////////////////////////////////
970 // Groesse der form::ListBox anpassen
971 Point
aLBPos( LISTBOX_BORDER
, LISTBOX_BORDER
);
972 Size
aLBSize( aSize
);
973 aLBSize
.Width() -= (2*LISTBOX_BORDER
);
974 aLBSize
.Height() -= (2*LISTBOX_BORDER
);
976 m_pImpl
->m_pNavigatorTree
->SetPosSizePixel( aLBPos
, aLBSize
);
978 // -----------------------------------------------------------------------------
979 // -----------------------------------------------------------------------------
980 void ONavigator::GetFocus()
983 if ( m_pImpl
->m_pNavigatorTree
.get() )
984 m_pImpl
->m_pNavigatorTree
->GrabFocus();
986 // =============================================================================
988 // =============================================================================