Update ooo320-m1
[ooovba.git] / reportdesign / source / ui / dlg / Navigator.cxx
blob586933d50814ea8c53083c7354c036775563d8db
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: Navigator.cxx,v $
10 * $Revision: 1.7 $
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"
37 #include "Undo.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>
64 #include <memory>
65 #include <algorithm>
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
73 namespace rptui
75 using namespace ::com::sun::star;
76 using namespace svt;
77 using namespace ::comphelper;
79 USHORT lcl_getImageId(const uno::Reference< report::XReportComponent>& _xElement)
81 USHORT nId = 0;
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() )
88 nId = SID_FM_EDIT;
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;
93 return nId;
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
128 class UserData;
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;
138 public:
139 UserData(NavigatorTree* _pTree,const uno::Reference<uno::XInterface>& _xContent);
140 ~UserData();
142 inline uno::Reference< uno::XInterface > getContent() const { return m_xContent; }
143 inline void setContent(const uno::Reference< uno::XInterface >& _xContent) { m_xContent = _xContent; }
144 protected:
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&);
175 protected:
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 );
194 public:
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);
203 // ITraverseReport
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);
221 private:
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 ) );
251 SetNodeBitmaps(
252 m_aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
253 m_aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
254 BMP_COLOR_NORMAL
256 SetNodeBitmaps(
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);
265 Clear();
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();
275 while ( pCurrent )
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;
294 ::Point aWhere;
295 if (rEvt.IsMouseEvent())
297 aWhere = rEvt.GetMousePosPixel();
298 ptClickedOn = GetEntry(aWhere);
299 if (ptClickedOn == NULL)
300 break;
301 if ( !IsSelected(ptClickedOn) )
303 SelectAll(sal_False);
304 Select(ptClickedOn, sal_True);
305 SetCurEntry(ptClickedOn);
308 else
310 ptClickedOn = GetCurEntry();
311 if ( !ptClickedOn )
312 break;
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);
337 else
338 aContextMenu.EnableItem(nId,bEnabled);
340 } // for (USHORT i = 0; i < nCount; ++i)
341 USHORT nId = aContextMenu.Execute(this, aWhere);
342 if ( nId )
344 uno::Sequence< beans::PropertyValue> aArgs;
345 if ( nId == SID_RPT_NEW_FUNCTION )
347 aArgs.realloc(1);
348 aArgs[0].Value <<= (xFunctions.is() ? xFunctions : xSupplier->getFunctions());
350 else if ( nId == SID_DELETE )
352 if ( xGroup.is() )
353 nId = SID_GROUP_REMOVE;
354 aArgs.realloc(1);
355 aArgs[0].Name = PROPERTY_GROUP;
356 aArgs[0].Value <<= pData->getContent();
358 m_rController.executeUnChecked(nId,aArgs);
361 bHandled = sal_True;
362 } break;
365 if (!bHandled)
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;
373 if (_rEvt.mbLeaving)
375 if (m_aDropActionTimer.IsActive())
376 m_aDropActionTimer.Stop();
378 else
380 bool bNeedTrigger = false;
381 // auf dem ersten Eintrag ?
382 if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight()))
384 m_aDropActionType = DA_SCROLLUP;
385 bNeedTrigger = true;
387 else if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight()))
389 m_aDropActionType = DA_SCROLLDOWN;
390 bNeedTrigger = true;
392 else
394 SvLBoxEntry* pDropppedOn = GetEntry(aDropPos);
395 if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
397 m_aDropActionType = DA_EXPANDNODE;
398 bNeedTrigger = true;
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;
408 // und den Timer los
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();
419 return nDropOption;
421 // -------------------------------------------------------------------------
422 sal_Int8 NavigatorTree::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
424 // _rEvt.mnAction;
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 )
433 EndSelection();
436 //------------------------------------------------------------------------
437 IMPL_LINK( NavigatorTree, OnDropActionTimer, void*, EMPTYARG )
439 if (--m_nTimerCounter > 0)
440 return 0L;
442 switch ( m_aDropActionType )
444 case DA_EXPANDNODE:
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
451 Expand(pToExpand);
453 // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
454 m_aDropActionTimer.Stop();
456 break;
458 case DA_SCROLLUP :
459 ScrollOutputArea( 1 );
460 m_nTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
461 break;
463 case DA_SCROLLDOWN :
464 ScrollOutputArea( -1 );
465 m_nTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
466 break;
470 return 0L;
473 // -----------------------------------------------------------------------------
474 IMPL_LINK(NavigatorTree, OnEntrySelDesel, NavigatorTree*, /*pThis*/)
476 if ( !m_pSelectionListener->locked() )
478 m_pSelectionListener->lock();
479 SvLBoxEntry* pEntry = GetCurEntry();
480 uno::Any aSelection;
481 if ( IsSelected(pEntry) )
482 aSelection <<= static_cast<UserData*>(pEntry->GetUserData())->getContent();
483 m_rController.select(aSelection);
484 m_pSelectionListener->unlock();
487 return 0L;
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;
496 aSec >>= 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);
504 SetCurEntry(pEntry);
506 else if ( !pEntry )
507 SelectAll(FALSE,FALSE);
509 else
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);
519 SetCurEntry(pEntry);
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;
529 if ( _nImageId )
531 const Image aImage( m_aNavigatorImages.GetImage( _nImageId ) );
532 pEntry = InsertEntry(_sName,aImage,aImage,_pParent,FALSE,_nPosition,_pData);
533 if ( pEntry )
535 const Image aImageHC( m_aNavigatorImagesHC.GetImage( _nImageId ) );
536 SetExpandedEntryBmp( pEntry, aImageHC, BMP_COLOR_HIGHCONTRAST );
537 SetCollapsedEntryBmp( pEntry, aImageHC, BMP_COLOR_HIGHCONTRAST );
540 else
541 pEntry = InsertEntry(_sName,_pParent,FALSE,_nPosition,_pData);
542 return pEntry;
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();
581 while ( pCurrent )
583 UserData* pData = static_cast<UserData*>(pCurrent->GetUserData());
584 OSL_ENSURE(pData,"No UserData set an entry!");
585 if ( pData->getContent() == _xContent )
587 pRet = pCurrent;
588 break;
590 pCurrent = Next(pCurrent);
593 return pRet;
595 // -----------------------------------------------------------------------------
596 // ITraverseReport
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);
677 if ( xReport.is() )
679 sal_Bool bEnabled = sal_False;
680 _rEvent.NewValue >>= bEnabled;
681 if ( 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();
710 if ( xInfo.is() )
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);
718 if ( xGroup.is() )
720 reportdesign::OReportVisitor aSubVisitor(this);
721 aSubVisitor.start(xGroup);
723 else
725 uno::Reference< report::XReportComponent> xElement(xProp,uno::UNO_QUERY);
726 if ( xProp.is() )
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) )
731 Expand(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!");
740 if ( pEntry )
742 SvLBoxEntry* pParent = GetParent(pEntry);
743 removeEntry(pEntry);
744 PaintEntry(pParent);
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);
752 if ( pEntry )
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)
770 if ( _pEntry )
772 SvLBoxEntry* pChild = FirstChild(_pEntry);
773 while( pChild )
775 removeEntry(pChild,false);
776 pChild = NextSibling(pChild);
778 delete static_cast<UserData*>(_pEntry->GetUserData());
779 if ( _bRemove )
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)
789 , m_pTree(_pTree)
791 DBG_CTOR(rpt_NavigatorTree_UserData,NULL);
792 uno::Reference<beans::XPropertySet> xProp(m_xContent,uno::UNO_QUERY);
793 if ( xProp.is() )
795 uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
796 if ( xInfo.is() )
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 )
839 sal_Int32 nPos = 1;
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);
843 if ( bFooterOn )
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) )
853 if ( bFooterOn )
854 ++nPos;
855 m_pTree->traverseSection(pMemFunSection(&aGroupHelper),pEntry,bFooterOn ? SID_GROUPFOOTER : SID_GROUPHEADER,nPos);
857 //else
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 // -----------------------------------------------------------------------------
898 class ONavigatorImpl
900 ONavigatorImpl(const ONavigatorImpl&);
901 void operator =(const ONavigatorImpl&);
902 public:
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 //========================================================================
932 // class ONavigator
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);
946 FreeResource();
947 m_pImpl->m_pNavigatorTree->Show();
948 m_pImpl->m_pNavigatorTree->GrabFocus();
949 SetSizePixel(Size(STD_WIN_SIZE_X,STD_WIN_SIZE_Y));
950 Show();
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()
982 Window::GetFocus();
983 if ( m_pImpl->m_pNavigatorTree.get() )
984 m_pImpl->m_pNavigatorTree->GrabFocus();
986 // =============================================================================
987 } // rptui
988 // =============================================================================