summaryrefslogtreecommitdiffstats
path: root/reportdesign/source/ui/dlg/Navigator.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'reportdesign/source/ui/dlg/Navigator.cxx')
-rw-r--r--reportdesign/source/ui/dlg/Navigator.cxx988
1 files changed, 988 insertions, 0 deletions
diff --git a/reportdesign/source/ui/dlg/Navigator.cxx b/reportdesign/source/ui/dlg/Navigator.cxx
new file mode 100644
index 000000000000..0c1760b8e48a
--- /dev/null
+++ b/reportdesign/source/ui/dlg/Navigator.cxx
@@ -0,0 +1,988 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#include "precompiled_reportdesign.hxx"
+
+#include "Navigator.hxx"
+
+#include "uistrings.hrc"
+#include "ReportController.hxx"
+#include "UITools.hxx"
+#include "Undo.hxx"
+#include "reportformula.hxx"
+#include <com/sun/star/container/XContainerListener.hpp>
+#include <com/sun/star/report/XReportDefinition.hpp>
+#include <com/sun/star/report/XFixedText.hpp>
+#include <com/sun/star/report/XFixedLine.hpp>
+#include <com/sun/star/report/XFormattedField.hpp>
+#include <com/sun/star/report/XImageControl.hpp>
+#include <com/sun/star/report/XShape.hpp>
+#include <svx/globlmn.hrc>
+#include <svx/svxids.hrc>
+#include "helpids.hrc"
+#include "RptResId.hrc"
+#include "rptui_slotid.hrc"
+#include <tools/debug.hxx>
+#include <comphelper/propmultiplex.hxx>
+#include <comphelper/containermultiplexer.hxx>
+#include <comphelper/types.hxx>
+#include "cppuhelper/basemutex.hxx"
+#include "comphelper/SelectionMultiplex.hxx"
+#include <svtools/svtreebx.hxx>
+#include <svl/solar.hrc>
+#include "ReportVisitor.hxx"
+#include "ModuleHelper.hxx"
+#include <rtl/ref.hxx>
+
+#include <boost/bind.hpp>
+#include <memory>
+#include <algorithm>
+
+#define RID_SVXIMG_COLLAPSEDNODE (RID_FORMS_START + 2)
+#define RID_SVXIMG_EXPANDEDNODE (RID_FORMS_START + 3)
+#define DROP_ACTION_TIMER_INITIAL_TICKS 10
+#define DROP_ACTION_TIMER_SCROLL_TICKS 3
+#define DROP_ACTION_TIMER_TICK_BASE 10
+
+namespace rptui
+{
+using namespace ::com::sun::star;
+using namespace utl;
+using namespace ::comphelper;
+
+USHORT lcl_getImageId(const uno::Reference< report::XReportComponent>& _xElement)
+{
+ USHORT nId = 0;
+ uno::Reference< report::XFixedLine> xFixedLine(_xElement,uno::UNO_QUERY);
+ if ( uno::Reference< report::XFixedText>(_xElement,uno::UNO_QUERY).is() )
+ nId = SID_FM_FIXEDTEXT;
+ else if ( xFixedLine.is() )
+ nId = xFixedLine->getOrientation() ? SID_INSERT_VFIXEDLINE : SID_INSERT_HFIXEDLINE;
+ else if ( uno::Reference< report::XFormattedField>(_xElement,uno::UNO_QUERY).is() )
+ nId = SID_FM_EDIT;
+ else if ( uno::Reference< report::XImageControl>(_xElement,uno::UNO_QUERY).is() )
+ nId = SID_FM_IMAGECONTROL;
+ else if ( uno::Reference< report::XShape>(_xElement,uno::UNO_QUERY).is() )
+ nId = SID_DRAWTBX_CS_BASIC;
+ return nId;
+}
+// -----------------------------------------------------------------------------
+::rtl::OUString lcl_getName(const uno::Reference< beans::XPropertySet>& _xElement)
+{
+ OSL_ENSURE(_xElement.is(),"Found report element which is NULL!");
+ ::rtl::OUString sTempName;
+ _xElement->getPropertyValue(PROPERTY_NAME) >>= sTempName;
+ ::rtl::OUStringBuffer sName = sTempName;
+ uno::Reference< report::XFixedText> xFixedText(_xElement,uno::UNO_QUERY);
+ uno::Reference< report::XReportControlModel> xReportModel(_xElement,uno::UNO_QUERY);
+ if ( xFixedText.is() )
+ {
+ sName.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : ")));
+ sName.append(xFixedText->getLabel());
+ }
+ else if ( xReportModel.is() && _xElement->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) )
+ {
+ ReportFormula aFormula( xReportModel->getDataField() );
+ if ( aFormula.isValid() )
+ {
+ sName.append(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" : ")));
+ sName.append( aFormula.getUndecoratedContent() );
+ }
+ }
+ return sName.makeStringAndClear();
+}
+// -----------------------------------------------------------------------------
+
+class NavigatorTree : public ::cppu::BaseMutex
+ , public SvTreeListBox
+ , public reportdesign::ITraverseReport
+ , public comphelper::OSelectionChangeListener
+ , public ::comphelper::OPropertyChangeListener
+{
+ class UserData;
+ friend class UserData;
+ class UserData : public ::cppu::BaseMutex
+ ,public ::comphelper::OPropertyChangeListener
+ ,public ::comphelper::OContainerListener
+ {
+ uno::Reference< uno::XInterface > m_xContent;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pListener;
+ ::rtl::Reference< comphelper::OContainerListenerAdapter> m_pContainerListener;
+ NavigatorTree* m_pTree;
+ public:
+ UserData(NavigatorTree* _pTree,const uno::Reference<uno::XInterface>& _xContent);
+ ~UserData();
+
+ inline uno::Reference< uno::XInterface > getContent() const { return m_xContent; }
+ inline void setContent(const uno::Reference< uno::XInterface >& _xContent) { m_xContent = _xContent; }
+ protected:
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException);
+
+ // OContainerListener
+ virtual void _elementInserted( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException);
+ virtual void _elementRemoved( const container::ContainerEvent& _Event ) throw(uno::RuntimeException);
+ virtual void _elementReplaced( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException);
+ virtual void _disposing(const lang::EventObject& _rSource) throw( uno::RuntimeException);
+ };
+
+ enum DROP_ACTION { DA_SCROLLUP, DA_SCROLLDOWN, DA_EXPANDNODE };
+ AutoTimer m_aDropActionTimer;
+ Timer m_aSynchronizeTimer;
+ ImageList m_aNavigatorImages;
+ ImageList m_aNavigatorImagesHC;
+ Point m_aTimerTriggered; // die Position, an der der DropTimer angeschaltet wurde
+ DROP_ACTION m_aDropActionType;
+ OReportController& m_rController;
+ SvLBoxEntry* m_pMasterReport;
+ SvLBoxEntry* m_pDragedEntry;
+ ::rtl::Reference< comphelper::OPropertyChangeMultiplexer> m_pReportListener;
+ ::rtl::Reference< comphelper::OSelectionChangeMultiplexer> m_pSelectionListener;
+ unsigned short m_nTimerCounter;
+
+ SvLBoxEntry* insertEntry(const ::rtl::OUString& _sName,SvLBoxEntry* _pParent,USHORT _nImageId,ULONG _nPosition,UserData* _pData);
+ void traverseSection(const uno::Reference< report::XSection>& _xSection,SvLBoxEntry* _pParent,USHORT _nImageId,ULONG _nPosition = LIST_APPEND);
+ void traverseFunctions(const uno::Reference< report::XFunctions>& _xFunctions,SvLBoxEntry* _pParent);
+
+ NavigatorTree(const NavigatorTree&);
+ void operator =(const NavigatorTree&);
+protected:
+ virtual void Command( const CommandEvent& rEvt );
+ // DragSourceHelper overridables
+ virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel );
+ // DropTargetHelper overridables
+ virtual sal_Int8 AcceptDrop( const AcceptDropEvent& _rEvt );
+ virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& _rEvt );
+
+ // OSelectionChangeListener
+ virtual void _disposing(const lang::EventObject& _rSource) throw( uno::RuntimeException);
+
+ // OPropertyChangeListener
+ virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException);
+
+ // OContainerListener Helper
+ void _elementInserted( const container::ContainerEvent& _rEvent );
+ void _elementRemoved( const container::ContainerEvent& _Event );
+ void _elementReplaced( const container::ContainerEvent& _rEvent );
+
+public:
+ NavigatorTree(Window* pParent,OReportController& _rController );
+ virtual ~NavigatorTree();
+
+ DECL_LINK(OnEntrySelDesel, NavigatorTree*);
+ DECL_LINK( OnDropActionTimer, void* );
+
+ virtual void _selectionChanged( const lang::EventObject& aEvent ) throw (uno::RuntimeException);
+
+ // ITraverseReport
+ virtual void traverseReport(const uno::Reference< report::XReportDefinition>& _xReport);
+ virtual void traverseReportFunctions(const uno::Reference< report::XFunctions>& _xFunctions);
+ virtual void traverseReportHeader(const uno::Reference< report::XSection>& _xSection);
+ virtual void traverseReportFooter(const uno::Reference< report::XSection>& _xSection);
+ virtual void traversePageHeader(const uno::Reference< report::XSection>& _xSection);
+ virtual void traversePageFooter(const uno::Reference< report::XSection>& _xSection);
+
+ virtual void traverseGroups(const uno::Reference< report::XGroups>& _xGroups);
+ virtual void traverseGroup(const uno::Reference< report::XGroup>& _xGroup);
+ virtual void traverseGroupFunctions(const uno::Reference< report::XFunctions>& _xFunctions);
+ virtual void traverseGroupHeader(const uno::Reference< report::XSection>& _xSection);
+ virtual void traverseGroupFooter(const uno::Reference< report::XSection>& _xSection);
+
+ virtual void traverseDetail(const uno::Reference< report::XSection>& _xSection);
+
+ SvLBoxEntry* find(const uno::Reference< uno::XInterface >& _xContent);
+ void removeEntry(SvLBoxEntry* _pEntry,bool _bRemove = true);
+private:
+ using SvTreeListBox::ExecuteDrop;
+};
+DBG_NAME(rpt_NavigatorTree)
+// -----------------------------------------------------------------------------
+NavigatorTree::NavigatorTree( Window* pParent,OReportController& _rController )
+ :SvTreeListBox( pParent, WB_TABSTOP| WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HSCROLL|WB_HASBUTTONSATROOT )
+ ,comphelper::OSelectionChangeListener(m_aMutex)
+ ,OPropertyChangeListener(m_aMutex)
+ ,m_aTimerTriggered(-1,-1)
+ ,m_aDropActionType( DA_SCROLLUP )
+ ,m_rController(_rController)
+ ,m_pMasterReport(NULL)
+ ,m_pDragedEntry(NULL)
+ ,m_nTimerCounter( DROP_ACTION_TIMER_INITIAL_TICKS )
+{
+ DBG_CTOR(rpt_NavigatorTree,NULL);
+ m_pReportListener = new OPropertyChangeMultiplexer(this,m_rController.getReportDefinition().get());
+ m_pReportListener->addProperty(PROPERTY_PAGEHEADERON);
+ m_pReportListener->addProperty(PROPERTY_PAGEFOOTERON);
+ m_pReportListener->addProperty(PROPERTY_REPORTHEADERON);
+ m_pReportListener->addProperty(PROPERTY_REPORTFOOTERON);
+
+ m_pSelectionListener = new OSelectionChangeMultiplexer(this,&m_rController);
+
+ SetHelpId( HID_REPORT_NAVIGATOR_TREE );
+
+ m_aNavigatorImages = ImageList( ModuleRes( RID_SVXIMGLIST_RPTEXPL ) );
+ m_aNavigatorImagesHC = ImageList( ModuleRes( RID_SVXIMGLIST_RPTEXPL_HC ) );
+
+ SetNodeBitmaps(
+ m_aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
+ m_aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
+ BMP_COLOR_NORMAL
+ );
+ SetNodeBitmaps(
+ m_aNavigatorImagesHC.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
+ m_aNavigatorImagesHC.GetImage( RID_SVXIMG_EXPANDEDNODE ),
+ BMP_COLOR_HIGHCONTRAST
+ );
+
+ SetDragDropMode(0xFFFF);
+ EnableInplaceEditing( sal_False );
+ SetSelectionMode(MULTIPLE_SELECTION);
+ Clear();
+
+ m_aDropActionTimer.SetTimeoutHdl(LINK(this, NavigatorTree, OnDropActionTimer));
+ SetSelectHdl(LINK(this, NavigatorTree, OnEntrySelDesel));
+ SetDeselectHdl(LINK(this, NavigatorTree, OnEntrySelDesel));
+}
+// -----------------------------------------------------------------------------
+NavigatorTree::~NavigatorTree()
+{
+ SvLBoxEntry* pCurrent = First();
+ while ( pCurrent )
+ {
+ delete static_cast<UserData*>(pCurrent->GetUserData());
+ pCurrent = Next(pCurrent);
+ }
+ m_pReportListener->dispose();
+ m_pSelectionListener->dispose();
+ DBG_DTOR(rpt_NavigatorTree,NULL);
+}
+//------------------------------------------------------------------------------
+void NavigatorTree::Command( const CommandEvent& rEvt )
+{
+ sal_Bool bHandled = sal_False;
+ switch( rEvt.GetCommand() )
+ {
+ case COMMAND_CONTEXTMENU:
+ {
+ // die Stelle, an der geklickt wurde
+ SvLBoxEntry* ptClickedOn = NULL;
+ ::Point aWhere;
+ if (rEvt.IsMouseEvent())
+ {
+ aWhere = rEvt.GetMousePosPixel();
+ ptClickedOn = GetEntry(aWhere);
+ if (ptClickedOn == NULL)
+ break;
+ if ( !IsSelected(ptClickedOn) )
+ {
+ SelectAll(sal_False);
+ Select(ptClickedOn, sal_True);
+ SetCurEntry(ptClickedOn);
+ }
+ }
+ else
+ {
+ ptClickedOn = GetCurEntry();
+ if ( !ptClickedOn )
+ break;
+ aWhere = GetEntryPosition(ptClickedOn);
+ }
+ UserData* pData = static_cast<UserData*>(ptClickedOn->GetUserData());
+ uno::Reference< report::XFunctionsSupplier> xSupplier(pData->getContent(),uno::UNO_QUERY);
+ uno::Reference< report::XFunctions> xFunctions(pData->getContent(),uno::UNO_QUERY);
+ uno::Reference< report::XGroup> xGroup(pData->getContent(),uno::UNO_QUERY);
+ sal_Bool bDeleteAllowed = m_rController.isEditable() && (xGroup.is() ||
+ uno::Reference< report::XFunction>(pData->getContent(),uno::UNO_QUERY).is());
+ PopupMenu aContextMenu( ModuleRes( RID_MENU_NAVIGATOR ) );
+
+ USHORT nCount = aContextMenu.GetItemCount();
+ for (USHORT i = 0; i < nCount; ++i)
+ {
+ if ( MENUITEM_SEPARATOR != aContextMenu.GetItemType(i))
+ {
+ USHORT nId = aContextMenu.GetItemId(i);
+
+ aContextMenu.CheckItem(nId,m_rController.isCommandChecked(nId));
+ sal_Bool bEnabled = m_rController.isCommandEnabled(nId);
+ if ( nId == SID_RPT_NEW_FUNCTION )
+ aContextMenu.EnableItem(nId,m_rController.isEditable() && (xSupplier.is() || xFunctions.is()) );
+ // special condition, check for function and group
+ else if ( nId == SID_DELETE )
+ aContextMenu.EnableItem(SID_DELETE,bDeleteAllowed);
+ else
+ aContextMenu.EnableItem(nId,bEnabled);
+ }
+ } // for (USHORT i = 0; i < nCount; ++i)
+ USHORT nId = aContextMenu.Execute(this, aWhere);
+ if ( nId )
+ {
+ uno::Sequence< beans::PropertyValue> aArgs;
+ if ( nId == SID_RPT_NEW_FUNCTION )
+ {
+ aArgs.realloc(1);
+ aArgs[0].Value <<= (xFunctions.is() ? xFunctions : xSupplier->getFunctions());
+ }
+ else if ( nId == SID_DELETE )
+ {
+ if ( xGroup.is() )
+ nId = SID_GROUP_REMOVE;
+ aArgs.realloc(1);
+ aArgs[0].Name = PROPERTY_GROUP;
+ aArgs[0].Value <<= pData->getContent();
+ }
+ m_rController.executeUnChecked(nId,aArgs);
+ }
+
+ bHandled = sal_True;
+ } break;
+ }
+
+ if (!bHandled)
+ SvTreeListBox::Command( rEvt );
+}
+// -----------------------------------------------------------------------------
+sal_Int8 NavigatorTree::AcceptDrop( const AcceptDropEvent& _rEvt )
+{
+ sal_Int8 nDropOption = DND_ACTION_NONE;
+ ::Point aDropPos = _rEvt.maPosPixel;
+ if (_rEvt.mbLeaving)
+ {
+ if (m_aDropActionTimer.IsActive())
+ m_aDropActionTimer.Stop();
+ }
+ else
+ {
+ bool bNeedTrigger = false;
+ // auf dem ersten Eintrag ?
+ if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight()))
+ {
+ m_aDropActionType = DA_SCROLLUP;
+ bNeedTrigger = true;
+ }
+ else if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight()))
+ {
+ m_aDropActionType = DA_SCROLLDOWN;
+ bNeedTrigger = true;
+ }
+ else
+ {
+ SvLBoxEntry* pDropppedOn = GetEntry(aDropPos);
+ if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
+ {
+ m_aDropActionType = DA_EXPANDNODE;
+ bNeedTrigger = true;
+ }
+ }
+
+ if (bNeedTrigger && (m_aTimerTriggered != aDropPos))
+ {
+ // neu anfangen zu zaehlen
+ m_nTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS;
+ // die Pos merken, da ich auch AcceptDrops bekomme, wenn sich die Maus gar nicht bewegt hat
+ m_aTimerTriggered = aDropPos;
+ // und den Timer los
+ if (!m_aDropActionTimer.IsActive()) // gibt es den Timer schon ?
+ {
+ m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE);
+ m_aDropActionTimer.Start();
+ }
+ }
+ else if (!bNeedTrigger)
+ m_aDropActionTimer.Stop();
+ }
+
+ return nDropOption;
+}
+// -------------------------------------------------------------------------
+sal_Int8 NavigatorTree::ExecuteDrop( const ExecuteDropEvent& /*_rEvt*/ )
+{
+ // _rEvt.mnAction;
+ return DND_ACTION_NONE;
+}
+// -------------------------------------------------------------------------
+void NavigatorTree::StartDrag( sal_Int8 /*_nAction*/, const Point& _rPosPixel )
+{
+ m_pDragedEntry = GetEntry(_rPosPixel);
+ if ( m_pDragedEntry )
+ {
+ EndSelection();
+ }
+}
+//------------------------------------------------------------------------
+IMPL_LINK( NavigatorTree, OnDropActionTimer, void*, EMPTYARG )
+{
+ if (--m_nTimerCounter > 0)
+ return 0L;
+
+ switch ( m_aDropActionType )
+ {
+ case DA_EXPANDNODE:
+ {
+ SvLBoxEntry* pToExpand = GetEntry(m_aTimerTriggered);
+ if (pToExpand && (GetChildCount(pToExpand) > 0) && !IsExpanded(pToExpand))
+ // tja, eigentlich muesste ich noch testen, ob die Node nicht schon expandiert ist, aber ich
+ // habe dazu weder in den Basisklassen noch im Model eine Methode gefunden ...
+ // aber ich denke, die BK sollte es auch so vertragen
+ Expand(pToExpand);
+
+ // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
+ m_aDropActionTimer.Stop();
+ }
+ break;
+
+ case DA_SCROLLUP :
+ ScrollOutputArea( 1 );
+ m_nTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
+ break;
+
+ case DA_SCROLLDOWN :
+ ScrollOutputArea( -1 );
+ m_nTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
+ break;
+
+ }
+
+ return 0L;
+}
+
+// -----------------------------------------------------------------------------
+IMPL_LINK(NavigatorTree, OnEntrySelDesel, NavigatorTree*, /*pThis*/)
+{
+ if ( !m_pSelectionListener->locked() )
+ {
+ m_pSelectionListener->lock();
+ SvLBoxEntry* pEntry = GetCurEntry();
+ uno::Any aSelection;
+ if ( IsSelected(pEntry) )
+ aSelection <<= static_cast<UserData*>(pEntry->GetUserData())->getContent();
+ m_rController.select(aSelection);
+ m_pSelectionListener->unlock();
+ }
+
+ return 0L;
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::_selectionChanged( const lang::EventObject& aEvent ) throw (uno::RuntimeException)
+{
+ m_pSelectionListener->lock();
+ uno::Reference< view::XSelectionSupplier> xSelectionSupplier(aEvent.Source,uno::UNO_QUERY);
+ uno::Any aSec = xSelectionSupplier->getSelection();
+ uno::Sequence< uno::Reference< report::XReportComponent > > aSelection;
+ aSec >>= aSelection;
+ if ( !aSelection.getLength() )
+ {
+ uno::Reference< uno::XInterface> xSelection(aSec,uno::UNO_QUERY);
+ SvLBoxEntry* pEntry = find(xSelection);
+ if ( pEntry && !IsSelected(pEntry) )
+ {
+ Select(pEntry, sal_True);
+ SetCurEntry(pEntry);
+ }
+ else if ( !pEntry )
+ SelectAll(FALSE,FALSE);
+ }
+ else
+ {
+ const uno::Reference< report::XReportComponent >* pIter = aSelection.getConstArray();
+ const uno::Reference< report::XReportComponent >* pEnd = pIter + aSelection.getLength();
+ for (; pIter != pEnd; ++pIter)
+ {
+ SvLBoxEntry* pEntry = find(*pIter);
+ if ( pEntry && !IsSelected(pEntry) )
+ {
+ Select(pEntry, sal_True);
+ SetCurEntry(pEntry);
+ }
+ }
+ }
+ m_pSelectionListener->unlock();
+}
+// -----------------------------------------------------------------------------
+SvLBoxEntry* NavigatorTree::insertEntry(const ::rtl::OUString& _sName,SvLBoxEntry* _pParent,USHORT _nImageId,ULONG _nPosition,UserData* _pData)
+{
+ SvLBoxEntry* pEntry = NULL;
+ if ( _nImageId )
+ {
+ const Image aImage( m_aNavigatorImages.GetImage( _nImageId ) );
+ pEntry = InsertEntry(_sName,aImage,aImage,_pParent,FALSE,_nPosition,_pData);
+ if ( pEntry )
+ {
+ const Image aImageHC( m_aNavigatorImagesHC.GetImage( _nImageId ) );
+ SetExpandedEntryBmp( pEntry, aImageHC, BMP_COLOR_HIGHCONTRAST );
+ SetCollapsedEntryBmp( pEntry, aImageHC, BMP_COLOR_HIGHCONTRAST );
+ }
+ }
+ else
+ pEntry = InsertEntry(_sName,_pParent,FALSE,_nPosition,_pData);
+ return pEntry;
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseSection(const uno::Reference< report::XSection>& _xSection,SvLBoxEntry* _pParent,USHORT _nImageId,ULONG _nPosition)
+{
+ SvLBoxEntry* pSection = insertEntry(_xSection->getName(),_pParent,_nImageId,_nPosition,new UserData(this,_xSection));
+ const sal_Int32 nCount = _xSection->getCount();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ uno::Reference< report::XReportComponent> xElement(_xSection->getByIndex(i),uno::UNO_QUERY_THROW);
+ OSL_ENSURE(xElement.is(),"Found report element which is NULL!");
+ insertEntry(lcl_getName(xElement.get()),pSection,lcl_getImageId(xElement),LIST_APPEND,new UserData(this,xElement));
+ uno::Reference< report::XReportDefinition> xSubReport(xElement,uno::UNO_QUERY);
+ if ( xSubReport.is() )
+ {
+ m_pMasterReport = find(_xSection->getReportDefinition());
+ reportdesign::OReportVisitor aSubVisitor(this);
+ aSubVisitor.start(xSubReport);
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseFunctions(const uno::Reference< report::XFunctions>& _xFunctions,SvLBoxEntry* _pParent)
+{
+ SvLBoxEntry* pFunctions = insertEntry(String(ModuleRes(RID_STR_FUNCTIONS)),_pParent,SID_RPT_NEW_FUNCTION,LIST_APPEND,new UserData(this,_xFunctions));
+ const sal_Int32 nCount = _xFunctions->getCount();
+ for (sal_Int32 i = 0; i< nCount; ++i)
+ {
+ uno::Reference< report::XFunction> xElement(_xFunctions->getByIndex(i),uno::UNO_QUERY);
+ insertEntry(xElement->getName(),pFunctions,SID_RPT_NEW_FUNCTION,LIST_APPEND,new UserData(this,xElement));
+ }
+}
+// -----------------------------------------------------------------------------
+SvLBoxEntry* NavigatorTree::find(const uno::Reference< uno::XInterface >& _xContent)
+{
+ SvLBoxEntry* pRet = NULL;
+ if ( _xContent.is() )
+ {
+ SvLBoxEntry* pCurrent = First();
+ while ( pCurrent )
+ {
+ UserData* pData = static_cast<UserData*>(pCurrent->GetUserData());
+ OSL_ENSURE(pData,"No UserData set an entry!");
+ if ( pData->getContent() == _xContent )
+ {
+ pRet = pCurrent;
+ break;
+ }
+ pCurrent = Next(pCurrent);
+ }
+ }
+ return pRet;
+}
+// -----------------------------------------------------------------------------
+// ITraverseReport
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseReport(const uno::Reference< report::XReportDefinition>& _xReport)
+{
+ insertEntry(_xReport->getName(),m_pMasterReport,SID_SELECT_REPORT,LIST_APPEND,new UserData(this,_xReport));
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseReportFunctions(const uno::Reference< report::XFunctions>& _xFunctions)
+{
+ SvLBoxEntry* pReport = find(_xFunctions->getParent());
+ traverseFunctions(_xFunctions,pReport);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseReportHeader(const uno::Reference< report::XSection>& _xSection)
+{
+ SvLBoxEntry* pReport = find(_xSection->getReportDefinition());
+ traverseSection(_xSection,pReport,SID_REPORTHEADERFOOTER);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseReportFooter(const uno::Reference< report::XSection>& _xSection)
+{
+ SvLBoxEntry* pReport = find(_xSection->getReportDefinition());
+ traverseSection(_xSection,pReport,SID_REPORTHEADERFOOTER);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traversePageHeader(const uno::Reference< report::XSection>& _xSection)
+{
+ SvLBoxEntry* pReport = find(_xSection->getReportDefinition());
+ traverseSection(_xSection,pReport,SID_PAGEHEADERFOOTER);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traversePageFooter(const uno::Reference< report::XSection>& _xSection)
+{
+ SvLBoxEntry* pReport = find(_xSection->getReportDefinition());
+ traverseSection(_xSection,pReport,SID_PAGEHEADERFOOTER);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseGroups(const uno::Reference< report::XGroups>& _xGroups)
+{
+ SvLBoxEntry* pReport = find(_xGroups->getReportDefinition());
+ insertEntry(String(ModuleRes(RID_STR_GROUPS)),pReport,SID_SORTINGANDGROUPING,LIST_APPEND,new UserData(this,_xGroups));
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseGroup(const uno::Reference< report::XGroup>& _xGroup)
+{
+ uno::Reference< report::XGroups> xGroups(_xGroup->getParent(),uno::UNO_QUERY);
+ SvLBoxEntry* pGroups = find(xGroups);
+ OSL_ENSURE(pGroups,"No Groups inserted so far. Why!");
+ insertEntry(_xGroup->getExpression(),pGroups,SID_GROUP,rptui::getPositionInIndexAccess(xGroups.get(),_xGroup),new UserData(this,_xGroup));
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseGroupFunctions(const uno::Reference< report::XFunctions>& _xFunctions)
+{
+ SvLBoxEntry* pGroup = find(_xFunctions->getParent());
+ traverseFunctions(_xFunctions,pGroup);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseGroupHeader(const uno::Reference< report::XSection>& _xSection)
+{
+ SvLBoxEntry* pGroup = find(_xSection->getGroup());
+ OSL_ENSURE(pGroup,"No group found");
+ traverseSection(_xSection,pGroup,SID_GROUPHEADER,1);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseGroupFooter(const uno::Reference< report::XSection>& _xSection)
+{
+ SvLBoxEntry* pGroup = find(_xSection->getGroup());
+ OSL_ENSURE(pGroup,"No group found");
+ traverseSection(_xSection,pGroup,SID_GROUPFOOTER);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::traverseDetail(const uno::Reference< report::XSection>& _xSection)
+{
+ uno::Reference< report::XReportDefinition> xReport = _xSection->getReportDefinition();
+ SvLBoxEntry* pParent = find(xReport);
+ traverseSection(_xSection,pParent,SID_ICON_DETAIL);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException)
+{
+ uno::Reference< report::XReportDefinition> xReport(_rEvent.Source,uno::UNO_QUERY);
+ if ( xReport.is() )
+ {
+ sal_Bool bEnabled = sal_False;
+ _rEvent.NewValue >>= bEnabled;
+ if ( bEnabled )
+ {
+ SvLBoxEntry* pParent = find(xReport);
+ if ( _rEvent.PropertyName == PROPERTY_REPORTHEADERON )
+ {
+ ULONG nPos = xReport->getReportHeaderOn() ? 2 : 1;
+ traverseSection(xReport->getReportHeader(),pParent,SID_REPORTHEADERFOOTER,nPos);
+ }
+ else if ( _rEvent.PropertyName == PROPERTY_PAGEHEADERON )
+ {
+ traverseSection(xReport->getPageHeader(),pParent, SID_PAGEHEADERFOOTER,1);
+ }
+ else if ( _rEvent.PropertyName == PROPERTY_PAGEFOOTERON )
+ traverseSection(xReport->getPageFooter(),pParent, SID_PAGEHEADERFOOTER);
+ else if ( _rEvent.PropertyName == PROPERTY_REPORTFOOTERON )
+ {
+ ULONG nPos = xReport->getPageFooterOn() ? (GetLevelChildCount(pParent) - 1) : LIST_APPEND;
+ traverseSection(xReport->getReportFooter(),pParent,SID_REPORTHEADERFOOTER,nPos);
+ }
+ }
+ }
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::_elementInserted( const container::ContainerEvent& _rEvent )
+{
+ SvLBoxEntry* pEntry = find(_rEvent.Source);
+ uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY_THROW);
+ ::rtl::OUString sName;
+ uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
+ if ( xInfo.is() )
+ {
+ if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
+ xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
+ else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
+ xProp->getPropertyValue(PROPERTY_EXPRESSION) >>= sName;
+ }
+ uno::Reference< report::XGroup> xGroup(xProp,uno::UNO_QUERY);
+ if ( xGroup.is() )
+ {
+ reportdesign::OReportVisitor aSubVisitor(this);
+ aSubVisitor.start(xGroup);
+ }
+ else
+ {
+ uno::Reference< report::XReportComponent> xElement(xProp,uno::UNO_QUERY);
+ if ( xProp.is() )
+ sName = lcl_getName(xProp);
+ insertEntry(sName,pEntry,(!xElement.is() ? USHORT(SID_RPT_NEW_FUNCTION) : lcl_getImageId(xElement)),LIST_APPEND,new UserData(this,xProp));
+ }
+ if ( !IsExpanded(pEntry) )
+ Expand(pEntry);
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::_elementRemoved( const container::ContainerEvent& _rEvent )
+{
+ uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY);
+ SvLBoxEntry* pEntry = find(xProp);
+ OSL_ENSURE(pEntry,"NavigatorTree::_elementRemoved: No Entry found!");
+
+ if ( pEntry )
+ {
+ SvLBoxEntry* pParent = GetParent(pEntry);
+ removeEntry(pEntry);
+ PaintEntry(pParent);
+ }
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::_elementReplaced( const container::ContainerEvent& _rEvent )
+{
+ uno::Reference<beans::XPropertySet> xProp(_rEvent.ReplacedElement,uno::UNO_QUERY);
+ SvLBoxEntry* pEntry = find(xProp);
+ if ( pEntry )
+ {
+ UserData* pData = static_cast<UserData*>(pEntry->GetUserData());
+ xProp.set(_rEvent.Element,uno::UNO_QUERY);
+ pData->setContent(xProp);
+ ::rtl::OUString sName;
+ xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
+ SetEntryText(pEntry,sName);
+ }
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::_disposing(const lang::EventObject& _rSource)throw( uno::RuntimeException)
+{
+ removeEntry(find(_rSource.Source));
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::removeEntry(SvLBoxEntry* _pEntry,bool _bRemove)
+{
+ if ( _pEntry )
+ {
+ SvLBoxEntry* pChild = FirstChild(_pEntry);
+ while( pChild )
+ {
+ removeEntry(pChild,false);
+ pChild = NextSibling(pChild);
+ }
+ delete static_cast<UserData*>(_pEntry->GetUserData());
+ if ( _bRemove )
+ GetModel()->Remove(_pEntry);
+ }
+}
+DBG_NAME(rpt_NavigatorTree_UserData)
+// -----------------------------------------------------------------------------
+NavigatorTree::UserData::UserData(NavigatorTree* _pTree,const uno::Reference<uno::XInterface>& _xContent)
+ : OPropertyChangeListener(m_aMutex)
+ , OContainerListener(m_aMutex)
+ , m_xContent(_xContent)
+ , m_pTree(_pTree)
+{
+ DBG_CTOR(rpt_NavigatorTree_UserData,NULL);
+ uno::Reference<beans::XPropertySet> xProp(m_xContent,uno::UNO_QUERY);
+ if ( xProp.is() )
+ {
+ uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
+ if ( xInfo.is() )
+ {
+ m_pListener = new ::comphelper::OPropertyChangeMultiplexer(this,xProp);
+ if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
+ m_pListener->addProperty(PROPERTY_NAME);
+ else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
+ m_pListener->addProperty(PROPERTY_EXPRESSION);
+ if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) )
+ m_pListener->addProperty(PROPERTY_DATAFIELD);
+ if ( xInfo->hasPropertyByName(PROPERTY_LABEL) )
+ m_pListener->addProperty(PROPERTY_LABEL);
+ if ( xInfo->hasPropertyByName(PROPERTY_HEADERON) )
+ m_pListener->addProperty(PROPERTY_HEADERON);
+ if ( xInfo->hasPropertyByName(PROPERTY_FOOTERON) )
+ m_pListener->addProperty(PROPERTY_FOOTERON);
+ }
+ }
+ uno::Reference< container::XContainer> xContainer(m_xContent,uno::UNO_QUERY);
+ if ( xContainer.is() )
+ {
+ m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
+ }
+}
+// -----------------------------------------------------------------------------
+NavigatorTree::UserData::~UserData()
+{
+ DBG_DTOR(rpt_NavigatorTree_UserData,NULL);
+ if ( m_pContainerListener.is() )
+ m_pContainerListener->dispose();
+ if ( m_pListener.is() )
+ m_pListener->dispose();
+}
+// -----------------------------------------------------------------------------
+// OPropertyChangeListener
+void NavigatorTree::UserData::_propertyChanged(const beans::PropertyChangeEvent& _rEvent) throw( uno::RuntimeException)
+{
+ SvLBoxEntry* pEntry = m_pTree->find(_rEvent.Source);
+ OSL_ENSURE(pEntry,"No entry could be found! Why not!");
+ const bool bFooterOn = (PROPERTY_FOOTERON == _rEvent.PropertyName);
+ try
+ {
+ if ( bFooterOn || PROPERTY_HEADERON == _rEvent.PropertyName )
+ {
+ sal_Int32 nPos = 1;
+ uno::Reference< report::XGroup> xGroup(_rEvent.Source,uno::UNO_QUERY);
+ ::std::mem_fun_t< sal_Bool,OGroupHelper> pIsOn = ::std::mem_fun(&OGroupHelper::getHeaderOn);
+ ::std::mem_fun_t< uno::Reference<report::XSection> ,OGroupHelper> pMemFunSection = ::std::mem_fun(&OGroupHelper::getHeader);
+ if ( bFooterOn )
+ {
+ pIsOn = ::std::mem_fun(&OGroupHelper::getFooterOn);
+ pMemFunSection = ::std::mem_fun(&OGroupHelper::getFooter);
+ nPos = m_pTree->GetChildCount(pEntry) - 1;
+ }
+
+ OGroupHelper aGroupHelper(xGroup);
+ if ( pIsOn(&aGroupHelper) )
+ {
+ if ( bFooterOn )
+ ++nPos;
+ m_pTree->traverseSection(pMemFunSection(&aGroupHelper),pEntry,bFooterOn ? SID_GROUPFOOTER : SID_GROUPHEADER,nPos);
+ }
+ //else
+ // m_pTree->removeEntry(m_pTree->GetEntry(pEntry,nPos));
+ }
+ else if ( PROPERTY_EXPRESSION == _rEvent.PropertyName)
+ {
+ ::rtl::OUString sNewName;
+ _rEvent.NewValue >>= sNewName;
+ m_pTree->SetEntryText(pEntry,sNewName);
+ }
+ else if ( PROPERTY_DATAFIELD == _rEvent.PropertyName || PROPERTY_LABEL == _rEvent.PropertyName || PROPERTY_NAME == _rEvent.PropertyName )
+ {
+ uno::Reference<beans::XPropertySet> xProp(_rEvent.Source,uno::UNO_QUERY);
+ m_pTree->SetEntryText(pEntry,lcl_getName(xProp));
+ }
+ }
+ catch(uno::Exception)
+ {}
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::UserData::_elementInserted( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException)
+{
+ m_pTree->_elementInserted( _rEvent );
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::UserData::_elementRemoved( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException)
+{
+ m_pTree->_elementRemoved( _rEvent );
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::UserData::_elementReplaced( const container::ContainerEvent& _rEvent ) throw(uno::RuntimeException)
+{
+ m_pTree->_elementReplaced( _rEvent );
+}
+// -----------------------------------------------------------------------------
+void NavigatorTree::UserData::_disposing(const lang::EventObject& _rSource) throw( uno::RuntimeException)
+{
+ m_pTree->_disposing( _rSource );
+}
+// -----------------------------------------------------------------------------
+// class ONavigatorImpl
+// -----------------------------------------------------------------------------
+class ONavigatorImpl
+{
+ ONavigatorImpl(const ONavigatorImpl&);
+ void operator =(const ONavigatorImpl&);
+public:
+ ONavigatorImpl(OReportController& _rController,ONavigator* _pParent);
+ virtual ~ONavigatorImpl();
+
+ uno::Reference< report::XReportDefinition> m_xReport;
+ ::rptui::OReportController& m_rController;
+ ::std::auto_ptr<NavigatorTree> m_pNavigatorTree;
+};
+
+ONavigatorImpl::ONavigatorImpl(OReportController& _rController,ONavigator* _pParent)
+ :m_xReport(_rController.getReportDefinition())
+ ,m_rController(_rController)
+ ,m_pNavigatorTree(new NavigatorTree(_pParent,_rController))
+{
+ reportdesign::OReportVisitor aVisitor(m_pNavigatorTree.get());
+ aVisitor.start(m_xReport);
+ m_pNavigatorTree->Expand(m_pNavigatorTree->find(m_xReport));
+ lang::EventObject aEvent(m_rController);
+ m_pNavigatorTree->_selectionChanged(aEvent);
+}
+//------------------------------------------------------------------------
+ONavigatorImpl::~ONavigatorImpl()
+{
+}
+// -----------------------------------------------------------------------------
+DBG_NAME( rpt_ONavigator )
+const long STD_WIN_SIZE_X = 210;
+const long STD_WIN_SIZE_Y = 280;
+const long LISTBOX_BORDER = 2;
+//========================================================================
+// class ONavigator
+//========================================================================
+ONavigator::ONavigator( Window* _pParent
+ ,OReportController& _rController)
+ : FloatingWindow( _pParent, ModuleRes(RID_NAVIGATOR) )
+{
+ DBG_CTOR( rpt_ONavigator,NULL);
+
+ m_pImpl.reset(new ONavigatorImpl(_rController,this));
+
+ //Size aSpace = LogicToPixel( Size( 7, 120), MAP_APPFONT );
+ //Size aOutSize(nMaxTextWidth + m_aHeader.GetSizePixel().Width() + 3*aSpace.Width(),aSpace.Height());
+ //SetMinOutputSizePixel(aOutSize);
+ //SetOutputSizePixel(aOutSize);
+ FreeResource();
+ m_pImpl->m_pNavigatorTree->Show();
+ m_pImpl->m_pNavigatorTree->GrabFocus();
+ SetSizePixel(Size(STD_WIN_SIZE_X,STD_WIN_SIZE_Y));
+ Show();
+
+}
+// -----------------------------------------------------------------------------
+
+//------------------------------------------------------------------------
+ONavigator::~ONavigator()
+{
+ DBG_DTOR( rpt_ONavigator,NULL);
+}
+//------------------------------------------------------------------------------
+void ONavigator::Resize()
+{
+ FloatingWindow::Resize();
+
+ Point aPos(GetPosPixel());
+ Size aSize( GetOutputSizePixel() );
+
+ //////////////////////////////////////////////////////////////////////
+
+ // Groesse der form::ListBox anpassen
+ Point aLBPos( LISTBOX_BORDER, LISTBOX_BORDER );
+ Size aLBSize( aSize );
+ aLBSize.Width() -= (2*LISTBOX_BORDER);
+ aLBSize.Height() -= (2*LISTBOX_BORDER);
+
+ m_pImpl->m_pNavigatorTree->SetPosSizePixel( aLBPos, aLBSize );
+}
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+void ONavigator::GetFocus()
+{
+ Window::GetFocus();
+ if ( m_pImpl->m_pNavigatorTree.get() )
+ m_pImpl->m_pNavigatorTree->GrabFocus();
+}
+// =============================================================================
+} // rptui
+// =============================================================================
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */