update emoji autocorrect entries from po-files
[LibreOffice.git] / reportdesign / source / ui / dlg / Navigator.cxx
blobf65a642278e08856149b8fe65b8b450f0edabf98
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 "uistrings.hrc"
23 #include "ReportController.hxx"
24 #include "UITools.hxx"
25 #include "RptUndo.hxx"
26 #include "reportformula.hxx"
27 #include <boost/noncopyable.hpp>
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>
35 #include "helpids.hrc"
36 #include "RptResId.hrc"
37 #include "rptui_slotid.hrc"
38 #include <tools/debug.hxx>
39 #include <comphelper/propmultiplex.hxx>
40 #include <comphelper/containermultiplexer.hxx>
41 #include <comphelper/types.hxx>
42 #include <cppuhelper/basemutex.hxx>
43 #include <comphelper/SelectionMultiplex.hxx>
44 #include <svtools/treelistbox.hxx>
45 #include <svtools/treelistentry.hxx>
46 #include <svl/solar.hrc>
47 #include "ReportVisitor.hxx"
48 #include "ModuleHelper.hxx"
49 #include <rtl/ref.hxx>
51 #include <memory>
52 #include <algorithm>
54 #define RID_SVXIMG_COLLAPSEDNODE (RID_FORMS_START + 2)
55 #define RID_SVXIMG_EXPANDEDNODE (RID_FORMS_START + 3)
56 #define DROP_ACTION_TIMER_INITIAL_TICKS 10
57 #define DROP_ACTION_TIMER_SCROLL_TICKS 3
58 #define DROP_ACTION_TIMER_TICK_BASE 10
60 namespace rptui
62 using namespace ::com::sun::star;
63 using namespace utl;
64 using namespace ::comphelper;
66 sal_uInt16 lcl_getImageId(const uno::Reference< report::XReportComponent>& _xElement)
68 sal_uInt16 nId = 0;
69 uno::Reference< report::XFixedLine> xFixedLine(_xElement,uno::UNO_QUERY);
70 if ( uno::Reference< report::XFixedText>(_xElement,uno::UNO_QUERY).is() )
71 nId = SID_FM_FIXEDTEXT;
72 else if ( xFixedLine.is() )
73 nId = xFixedLine->getOrientation() ? SID_INSERT_VFIXEDLINE : SID_INSERT_HFIXEDLINE;
74 else if ( uno::Reference< report::XFormattedField>(_xElement,uno::UNO_QUERY).is() )
75 nId = SID_FM_EDIT;
76 else if ( uno::Reference< report::XImageControl>(_xElement,uno::UNO_QUERY).is() )
77 nId = SID_FM_IMAGECONTROL;
78 else if ( uno::Reference< report::XShape>(_xElement,uno::UNO_QUERY).is() )
79 nId = SID_DRAWTBX_CS_BASIC;
80 return nId;
83 OUString lcl_getName(const uno::Reference< beans::XPropertySet>& _xElement)
85 OSL_ENSURE(_xElement.is(),"Found report element which is NULL!");
86 OUString sTempName;
87 _xElement->getPropertyValue(PROPERTY_NAME) >>= sTempName;
88 OUStringBuffer sName = sTempName;
89 uno::Reference< report::XFixedText> xFixedText(_xElement,uno::UNO_QUERY);
90 uno::Reference< report::XReportControlModel> xReportModel(_xElement,uno::UNO_QUERY);
91 if ( xFixedText.is() )
93 sName.append(" : ");
94 sName.append(xFixedText->getLabel());
96 else if ( xReportModel.is() && _xElement->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) )
98 ReportFormula aFormula( xReportModel->getDataField() );
99 if ( aFormula.isValid() )
101 sName.append(" : ");
102 sName.append( aFormula.getUndecoratedContent() );
105 return sName.makeStringAndClear();
109 class NavigatorTree : public ::cppu::BaseMutex
110 , public SvTreeListBox
111 , public reportdesign::ITraverseReport
112 , public comphelper::OSelectionChangeListener
113 , public ::comphelper::OPropertyChangeListener
115 class UserData;
116 friend class UserData;
117 class UserData : public ::cppu::BaseMutex
118 ,public ::comphelper::OPropertyChangeListener
119 ,public ::comphelper::OContainerListener
121 uno::Reference< uno::XInterface > m_xContent;
122 ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pListener;
123 ::rtl::Reference< comphelper::OContainerListenerAdapter> m_pContainerListener;
124 VclPtr<NavigatorTree> m_pTree;
125 public:
126 UserData(NavigatorTree* _pTree,const uno::Reference<uno::XInterface>& _xContent);
127 virtual ~UserData();
129 inline uno::Reference< uno::XInterface > getContent() const { return m_xContent; }
130 inline void setContent(const uno::Reference< uno::XInterface >& _xContent) { m_xContent = _xContent; }
132 protected:
133 // OPropertyChangeListener
134 virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException) SAL_OVERRIDE;
136 // OContainerListener
137 virtual void _elementInserted( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
138 virtual void _elementRemoved( const container::ContainerEvent& _Event )
139 throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
140 virtual void _elementReplaced( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException, std::exception) SAL_OVERRIDE;
141 virtual void _disposing(const lang::EventObject& _rSource)
142 throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
145 enum DROP_ACTION { DA_SCROLLUP, DA_SCROLLDOWN, DA_EXPANDNODE };
146 AutoTimer m_aDropActionTimer;
147 Timer m_aSynchronizeTimer;
148 ImageList m_aNavigatorImages;
149 Point m_aTimerTriggered; // die Position, an der der DropTimer angeschaltet wurde
150 DROP_ACTION m_aDropActionType;
151 OReportController& m_rController;
152 SvTreeListEntry* m_pMasterReport;
153 SvTreeListEntry* m_pDragedEntry;
154 ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener;
155 ::rtl::Reference< comphelper::OSelectionChangeMultiplexer> m_pSelectionListener;
156 unsigned short m_nTimerCounter;
158 SvTreeListEntry* insertEntry(const OUString& _sName,SvTreeListEntry* _pParent,sal_uInt16 _nImageId,sal_uLong _nPosition,UserData* _pData);
159 void traverseSection(const uno::Reference< report::XSection>& _xSection,SvTreeListEntry* _pParent,sal_uInt16 _nImageId,sal_uLong _nPosition = TREELIST_APPEND);
160 void traverseFunctions(const uno::Reference< report::XFunctions>& _xFunctions,SvTreeListEntry* _pParent);
162 protected:
163 virtual void Command( const CommandEvent& rEvt ) SAL_OVERRIDE;
164 // DragSourceHelper overridables
165 virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ) SAL_OVERRIDE;
166 // DropTargetHelper overridables
167 virtual sal_Int8 AcceptDrop( const AcceptDropEvent& _rEvt ) SAL_OVERRIDE;
168 virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& _rEvt ) SAL_OVERRIDE;
170 // OSelectionChangeListener
171 virtual void _disposing(const lang::EventObject& _rSource)
172 throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
174 // OPropertyChangeListener
175 virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException) SAL_OVERRIDE;
177 // OContainerListener Helper
178 void _elementInserted( const container::ContainerEvent& _rEvent );
179 void _elementRemoved( const container::ContainerEvent& _Event );
180 void _elementReplaced( const container::ContainerEvent& _rEvent );
182 public:
183 NavigatorTree(vcl::Window* pParent,OReportController& _rController );
184 virtual ~NavigatorTree();
185 virtual void dispose() SAL_OVERRIDE;
187 DECL_LINK(OnEntrySelDesel, NavigatorTree*);
188 DECL_LINK_TYPED( OnDropActionTimer, Timer*, void );
190 virtual void _selectionChanged( const lang::EventObject& aEvent ) throw (uno::RuntimeException) SAL_OVERRIDE;
192 // ITraverseReport
193 virtual void traverseReport(const uno::Reference< report::XReportDefinition>& _xReport) SAL_OVERRIDE;
194 virtual void traverseReportFunctions(const uno::Reference< report::XFunctions>& _xFunctions) SAL_OVERRIDE;
195 virtual void traverseReportHeader(const uno::Reference< report::XSection>& _xSection) SAL_OVERRIDE;
196 virtual void traverseReportFooter(const uno::Reference< report::XSection>& _xSection) SAL_OVERRIDE;
197 virtual void traversePageHeader(const uno::Reference< report::XSection>& _xSection) SAL_OVERRIDE;
198 virtual void traversePageFooter(const uno::Reference< report::XSection>& _xSection) SAL_OVERRIDE;
200 virtual void traverseGroups(const uno::Reference< report::XGroups>& _xGroups) SAL_OVERRIDE;
201 virtual void traverseGroup(const uno::Reference< report::XGroup>& _xGroup) SAL_OVERRIDE;
202 virtual void traverseGroupFunctions(const uno::Reference< report::XFunctions>& _xFunctions) SAL_OVERRIDE;
203 virtual void traverseGroupHeader(const uno::Reference< report::XSection>& _xSection) SAL_OVERRIDE;
204 virtual void traverseGroupFooter(const uno::Reference< report::XSection>& _xSection) SAL_OVERRIDE;
206 virtual void traverseDetail(const uno::Reference< report::XSection>& _xSection) SAL_OVERRIDE;
208 SvTreeListEntry* find(const uno::Reference< uno::XInterface >& _xContent);
209 void removeEntry(SvTreeListEntry* _pEntry,bool _bRemove = true);
211 virtual Size GetOptimalSize() const SAL_OVERRIDE;
212 private:
213 using SvTreeListBox::ExecuteDrop;
216 NavigatorTree::NavigatorTree( vcl::Window* pParent,OReportController& _rController )
217 :SvTreeListBox( pParent, WB_TABSTOP| WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HSCROLL|WB_HASBUTTONSATROOT )
218 ,comphelper::OSelectionChangeListener(m_aMutex)
219 ,OPropertyChangeListener(m_aMutex)
220 ,m_aTimerTriggered(-1,-1)
221 ,m_aDropActionType( DA_SCROLLUP )
222 ,m_rController(_rController)
223 ,m_pMasterReport(NULL)
224 ,m_pDragedEntry(NULL)
225 ,m_nTimerCounter( DROP_ACTION_TIMER_INITIAL_TICKS )
227 set_hexpand(true);
228 set_vexpand(true);
230 m_pReportListener = new OPropertyChangeMultiplexer(this,m_rController.getReportDefinition().get());
231 m_pReportListener->addProperty(PROPERTY_PAGEHEADERON);
232 m_pReportListener->addProperty(PROPERTY_PAGEFOOTERON);
233 m_pReportListener->addProperty(PROPERTY_REPORTHEADERON);
234 m_pReportListener->addProperty(PROPERTY_REPORTFOOTERON);
236 m_pSelectionListener = new OSelectionChangeMultiplexer(this,&m_rController);
238 SetHelpId( HID_REPORT_NAVIGATOR_TREE );
240 m_aNavigatorImages = ImageList( ModuleRes( RID_SVXIMGLIST_RPTEXPL ) );
242 SetNodeBitmaps(
243 m_aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
244 m_aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE )
247 SetDragDropMode(DragDropMode::ALL);
248 EnableInplaceEditing( false );
249 SetSelectionMode(MULTIPLE_SELECTION);
250 Clear();
252 m_aDropActionTimer.SetTimeoutHdl(LINK(this, NavigatorTree, OnDropActionTimer));
253 SetSelectHdl(LINK(this, NavigatorTree, OnEntrySelDesel));
254 SetDeselectHdl(LINK(this, NavigatorTree, OnEntrySelDesel));
257 NavigatorTree::~NavigatorTree()
259 disposeOnce();
262 void NavigatorTree::dispose()
264 SvTreeListEntry* pCurrent = First();
265 while ( pCurrent )
267 delete static_cast<UserData*>(pCurrent->GetUserData());
268 pCurrent = Next(pCurrent);
270 m_pReportListener->dispose();
271 m_pSelectionListener->dispose();
272 SvTreeListBox::dispose();
275 void NavigatorTree::Command( const CommandEvent& rEvt )
277 bool bHandled = false;
278 switch( rEvt.GetCommand())
280 case CommandEventId::ContextMenu:
282 // die Stelle, an der geklickt wurde
283 SvTreeListEntry* ptClickedOn = NULL;
284 ::Point aWhere;
285 if (rEvt.IsMouseEvent())
287 aWhere = rEvt.GetMousePosPixel();
288 ptClickedOn = GetEntry(aWhere);
289 if (ptClickedOn == NULL)
290 break;
291 if ( !IsSelected(ptClickedOn) )
293 SelectAll(false);
294 Select(ptClickedOn, true);
295 SetCurEntry(ptClickedOn);
298 else
300 ptClickedOn = GetCurEntry();
301 if ( !ptClickedOn )
302 break;
303 aWhere = GetEntryPosition(ptClickedOn);
305 UserData* pData = static_cast<UserData*>(ptClickedOn->GetUserData());
306 uno::Reference< report::XFunctionsSupplier> xSupplier(pData->getContent(),uno::UNO_QUERY);
307 uno::Reference< report::XFunctions> xFunctions(pData->getContent(),uno::UNO_QUERY);
308 uno::Reference< report::XGroup> xGroup(pData->getContent(),uno::UNO_QUERY);
309 bool bDeleteAllowed = m_rController.isEditable() && (xGroup.is() ||
310 uno::Reference< report::XFunction>(pData->getContent(),uno::UNO_QUERY).is());
311 PopupMenu aContextMenu( ModuleRes( RID_MENU_NAVIGATOR ) );
313 sal_uInt16 nCount = aContextMenu.GetItemCount();
314 for (sal_uInt16 i = 0; i < nCount; ++i)
316 if ( MenuItemType::SEPARATOR != aContextMenu.GetItemType(i))
318 sal_uInt16 nId = aContextMenu.GetItemId(i);
320 aContextMenu.CheckItem(nId,m_rController.isCommandChecked(nId));
321 bool bEnabled = m_rController.isCommandEnabled(nId);
322 if ( nId == SID_RPT_NEW_FUNCTION )
323 aContextMenu.EnableItem(nId,m_rController.isEditable() && (xSupplier.is() || xFunctions.is()) );
324 // special condition, check for function and group
325 else if ( nId == SID_DELETE )
326 aContextMenu.EnableItem(SID_DELETE,bDeleteAllowed);
327 else
328 aContextMenu.EnableItem(nId,bEnabled);
331 sal_uInt16 nId = aContextMenu.Execute(this, aWhere);
332 if ( nId )
334 uno::Sequence< beans::PropertyValue> aArgs;
335 if ( nId == SID_RPT_NEW_FUNCTION )
337 aArgs.realloc(1);
338 aArgs[0].Value <<= (xFunctions.is() ? xFunctions : xSupplier->getFunctions());
340 else if ( nId == SID_DELETE )
342 if ( xGroup.is() )
343 nId = SID_GROUP_REMOVE;
344 aArgs.realloc(1);
345 aArgs[0].Name = PROPERTY_GROUP;
346 aArgs[0].Value <<= pData->getContent();
348 m_rController.executeUnChecked(nId,aArgs);
351 bHandled = true;
353 break;
354 default: break;
357 if (!bHandled)
358 SvTreeListBox::Command( rEvt );
361 sal_Int8 NavigatorTree::AcceptDrop( const AcceptDropEvent& _rEvt )
363 sal_Int8 nDropOption = DND_ACTION_NONE;
364 ::Point aDropPos = _rEvt.maPosPixel;
365 if (_rEvt.mbLeaving)
367 if (m_aDropActionTimer.IsActive())
368 m_aDropActionTimer.Stop();
370 else
372 bool bNeedTrigger = false;
373 // auf dem ersten Eintrag ?
374 if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight()))
376 m_aDropActionType = DA_SCROLLUP;
377 bNeedTrigger = true;
379 else if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight()))
381 m_aDropActionType = DA_SCROLLDOWN;
382 bNeedTrigger = true;
384 else
386 SvTreeListEntry* pDropppedOn = GetEntry(aDropPos);
387 if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
389 m_aDropActionType = DA_EXPANDNODE;
390 bNeedTrigger = true;
394 if (bNeedTrigger && (m_aTimerTriggered != aDropPos))
396 // neu anfangen zu zaehlen
397 m_nTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS;
398 // die Pos merken, da ich auch AcceptDrops bekomme, wenn sich die Maus gar nicht bewegt hat
399 m_aTimerTriggered = aDropPos;
400 // und den Timer los
401 if (!m_aDropActionTimer.IsActive()) // gibt es den Timer schon ?
403 m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE);
404 m_aDropActionTimer.Start();
407 else if (!bNeedTrigger)
408 m_aDropActionTimer.Stop();
411 return nDropOption;
414 sal_Int8 NavigatorTree::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
416 return DND_ACTION_NONE;
419 void NavigatorTree::StartDrag( sal_Int8 /*_nAction*/, const Point& _rPosPixel )
421 m_pDragedEntry = GetEntry(_rPosPixel);
422 if ( m_pDragedEntry )
424 EndSelection();
428 IMPL_LINK_NOARG_TYPED(NavigatorTree, OnDropActionTimer, Timer *, void)
430 if (--m_nTimerCounter > 0)
431 return;
433 switch ( m_aDropActionType )
435 case DA_EXPANDNODE:
437 SvTreeListEntry* pToExpand = GetEntry(m_aTimerTriggered);
438 if (pToExpand && (GetChildCount(pToExpand) > 0) && !IsExpanded(pToExpand))
439 Expand(pToExpand);
440 m_aDropActionTimer.Stop();
442 break;
444 case DA_SCROLLUP :
445 ScrollOutputArea( 1 );
446 m_nTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
447 break;
449 case DA_SCROLLDOWN :
450 ScrollOutputArea( -1 );
451 m_nTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
452 break;
458 IMPL_LINK(NavigatorTree, OnEntrySelDesel, NavigatorTree*, /*pThis*/)
460 if ( !m_pSelectionListener->locked() )
462 m_pSelectionListener->lock();
463 SvTreeListEntry* pEntry = GetCurEntry();
464 uno::Any aSelection;
465 if ( IsSelected(pEntry) )
466 aSelection <<= static_cast<UserData*>(pEntry->GetUserData())->getContent();
467 m_rController.select(aSelection);
468 m_pSelectionListener->unlock();
471 return 0L;
474 void NavigatorTree::_selectionChanged( const lang::EventObject& aEvent ) throw (uno::RuntimeException)
476 m_pSelectionListener->lock();
477 uno::Reference< view::XSelectionSupplier> xSelectionSupplier(aEvent.Source,uno::UNO_QUERY);
478 uno::Any aSec = xSelectionSupplier->getSelection();
479 uno::Sequence< uno::Reference< report::XReportComponent > > aSelection;
480 aSec >>= aSelection;
481 if ( !aSelection.getLength() )
483 uno::Reference< uno::XInterface> xSelection(aSec,uno::UNO_QUERY);
484 SvTreeListEntry* pEntry = find(xSelection);
485 if ( pEntry && !IsSelected(pEntry) )
487 Select(pEntry, true);
488 SetCurEntry(pEntry);
490 else if ( !pEntry )
491 SelectAll(false,false);
493 else
495 const uno::Reference< report::XReportComponent >* pIter = aSelection.getConstArray();
496 const uno::Reference< report::XReportComponent >* pEnd = pIter + aSelection.getLength();
497 for (; pIter != pEnd; ++pIter)
499 SvTreeListEntry* pEntry = find(*pIter);
500 if ( pEntry && !IsSelected(pEntry) )
502 Select(pEntry, true);
503 SetCurEntry(pEntry);
507 m_pSelectionListener->unlock();
510 SvTreeListEntry* NavigatorTree::insertEntry(const OUString& _sName,SvTreeListEntry* _pParent,sal_uInt16 _nImageId,sal_uLong _nPosition,UserData* _pData)
512 SvTreeListEntry* pEntry = NULL;
513 if ( _nImageId )
515 const Image aImage( m_aNavigatorImages.GetImage( _nImageId ) );
516 pEntry = InsertEntry(_sName,aImage,aImage,_pParent,false,_nPosition,_pData);
518 else
519 pEntry = InsertEntry(_sName,_pParent,false,_nPosition,_pData);
520 return pEntry;
523 void NavigatorTree::traverseSection(const uno::Reference< report::XSection>& _xSection,SvTreeListEntry* _pParent,sal_uInt16 _nImageId,sal_uLong _nPosition)
525 SvTreeListEntry* pSection = insertEntry(_xSection->getName(),_pParent,_nImageId,_nPosition,new UserData(this,_xSection));
526 const sal_Int32 nCount = _xSection->getCount();
527 for (sal_Int32 i = 0; i < nCount; ++i)
529 uno::Reference< report::XReportComponent> xElement(_xSection->getByIndex(i),uno::UNO_QUERY_THROW);
530 OSL_ENSURE(xElement.is(),"Found report element which is NULL!");
531 insertEntry(lcl_getName(xElement.get()),pSection,lcl_getImageId(xElement),TREELIST_APPEND,new UserData(this,xElement));
532 uno::Reference< report::XReportDefinition> xSubReport(xElement,uno::UNO_QUERY);
533 if ( xSubReport.is() )
535 m_pMasterReport = find(_xSection->getReportDefinition());
536 reportdesign::OReportVisitor aSubVisitor(this);
537 aSubVisitor.start(xSubReport);
542 void NavigatorTree::traverseFunctions(const uno::Reference< report::XFunctions>& _xFunctions,SvTreeListEntry* _pParent)
544 SvTreeListEntry* pFunctions = insertEntry(OUString(ModuleRes(RID_STR_FUNCTIONS)), _pParent, SID_RPT_NEW_FUNCTION, TREELIST_APPEND, new UserData(this,_xFunctions));
545 const sal_Int32 nCount = _xFunctions->getCount();
546 for (sal_Int32 i = 0; i< nCount; ++i)
548 uno::Reference< report::XFunction> xElement(_xFunctions->getByIndex(i),uno::UNO_QUERY);
549 insertEntry(xElement->getName(),pFunctions,SID_RPT_NEW_FUNCTION,TREELIST_APPEND,new UserData(this,xElement));
553 SvTreeListEntry* NavigatorTree::find(const uno::Reference< uno::XInterface >& _xContent)
555 SvTreeListEntry* pRet = NULL;
556 if ( _xContent.is() )
558 SvTreeListEntry* pCurrent = First();
559 while ( pCurrent )
561 UserData* pData = static_cast<UserData*>(pCurrent->GetUserData());
562 OSL_ENSURE(pData,"No UserData set an entry!");
563 if ( pData->getContent() == _xContent )
565 pRet = pCurrent;
566 break;
568 pCurrent = Next(pCurrent);
571 return pRet;
574 // ITraverseReport
576 void NavigatorTree::traverseReport(const uno::Reference< report::XReportDefinition>& _xReport)
578 insertEntry(_xReport->getName(),m_pMasterReport,SID_SELECT_REPORT,TREELIST_APPEND,new UserData(this,_xReport));
581 void NavigatorTree::traverseReportFunctions(const uno::Reference< report::XFunctions>& _xFunctions)
583 SvTreeListEntry* pReport = find(_xFunctions->getParent());
584 traverseFunctions(_xFunctions,pReport);
587 void NavigatorTree::traverseReportHeader(const uno::Reference< report::XSection>& _xSection)
589 SvTreeListEntry* pReport = find(_xSection->getReportDefinition());
590 traverseSection(_xSection,pReport,SID_REPORTHEADERFOOTER);
593 void NavigatorTree::traverseReportFooter(const uno::Reference< report::XSection>& _xSection)
595 SvTreeListEntry* pReport = find(_xSection->getReportDefinition());
596 traverseSection(_xSection,pReport,SID_REPORTHEADERFOOTER);
599 void NavigatorTree::traversePageHeader(const uno::Reference< report::XSection>& _xSection)
601 SvTreeListEntry* pReport = find(_xSection->getReportDefinition());
602 traverseSection(_xSection,pReport,SID_PAGEHEADERFOOTER);
605 void NavigatorTree::traversePageFooter(const uno::Reference< report::XSection>& _xSection)
607 SvTreeListEntry* pReport = find(_xSection->getReportDefinition());
608 traverseSection(_xSection,pReport,SID_PAGEHEADERFOOTER);
611 void NavigatorTree::traverseGroups(const uno::Reference< report::XGroups>& _xGroups)
613 SvTreeListEntry* pReport = find(_xGroups->getReportDefinition());
614 insertEntry(OUString(ModuleRes(RID_STR_GROUPS)), pReport, SID_SORTINGANDGROUPING, TREELIST_APPEND, new UserData(this,_xGroups));
617 void NavigatorTree::traverseGroup(const uno::Reference< report::XGroup>& _xGroup)
619 uno::Reference< report::XGroups> xGroups(_xGroup->getParent(),uno::UNO_QUERY);
620 SvTreeListEntry* pGroups = find(xGroups);
621 OSL_ENSURE(pGroups,"No Groups inserted so far. Why!");
622 insertEntry(_xGroup->getExpression(),pGroups,SID_GROUP,rptui::getPositionInIndexAccess(xGroups.get(),_xGroup),new UserData(this,_xGroup));
625 void NavigatorTree::traverseGroupFunctions(const uno::Reference< report::XFunctions>& _xFunctions)
627 SvTreeListEntry* pGroup = find(_xFunctions->getParent());
628 traverseFunctions(_xFunctions,pGroup);
631 void NavigatorTree::traverseGroupHeader(const uno::Reference< report::XSection>& _xSection)
633 SvTreeListEntry* pGroup = find(_xSection->getGroup());
634 OSL_ENSURE(pGroup,"No group found");
635 traverseSection(_xSection,pGroup,SID_GROUPHEADER,1);
638 void NavigatorTree::traverseGroupFooter(const uno::Reference< report::XSection>& _xSection)
640 SvTreeListEntry* pGroup = find(_xSection->getGroup());
641 OSL_ENSURE(pGroup,"No group found");
642 traverseSection(_xSection,pGroup,SID_GROUPFOOTER);
645 void NavigatorTree::traverseDetail(const uno::Reference< report::XSection>& _xSection)
647 uno::Reference< report::XReportDefinition> xReport = _xSection->getReportDefinition();
648 SvTreeListEntry* pParent = find(xReport);
649 traverseSection(_xSection,pParent,SID_ICON_DETAIL);
652 void NavigatorTree::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException)
654 uno::Reference< report::XReportDefinition> xReport(_rEvent.Source,uno::UNO_QUERY);
655 if ( xReport.is() )
657 bool bEnabled = false;
658 _rEvent.NewValue >>= bEnabled;
659 if ( bEnabled )
661 SvTreeListEntry* pParent = find(xReport);
662 if ( _rEvent.PropertyName == PROPERTY_REPORTHEADERON )
664 sal_uLong nPos = xReport->getReportHeaderOn() ? 2 : 1;
665 traverseSection(xReport->getReportHeader(),pParent,SID_REPORTHEADERFOOTER,nPos);
667 else if ( _rEvent.PropertyName == PROPERTY_PAGEHEADERON )
669 traverseSection(xReport->getPageHeader(),pParent, SID_PAGEHEADERFOOTER,1);
671 else if ( _rEvent.PropertyName == PROPERTY_PAGEFOOTERON )
672 traverseSection(xReport->getPageFooter(),pParent, SID_PAGEHEADERFOOTER);
673 else if ( _rEvent.PropertyName == PROPERTY_REPORTFOOTERON )
675 sal_uLong nPos = xReport->getPageFooterOn() ? (GetLevelChildCount(pParent) - 1) : TREELIST_APPEND;
676 traverseSection(xReport->getReportFooter(),pParent,SID_REPORTHEADERFOOTER,nPos);
682 void NavigatorTree::_elementInserted( const container::ContainerEvent& _rEvent )
684 SvTreeListEntry* pEntry = find(_rEvent.Source);
685 uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY_THROW);
686 OUString sName;
687 uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
688 if ( xInfo.is() )
690 if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
691 xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
692 else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
693 xProp->getPropertyValue(PROPERTY_EXPRESSION) >>= sName;
695 uno::Reference< report::XGroup> xGroup(xProp,uno::UNO_QUERY);
696 if ( xGroup.is() )
698 reportdesign::OReportVisitor aSubVisitor(this);
699 aSubVisitor.start(xGroup);
701 else
703 uno::Reference< report::XReportComponent> xElement(xProp,uno::UNO_QUERY);
704 if ( xProp.is() )
705 sName = lcl_getName(xProp);
706 insertEntry(sName,pEntry,(!xElement.is() ? sal_uInt16(SID_RPT_NEW_FUNCTION) : lcl_getImageId(xElement)),TREELIST_APPEND,new UserData(this,xProp));
708 if ( !IsExpanded(pEntry) )
709 Expand(pEntry);
712 void NavigatorTree::_elementRemoved( const container::ContainerEvent& _rEvent )
714 uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY);
715 SvTreeListEntry* pEntry = find(xProp);
716 OSL_ENSURE(pEntry,"NavigatorTree::_elementRemoved: No Entry found!");
718 if (pEntry)
720 removeEntry(pEntry);
721 Invalidate();
725 void NavigatorTree::_elementReplaced( const container::ContainerEvent& _rEvent )
727 uno::Reference<beans::XPropertySet> xProp(_rEvent.ReplacedElement,uno::UNO_QUERY);
728 SvTreeListEntry* pEntry = find(xProp);
729 if ( pEntry )
731 UserData* pData = static_cast<UserData*>(pEntry->GetUserData());
732 xProp.set(_rEvent.Element,uno::UNO_QUERY);
733 pData->setContent(xProp);
734 OUString sName;
735 xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
736 SetEntryText(pEntry,sName);
740 void NavigatorTree::_disposing(const lang::EventObject& _rSource)
741 throw (uno::RuntimeException, std::exception)
743 removeEntry(find(_rSource.Source));
746 void NavigatorTree::removeEntry(SvTreeListEntry* _pEntry,bool _bRemove)
748 if ( _pEntry )
750 SvTreeListEntry* pChild = FirstChild(_pEntry);
751 while( pChild )
753 removeEntry(pChild,false);
754 pChild = NextSibling(pChild);
756 delete static_cast<UserData*>(_pEntry->GetUserData());
757 if ( _bRemove )
758 GetModel()->Remove(_pEntry);
762 NavigatorTree::UserData::UserData(NavigatorTree* _pTree,const uno::Reference<uno::XInterface>& _xContent)
763 : OPropertyChangeListener(m_aMutex)
764 , OContainerListener(m_aMutex)
765 , m_xContent(_xContent)
766 , m_pTree(_pTree)
768 uno::Reference<beans::XPropertySet> xProp(m_xContent,uno::UNO_QUERY);
769 if ( xProp.is() )
771 uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
772 if ( xInfo.is() )
774 m_pListener = new ::comphelper::OPropertyChangeMultiplexer(this,xProp);
775 if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
776 m_pListener->addProperty(PROPERTY_NAME);
777 else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
778 m_pListener->addProperty(PROPERTY_EXPRESSION);
779 if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) )
780 m_pListener->addProperty(PROPERTY_DATAFIELD);
781 if ( xInfo->hasPropertyByName(PROPERTY_LABEL) )
782 m_pListener->addProperty(PROPERTY_LABEL);
783 if ( xInfo->hasPropertyByName(PROPERTY_HEADERON) )
784 m_pListener->addProperty(PROPERTY_HEADERON);
785 if ( xInfo->hasPropertyByName(PROPERTY_FOOTERON) )
786 m_pListener->addProperty(PROPERTY_FOOTERON);
789 uno::Reference< container::XContainer> xContainer(m_xContent,uno::UNO_QUERY);
790 if ( xContainer.is() )
792 m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
796 NavigatorTree::UserData::~UserData()
798 if ( m_pContainerListener.is() )
799 m_pContainerListener->dispose();
800 if ( m_pListener.is() )
801 m_pListener->dispose();
804 // OPropertyChangeListener
805 void NavigatorTree::UserData::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException)
807 SvTreeListEntry* pEntry = m_pTree->find(_rEvent.Source);
808 OSL_ENSURE(pEntry,"No entry could be found! Why not!");
809 const bool bFooterOn = (PROPERTY_FOOTERON == _rEvent.PropertyName);
812 if ( bFooterOn || PROPERTY_HEADERON == _rEvent.PropertyName )
814 sal_Int32 nPos = 1;
815 uno::Reference< report::XGroup> xGroup(_rEvent.Source,uno::UNO_QUERY);
816 ::std::mem_fun_t< bool,OGroupHelper> pIsOn = ::std::mem_fun(&OGroupHelper::getHeaderOn);
817 ::std::mem_fun_t< uno::Reference<report::XSection> ,OGroupHelper> pMemFunSection = ::std::mem_fun(&OGroupHelper::getHeader);
818 if ( bFooterOn )
820 pIsOn = ::std::mem_fun(&OGroupHelper::getFooterOn);
821 pMemFunSection = ::std::mem_fun(&OGroupHelper::getFooter);
822 nPos = m_pTree->GetChildCount(pEntry) - 1;
825 OGroupHelper aGroupHelper(xGroup);
826 if ( pIsOn(&aGroupHelper) )
828 if ( bFooterOn )
829 ++nPos;
830 m_pTree->traverseSection(pMemFunSection(&aGroupHelper),pEntry,bFooterOn ? SID_GROUPFOOTER : SID_GROUPHEADER,nPos);
833 else if ( PROPERTY_EXPRESSION == _rEvent.PropertyName)
835 OUString sNewName;
836 _rEvent.NewValue >>= sNewName;
837 m_pTree->SetEntryText(pEntry,sNewName);
839 else if ( PROPERTY_DATAFIELD == _rEvent.PropertyName || PROPERTY_LABEL == _rEvent.PropertyName || PROPERTY_NAME == _rEvent.PropertyName )
841 uno::Reference<beans::XPropertySet> xProp(_rEvent.Source,uno::UNO_QUERY);
842 m_pTree->SetEntryText(pEntry,lcl_getName(xProp));
845 catch(const uno::Exception &)
849 void NavigatorTree::UserData::_elementInserted( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException, std::exception)
851 m_pTree->_elementInserted( _rEvent );
854 void NavigatorTree::UserData::_elementRemoved( const container::ContainerEvent& _rEvent )
855 throw (uno::RuntimeException, std::exception)
857 m_pTree->_elementRemoved( _rEvent );
860 void NavigatorTree::UserData::_elementReplaced( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException, std::exception)
862 m_pTree->_elementReplaced( _rEvent );
865 void NavigatorTree::UserData::_disposing(const lang::EventObject& _rSource)
866 throw (uno::RuntimeException, std::exception)
868 m_pTree->_disposing( _rSource );
871 Size NavigatorTree::GetOptimalSize() const
873 return LogicToPixel(Size(100, 70), MAP_APPFONT);
876 // class ONavigatorImpl
877 class ONavigatorImpl: private boost::noncopyable
879 public:
880 ONavigatorImpl(OReportController& _rController,ONavigator* _pParent);
882 uno::Reference< report::XReportDefinition> m_xReport;
883 ::rptui::OReportController& m_rController;
884 VclPtr<NavigatorTree> m_pNavigatorTree;
887 ONavigatorImpl::ONavigatorImpl(OReportController& _rController,ONavigator* _pParent)
888 :m_xReport(_rController.getReportDefinition())
889 ,m_rController(_rController)
890 ,m_pNavigatorTree(VclPtr<NavigatorTree>::Create(_pParent->get<vcl::Window>("box"),_rController))
892 reportdesign::OReportVisitor aVisitor(m_pNavigatorTree.get());
893 aVisitor.start(m_xReport);
894 m_pNavigatorTree->Expand(m_pNavigatorTree->find(m_xReport));
895 lang::EventObject aEvent(m_rController);
896 m_pNavigatorTree->_selectionChanged(aEvent);
899 // class ONavigator
900 ONavigator::ONavigator(vcl::Window* _pParent ,OReportController& _rController)
901 : FloatingWindow( _pParent, "FloatingNavigator", "modules/dbreport/ui/floatingnavigator.ui")
903 m_pImpl.reset(new ONavigatorImpl(_rController,this));
905 m_pImpl->m_pNavigatorTree->Show();
906 m_pImpl->m_pNavigatorTree->GrabFocus();
907 Show();
910 void ONavigator::GetFocus()
912 Window::GetFocus();
913 if ( m_pImpl->m_pNavigatorTree.get() )
914 m_pImpl->m_pNavigatorTree->GrabFocus();
917 } // rptui
920 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */