summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
Diffstat (limited to 'sc')
-rw-r--r--sc/inc/AccessibleFilterMenu.hxx194
-rw-r--r--sc/inc/AccessibleFilterMenuItem.hxx124
-rw-r--r--sc/inc/AccessibleFilterTopWindow.hxx104
-rw-r--r--sc/inc/AccessibleGlobal.hxx72
-rw-r--r--sc/inc/attrib.hxx16
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/inc/document.hxx2
-rw-r--r--sc/inc/dpgroup.hxx5
-rw-r--r--sc/inc/dpobject.hxx42
-rw-r--r--sc/inc/dpoutput.hxx7
-rw-r--r--sc/inc/dpoutputgeometry.hxx80
-rw-r--r--sc/inc/dpsave.hxx73
-rw-r--r--sc/inc/dptabres.hxx5
-rw-r--r--sc/inc/dptabsrc.hxx18
-rw-r--r--sc/inc/fillinfo.hxx2
-rw-r--r--sc/inc/global.hxx2
-rw-r--r--sc/inc/miscuno.hxx17
-rw-r--r--sc/inc/pivot.hxx46
-rw-r--r--sc/inc/sc.hrc5
-rw-r--r--sc/inc/scabstdlg.hxx2
-rw-r--r--sc/inc/table.hxx1
-rw-r--r--sc/inc/unonames.hxx4
-rw-r--r--sc/source/core/data/attarray.cxx3
-rw-r--r--sc/source/core/data/column2.cxx14
-rw-r--r--sc/source/core/data/documen8.cxx10
-rw-r--r--sc/source/core/data/document.cxx26
-rw-r--r--sc/source/core/data/dpgroup.cxx4
-rw-r--r--sc/source/core/data/dpobject.cxx329
-rw-r--r--sc/source/core/data/dpoutput.cxx104
-rw-r--r--sc/source/core/data/dpoutputgeometry.cxx217
-rw-r--r--sc/source/core/data/dpsave.cxx327
-rw-r--r--sc/source/core/data/dptabres.cxx94
-rw-r--r--sc/source/core/data/dptabsrc.cxx129
-rw-r--r--sc/source/core/data/fillinfo.cxx8
-rw-r--r--sc/source/core/data/global2.cxx47
-rw-r--r--sc/source/core/data/makefile.mk2
-rw-r--r--sc/source/core/data/pivot2.cxx25
-rw-r--r--sc/source/core/data/table2.cxx8
-rw-r--r--sc/source/filter/excel/read.cxx4
-rw-r--r--sc/source/filter/excel/xepivot.cxx141
-rw-r--r--sc/source/filter/excel/xestring.cxx4
-rw-r--r--sc/source/filter/excel/xiescher.cxx129
-rw-r--r--sc/source/filter/excel/xipivot.cxx173
-rw-r--r--sc/source/filter/excel/xlpivot.cxx125
-rw-r--r--sc/source/filter/inc/xepivot.hxx5
-rw-r--r--sc/source/filter/inc/xestring.hxx1
-rw-r--r--sc/source/filter/inc/xiescher.hxx2
-rw-r--r--sc/source/filter/inc/xipivot.hxx16
-rw-r--r--sc/source/filter/inc/xlpivot.hxx30
-rw-r--r--sc/source/filter/inc/xlstring.hxx1
-rw-r--r--sc/source/filter/xml/XMLExportDataPilot.cxx58
-rw-r--r--sc/source/filter/xml/XMLExportDataPilot.hxx3
-rw-r--r--sc/source/filter/xml/xmldpimp.cxx271
-rw-r--r--sc/source/filter/xml/xmldpimp.hxx67
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx22
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx47
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx19
-rw-r--r--sc/source/ui/Accessibility/AccessibleContextBase.cxx5
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterMenu.cxx401
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx208
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx137
-rw-r--r--sc/source/ui/Accessibility/AccessibleGlobal.cxx98
-rw-r--r--sc/source/ui/Accessibility/makefile.mk8
-rw-r--r--sc/source/ui/cctrl/dpcontrol.cxx1419
-rw-r--r--sc/source/ui/cctrl/dpcontrol.src82
-rw-r--r--sc/source/ui/cctrl/makefile.mk10
-rw-r--r--sc/source/ui/dbgui/makefile.mk1
-rw-r--r--sc/source/ui/dbgui/pvfundlg.cxx66
-rw-r--r--sc/source/ui/dbgui/pvlaydlg.cxx106
-rw-r--r--sc/source/ui/docshell/dbdocfun.cxx4
-rw-r--r--sc/source/ui/inc/AccessibleContextBase.hxx2
-rw-r--r--sc/source/ui/inc/dbfunc.hxx3
-rw-r--r--sc/source/ui/inc/dpcontrol.hrc43
-rw-r--r--sc/source/ui/inc/dpcontrol.hxx366
-rw-r--r--sc/source/ui/inc/gridwin.hxx25
-rw-r--r--sc/source/ui/inc/pvfundlg.hxx11
-rw-r--r--sc/source/ui/inc/pvlaydlg.hxx2
-rw-r--r--sc/source/ui/undo/undodat.cxx4
-rw-r--r--sc/source/ui/unoobj/dapiuno.cxx13
-rw-r--r--sc/source/ui/unoobj/miscuno.cxx37
-rw-r--r--sc/source/ui/view/cellsh2.cxx15
-rw-r--r--sc/source/ui/view/dbfunc.cxx18
-rw-r--r--sc/source/ui/view/dbfunc3.cxx509
-rw-r--r--sc/source/ui/view/gridwin.cxx120
-rw-r--r--sc/source/ui/view/gridwin2.cxx320
-rw-r--r--sc/source/ui/view/gridwin4.cxx30
-rw-r--r--sc/source/ui/view/makefile.mk4
-rw-r--r--sc/source/ui/view/tabview.cxx30
-rw-r--r--sc/util/makefile.mk1
89 files changed, 6701 insertions, 685 deletions
diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx
new file mode 100644
index 000000000000..76344a65ceda
--- /dev/null
+++ b/sc/inc/AccessibleFilterMenu.hxx
@@ -0,0 +1,194 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleDataPilotControl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef SC_ACCESSIBLEFILTERMENU_HXX
+#define SC_ACCESSIBLEFILTERMENU_HXX
+
+#include "AccessibleContextBase.hxx"
+#include "cppuhelper/implbase1.hxx"
+
+#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
+#include <com/sun/star/accessibility/XAccessibleText.hpp>
+#include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp>
+#include <com/sun/star/accessibility/TextSegment.hpp>
+
+#include <vector>
+
+namespace com { namespace sun { namespace star {
+ namespace accessibility {
+ struct AccessibleEventObject;
+ }
+}}}
+
+class ScDocument;
+class ScMenuFloatingWindow;
+
+typedef ::cppu::ImplHelper1<
+ ::com::sun::star::accessibility::XAccessibleSelection > ScAccessibleFilterMenu_BASE;
+
+class ScAccessibleFilterMenu :
+ public ScAccessibleContextBase,
+ public ScAccessibleFilterMenu_BASE
+{
+public:
+ explicit ScAccessibleFilterMenu(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, size_t nMenuPos, ScDocument* pDoc);
+ virtual ~ScAccessibleFilterMenu();
+
+ // XAccessibleComponent
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& rPoint )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isVisible()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL grabFocus()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getForeground()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getBackground()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleContext
+
+ virtual ::rtl::OUString SAL_CALL getAccessibleName()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleEventBroadcaster
+
+ using ScAccessibleContextBase::addEventListener;
+ using ScAccessibleContextBase::removeEventListener;
+
+ virtual void SAL_CALL
+ addEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException);
+
+ // Remove an existing event listener.
+ virtual void SAL_CALL
+ removeEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException);
+
+ // XAccessibleSelection
+
+ virtual void SAL_CALL selectAccessibleChild(sal_Int32 nChildIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int32 nChildIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL clearAccessibleSelection()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL selectAllAccessibleChildren()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::sal_Int32 SAL_CALL getSelectedAccessibleChildCount()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getSelectedAccessibleChild(sal_Int32 nChildIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL deselectAccessibleChild(sal_Int32 nChildIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ // XInterface
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
+ ::com::sun::star::uno::Type const & rType )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw ();
+ virtual void SAL_CALL release() throw ();
+
+ // XTypeProvider
+
+ virtual ::com::sun::star::uno::Sequence<sal_Int8> SAL_CALL getImplementationId()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // non-UNO methods
+
+ void appendMenuItem(const ::rtl::OUString& rName, bool bEnabled, size_t nMenuPos);
+ void setMenuPos(size_t nMenuPos);
+ void setEnabled(bool bEnabled);
+
+protected:
+
+ sal_Int32 getMenuItemCount() const;
+
+ virtual Rectangle GetBoundingBoxOnScreen() const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual Rectangle GetBoundingBox() const
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ bool isSelected() const;
+ bool isFocused() const;
+
+ void updateStates();
+
+private:
+ ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > > maMenuItems;
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > mxStateSet;
+
+ size_t mnMenuPos;
+ ScMenuFloatingWindow* mpWindow;
+ ScDocument* mpDoc;
+
+ bool mbEnabled:1;
+};
+
+#endif
diff --git a/sc/inc/AccessibleFilterMenuItem.hxx b/sc/inc/AccessibleFilterMenuItem.hxx
new file mode 100644
index 000000000000..f5ad0fd5d74b
--- /dev/null
+++ b/sc/inc/AccessibleFilterMenuItem.hxx
@@ -0,0 +1,124 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleDataPilotControl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef SC_ACCESSIBLEFILTERMENUITEM_HXX
+#define SC_ACCESSIBLEFILTERMENUITEM_HXX
+
+#include "AccessibleContextBase.hxx"
+#include "cppuhelper/implbase1.hxx"
+
+#include <com/sun/star/accessibility/XAccessibleAction.hpp>
+
+class ScMenuFloatingWindow;
+
+typedef ::cppu::ImplHelper1<
+ ::com::sun::star::accessibility::XAccessibleAction > ScAccessibleFilterMenuItem_BASE;
+
+class ScAccessibleFilterMenuItem :
+ public ScAccessibleContextBase,
+ public ScAccessibleFilterMenuItem_BASE
+{
+public:
+ explicit ScAccessibleFilterMenuItem(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const ::rtl::OUString& rName, size_t nMenuPos);
+
+ virtual ~ScAccessibleFilterMenuItem();
+
+ // XAccessibleContext
+
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleStateSet> SAL_CALL
+ getAccessibleStateSet()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XAccessibleAction
+
+ virtual ::sal_Int32 SAL_CALL getAccessibleActionCount()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL doAccessibleAction(sal_Int32 nIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ virtual ::rtl::OUString SAL_CALL getAccessibleActionDescription(sal_Int32 nIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleKeyBinding > SAL_CALL
+ getAccessibleActionKeyBinding(sal_Int32 nIndex)
+ throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+
+ // XInterface
+
+ virtual ::com::sun::star::uno::Any SAL_CALL queryInterface(
+ ::com::sun::star::uno::Type const & rType )
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL acquire() throw ();
+ virtual void SAL_CALL release() throw ();
+
+ // Non-UNO Methods
+
+ void setEnabled(bool bEnabled);
+
+protected:
+
+ virtual Rectangle GetBoundingBoxOnScreen() const
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual Rectangle GetBoundingBox() const
+ throw (::com::sun::star::uno::RuntimeException);
+
+private:
+ bool isSelected() const;
+ bool isFocused() const;
+ void updateStateSet();
+
+private:
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > mxStateSet;
+
+ ScMenuFloatingWindow* mpWindow;
+ ::rtl::OUString maName;
+ size_t mnMenuPos;
+ bool mbEnabled;
+};
+
+#endif
diff --git a/sc/inc/AccessibleFilterTopWindow.hxx b/sc/inc/AccessibleFilterTopWindow.hxx
new file mode 100644
index 000000000000..e901949286a1
--- /dev/null
+++ b/sc/inc/AccessibleFilterTopWindow.hxx
@@ -0,0 +1,104 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleDataPilotControl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef SC_ACCESSIBLEFILTERTOPWINDOW_HXX
+#define SC_ACCESSIBLEFILTERTOPWINDOW_HXX
+
+//#include "AccessibleContextBase.hxx"
+#include "AccessibleFilterMenu.hxx"
+#include "cppuhelper/implbase1.hxx"
+
+class ScDPFieldPopupWindow;
+class ScDocument;
+
+class ScAccessibleFilterTopWindow : public ScAccessibleFilterMenu
+{
+public:
+ ScAccessibleFilterTopWindow(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible>& rxParent,
+ ScDPFieldPopupWindow* pWin, const ::rtl::OUString& rName, ScDocument* pDoc);
+ virtual ~ScAccessibleFilterTopWindow();
+
+ // XAccessibleContext
+
+ virtual sal_Int32 SAL_CALL getAccessibleChildCount()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> SAL_CALL
+ getAccessibleChild(sal_Int32 nIndex)
+ throw (::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IndexOutOfBoundsException);
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // Non-UNO Methods
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ getAccessibleChildMenu();
+
+ enum ChildControlType {
+ LISTBOX, TOGGLE_ALL, SINGLE_ON_BTN, SINGLE_OFF_BTN, OK_BTN, CANCEL_BTN
+ };
+ void setAccessibleChild(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible >& rAccessible,
+ ChildControlType eType);
+
+private:
+ /** The top menu part */
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ mxAccMenu;
+
+ /** check list box for field member visibility */
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ mxAccListBox;
+
+ /** check box for toggling all field member's visibility. */
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ mxAccToggleAll;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ mxAccSingleOnBtn;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ mxAccSingleOffBtn;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ mxAccOkBtn;
+
+ ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
+ mxAccCancelBtn;
+
+ ScDPFieldPopupWindow* mpWindow;
+ ScDocument* mpDoc;
+};
+
+#endif
diff --git a/sc/inc/AccessibleGlobal.hxx b/sc/inc/AccessibleGlobal.hxx
new file mode 100644
index 000000000000..9f17c2eaacae
--- /dev/null
+++ b/sc/inc/AccessibleGlobal.hxx
@@ -0,0 +1,72 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleDataPilotControl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef SC_ACCESSIBLEGLOBAL_HXX
+#define SC_ACCESSIBLEGLOBAL_HXX
+
+#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
+#include "cppuhelper/implbase1.hxx"
+
+#include <set>
+
+/**
+ * Generic XAccessibleStateSet implementation.
+ */
+class ScAccessibleStateSet : public ::cppu::WeakImplHelper1< ::com::sun::star::accessibility::XAccessibleStateSet >
+{
+public:
+ ScAccessibleStateSet();
+ virtual ~ScAccessibleStateSet();
+
+ // XAccessibleStateSet
+
+ virtual ::sal_Bool SAL_CALL isEmpty()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL contains(sal_Int16 nState)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL containsAll(
+ const ::com::sun::star::uno::Sequence<sal_Int16>& aStateSet)
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual ::com::sun::star::uno::Sequence<sal_Int16> SAL_CALL getStates()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // Non-UNO Methods
+
+ void insert(sal_Int16 nState);
+ void clear();
+
+private:
+ ::std::set<sal_Int16> maStates;
+};
+
+#endif
diff --git a/sc/inc/attrib.hxx b/sc/inc/attrib.hxx
index 55bb707f4edb..9db8b4001690 100644
--- a/sc/inc/attrib.hxx
+++ b/sc/inc/attrib.hxx
@@ -42,13 +42,16 @@
// Flags fuer durch Merge verdeckte Zellen
// und Control fuer Auto-Filter
-#define SC_MF_HOR 1
-#define SC_MF_VER 2
-#define SC_MF_AUTO 4
-#define SC_MF_BUTTON 8
-#define SC_MF_SCENARIO 16
+#define SC_MF_HOR 0x0001
+#define SC_MF_VER 0x0002
+#define SC_MF_AUTO 0x0004 /// autofilter arrow
+#define SC_MF_BUTTON 0x0008 /// field button for datapilot
+#define SC_MF_SCENARIO 0x0010
+#define SC_MF_BUTTON_POPUP 0x0020 /// dp button with popup arrow
+#define SC_MF_HIDDEN_MEMBER 0x0040 /// dp field button with presence of hidden member
+#define SC_MF_DP_TABLE 0x0080 /// dp table output
-#define SC_MF_ALL 31
+#define SC_MF_ALL 0x00FF
class EditTextObject;
@@ -103,6 +106,7 @@ public:
BOOL HasAutoFilter() const { return ( GetValue() & SC_MF_AUTO ) != 0; }
BOOL HasButton() const { return ( GetValue() & SC_MF_BUTTON ) != 0; }
+ bool HasDPTable() const { return ( GetValue() & SC_MF_DP_TABLE ) != 0; }
BOOL IsScenario() const { return ( GetValue() & SC_MF_SCENARIO ) != 0; }
};
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 3f1fbfc1c88f..b69fcb384e04 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -161,7 +161,7 @@ public:
SCSIZE GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const;
BOOL HasDataAt(SCROW nRow) const;
BOOL HasVisibleDataAt(SCROW nRow) const;
-//UNUSED2009-05 SCROW GetFirstDataPos() const;
+ SCROW GetFirstDataPos() const;
SCROW GetLastDataPos() const;
SCROW GetLastVisDataPos(BOOL bNotes) const; // ohne Broadcaster
SCROW GetFirstVisDataPos(BOOL bNotes) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 116d25ee901e..cc575b529d73 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -866,6 +866,8 @@ public:
USHORT GetErrCode( const ScAddress& ) const;
+ bool ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const;
+
void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld );
SC_DLLPUBLIC BOOL GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const;
diff --git a/sc/inc/dpgroup.hxx b/sc/inc/dpgroup.hxx
index 99dac0e517db..cb933f4d2a98 100644
--- a/sc/inc/dpgroup.hxx
+++ b/sc/inc/dpgroup.hxx
@@ -33,6 +33,7 @@
#include <vector>
#include <hash_set>
+#include <boost/shared_ptr.hpp>
#include "dptabdat.hxx"
#include "scdllapi.h"
@@ -182,7 +183,7 @@ class ScDPGroupTableData : public ScDPTableData
{
typedef ::std::hash_set< ::rtl::OUString, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > StringHashSet;
- ScDPTableData* pSourceData;
+ ::boost::shared_ptr<ScDPTableData> pSourceData;
long nSourceCount;
ScDPGroupDimensionVec aGroups;
ScDPNumGroupDimension* pNumGroups; // array[nSourceCount]
@@ -200,7 +201,7 @@ class ScDPGroupTableData : public ScDPTableData
public:
// takes ownership of pSource
- ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument );
+ ScDPGroupTableData( const ::boost::shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument );
virtual ~ScDPGroupTableData();
void AddGroupDimension( const ScDPGroupDimension& rGroup );
diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx
index 2dc8829485c8..ef7a2c491c50 100644
--- a/sc/inc/dpobject.hxx
+++ b/sc/inc/dpobject.hxx
@@ -36,8 +36,11 @@
#include "address.hxx"
#include "collect.hxx"
#include "dpoutput.hxx"
+#include "pivot.hxx"
#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
+#include <boost/shared_ptr.hpp>
+
//------------------------------------------------------------------
namespace com { namespace sun { namespace star { namespace sheet {
@@ -64,6 +67,7 @@ class ScStrCollection;
class TypedScStrCollection;
struct PivotField;
class ScDPCacheTable;
+class ScDPTableData;
struct ScDPServiceDesc
{
@@ -99,15 +103,19 @@ private:
ScSheetSourceDesc* pSheetDesc; // for sheet data
ScImportSourceDesc* pImpDesc; // for database data
ScDPServiceDesc* pServDesc; // for external service
+ ::boost::shared_ptr<ScDPTableData> mpTableData;
// cached data
com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier> xSource;
ScDPOutput* pOutput;
BOOL bSettingsChanged;
BOOL bAlive; // FALSE if only used to hold settings
+ sal_uInt16 mnAutoFormatIndex;
BOOL bAllowMove;
long nHeaderRows; // page fields plus filter button
+ bool mbHeaderLayout; // TRUE : grid, FALSE : standard
+ SC_DLLPRIVATE ScDPTableData* GetTableData();
SC_DLLPRIVATE void CreateObjects();
SC_DLLPRIVATE void CreateOutput();
@@ -135,6 +143,12 @@ public:
void SetOutRange(const ScRange& rRange);
const ScRange& GetOutRange() const { return aOutRange; }
+ void SetAutoFormatIndex (const sal_uInt16 nIndex);
+ sal_uInt16 GetAutoFormatIndex() const;
+
+ void SetHeaderLayout(bool bUseGrid);
+ bool GetHeaderLayout() const;
+
void SetSheetDesc(const ScSheetSourceDesc& rDesc);
void SetImportDesc(const ScImportSourceDesc& rDesc);
void SetServiceData(const ScDPServiceDesc& rDesc);
@@ -157,7 +171,14 @@ public:
void SetTag(const String& rNew);
const String& GetTag() const { return aTableTag; }
- BOOL IsDimNameInUse( const String& rName ) const;
+ /**
+ * Data description cell displays the description of a data dimension if
+ * and only if there is only one data dimension. It's usually located at
+ * the upper-left corner of the table output.
+ */
+ bool IsDataDescriptionCell(const ScAddress& rPos);
+
+ bool IsDimNameInUse(const ::rtl::OUString& rName) const;
String GetDimName( long nDim, BOOL& rIsDataLayout );
BOOL IsDuplicated( long nDim );
long GetDimCount();
@@ -190,16 +211,10 @@ public:
sal_Int32 GetUsedHierarchy( sal_Int32 nDim );
BOOL GetMembersNA( sal_Int32 nDim, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers );
- BOOL GetMembers( sal_Int32 nDim,
- com::sun::star::uno::Sequence< rtl::OUString >& rMembers,
- com::sun::star::uno::Sequence< sal_Bool >* pVisible = 0,
- com::sun::star::uno::Sequence< sal_Bool >* pShowDet = 0 );
-
BOOL GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, com::sun::star::uno::Reference< com::sun::star::container::XNameAccess >& xMembers );
- BOOL GetMembers( sal_Int32 nDim, sal_Int32 nHier,
- com::sun::star::uno::Sequence< rtl::OUString >& rMembers,
- com::sun::star::uno::Sequence< sal_Bool >* pVisible = 0,
- com::sun::star::uno::Sequence< sal_Bool >* pShowDet = 0 );
+
+ bool GetMemberNames( sal_Int32 nDim, ::com::sun::star::uno::Sequence< ::rtl::OUString >& rNames );
+ bool GetMembers( sal_Int32 nDim, sal_Int32 nHier, ::std::vector<ScDPLabelData::Member>& rMembers );
void UpdateReference( UpdateRefMode eUpdateRefMode,
const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
@@ -221,6 +236,8 @@ public:
// (button attribute must be present)
void RefreshAfterLoad();
+ void BuildAllDimensionMembers();
+
static BOOL HasRegisteredSources();
static com::sun::star::uno::Sequence<rtl::OUString> GetRegisteredSources();
static com::sun::star::uno::Reference<com::sun::star::sheet::XDimensionsSupplier>
@@ -291,6 +308,11 @@ public:
ScSimpleSharedString& GetSharedString();
+ void FreeTable(ScDPObject* pDPObj);
+ SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj);
+
+ bool HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const;
+
ScDPCacheCell* getCacheCellFromPool(const ScDPCacheCell& rCell);
void clearCacheCellPool();
};
diff --git a/sc/inc/dpoutput.hxx b/sc/inc/dpoutput.hxx
index 58001e1183a6..e3ab86423d4b 100644
--- a/sc/inc/dpoutput.hxx
+++ b/sc/inc/dpoutput.hxx
@@ -94,6 +94,7 @@ private:
com::sun::star::uno::Sequence<
com::sun::star::sheet::DataResult> > aData;
BOOL bResultsError;
+ bool mbHasDataLayout;
String aDataDescription;
// Number format related parameters
@@ -109,6 +110,7 @@ private:
long nColCount;
long nRowCount;
long nHeaderSize;
+ bool mbHeaderLayout; // TRUE : grid, FALSE : standard
SCCOL nTabStartCol;
SCROW nTabStartRow;
SCCOL nMemberStartCol;
@@ -124,7 +126,7 @@ private:
const com::sun::star::sheet::MemberResult& rData,
BOOL bColHeader, long nLevel );
void FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption,
- BOOL bFrame = TRUE );
+ bool bInTable, bool bPopup, bool bHasHiddenMember );
void CalcSizes();
/** Query which sub-area of the table the cell is in. See
@@ -162,6 +164,9 @@ public:
void GetMemberResultNames( ScStrCollection& rNames, long nDimension );
+ void SetHeaderLayout(bool bUseGrid);
+ bool GetHeaderLayout() const;
+
static void GetDataDimensionNames( String& rSourceName, String& rGivenName,
const com::sun::star::uno::Reference<
com::sun::star::uno::XInterface>& xDim );
diff --git a/sc/inc/dpoutputgeometry.hxx b/sc/inc/dpoutputgeometry.hxx
new file mode 100644
index 000000000000..b665c9cc88b4
--- /dev/null
+++ b/sc/inc/dpoutputgeometry.hxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmldpimp.cxx,v $
+ * $Revision: 1.27.134.1 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef SC_DPOUTPUTGEOMETRY_HXX
+#define SC_DPOUTPUTGEOMETRY_HXX
+
+#include "address.hxx"
+#include <vector>
+
+class ScAddress;
+
+class SC_DLLPUBLIC ScDPOutputGeometry
+{
+public:
+ enum FieldType { Column, Row, Page, Data, None };
+ enum ImportType { ODF, XLS };
+
+ ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter, ImportType eImportType);
+ ~ScDPOutputGeometry();
+
+ /**
+ * @param nCount number of row fields, <b>excluding the data layout
+ * field if exists</b>.
+ */
+ void setRowFieldCount(sal_uInt32 nCount);
+ void setColumnFieldCount(sal_uInt32 nCount);
+ void setPageFieldCount(sal_uInt32 nCount);
+ void setDataFieldCount(sal_uInt32 nCount);
+
+ void getColumnFieldPositions(::std::vector<ScAddress>& rAddrs) const;
+ void getRowFieldPositions(::std::vector<ScAddress>& rAddrs) const;
+ void getPageFieldPositions(::std::vector<ScAddress>& rAddrs) const;
+
+ SCROW getRowFieldHeaderRow() const;
+
+ FieldType getFieldButtonType(const ScAddress& rPos) const;
+
+private:
+ ScDPOutputGeometry(); // disabled
+
+private:
+ ScRange maOutRange;
+ sal_uInt32 mnRowFields; /// number of row fields (data layout field NOT included!)
+ sal_uInt32 mnColumnFields;
+ sal_uInt32 mnPageFields;
+ sal_uInt32 mnDataFields;
+
+ ImportType meImportType;
+
+ bool mbShowFilter;
+};
+
+#endif
diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx
index d3d8d4354145..86093ac8614b 100644
--- a/sc/inc/dpsave.hxx
+++ b/sc/inc/dpsave.hxx
@@ -34,9 +34,11 @@
#include <tools/string.hxx>
#include <tools/list.hxx>
#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include "scdllapi.h"
#include <hash_map>
#include <list>
+#include <memory>
namespace com { namespace sun { namespace star { namespace sheet {
struct DataPilotFieldReference;
@@ -46,6 +48,7 @@ namespace com { namespace sun { namespace star { namespace sheet {
} } } }
class ScDPDimensionSaveData;
+class ScDPTableData;
// --------------------------------------------------------------------
//
@@ -57,6 +60,7 @@ class ScDPSaveMember
{
private:
String aName;
+ ::std::auto_ptr<rtl::OUString> mpLayoutName; // custom name to be displayed in the table.
USHORT nVisibleMode;
USHORT nShowDetailsMode;
@@ -77,18 +81,23 @@ public:
void SetName( const String& rNew ); // used if the source member was renamed (groups)
+ SC_DLLPUBLIC void SetLayoutName( const ::rtl::OUString& rName );
+ SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const;
+ void RemoveLayoutName();
+
void WriteToSource( const com::sun::star::uno::Reference<
com::sun::star::uno::XInterface>& xMember,
sal_Int32 nPosition );
};
-class ScDPSaveDimension
+class SC_DLLPUBLIC ScDPSaveDimension
{
private:
String aName;
- String* pLayoutName; // alternative name for layout, not used (yet)
String* pSelectedPage;
+ ::std::auto_ptr<rtl::OUString> mpLayoutName;
+ ::std::auto_ptr<rtl::OUString> mpSubtotalName;
BOOL bIsDataLayout;
BOOL bDupFlag;
USHORT nOrientation;
@@ -127,43 +136,52 @@ public:
void SetName( const String& rNew ); // used if the source dim was renamed (groups)
- SC_DLLPUBLIC void SetOrientation(USHORT nNew);
- SC_DLLPUBLIC void SetSubTotals(long nCount, const USHORT* pFuncs);
+ void SetOrientation(USHORT nNew);
+ void SetSubTotals(long nCount, const USHORT* pFuncs);
long GetSubTotalsCount() const { return nSubTotalCount; }
USHORT GetSubTotalFunc(long nIndex) const { return pSubTotalFuncs[nIndex]; }
- SC_DLLPUBLIC void SetShowEmpty(BOOL bSet);
+ void SetShowEmpty(BOOL bSet);
BOOL GetShowEmpty() const { return BOOL(nShowEmptyMode); }
- SC_DLLPUBLIC void SetFunction(USHORT nNew); // enum GeneralFunction
+ void SetFunction(USHORT nNew); // enum GeneralFunction
USHORT GetFunction() const { return nFunction; }
void SetUsedHierarchy(long nNew);
long GetUsedHierarchy() const { return nUsedHierarchy; }
- SC_DLLPUBLIC void SetLayoutName(const String* pName);
- SC_DLLPUBLIC const String& GetLayoutName() const;
- SC_DLLPUBLIC BOOL HasLayoutName() const;
+
+ void SetLayoutName(const ::rtl::OUString& rName);
+ const ::rtl::OUString* GetLayoutName() const;
+ void RemoveLayoutName();
+ void SetSubtotalName(const ::rtl::OUString& rName);
+ const ::rtl::OUString* GetSubtotalName() const;
+
+ bool IsMemberNameInUse(const ::rtl::OUString& rName) const;
const ::com::sun::star::sheet::DataPilotFieldReference* GetReferenceValue() const { return pReferenceValue; }
- SC_DLLPUBLIC void SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew);
+ void SetReferenceValue(const ::com::sun::star::sheet::DataPilotFieldReference* pNew);
const ::com::sun::star::sheet::DataPilotFieldSortInfo* GetSortInfo() const { return pSortInfo; }
- SC_DLLPUBLIC void SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew);
+ void SetSortInfo(const ::com::sun::star::sheet::DataPilotFieldSortInfo* pNew);
const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* GetAutoShowInfo() const { return pAutoShowInfo; }
- SC_DLLPUBLIC void SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew);
+ void SetAutoShowInfo(const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo* pNew);
const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* GetLayoutInfo() const { return pLayoutInfo; }
- SC_DLLPUBLIC void SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew);
+ void SetLayoutInfo(const ::com::sun::star::sheet::DataPilotFieldLayoutInfo* pNew);
- SC_DLLPUBLIC void SetCurrentPage( const String* pPage ); // NULL = no selection (all)
- SC_DLLPUBLIC BOOL HasCurrentPage() const;
- SC_DLLPUBLIC const String& GetCurrentPage() const;
+ void SetCurrentPage( const String* pPage ); // NULL = no selection (all)
+ BOOL HasCurrentPage() const;
+ const String& GetCurrentPage() const;
USHORT GetOrientation() const { return nOrientation; }
ScDPSaveMember* GetExistingMemberByName(const String& rName);
- SC_DLLPUBLIC ScDPSaveMember* GetMemberByName(const String& rName);
+ ScDPSaveMember* GetMemberByName(const String& rName);
void SetMemberPosition( const String& rName, sal_Int32 nNewPos );
void WriteToSource( const com::sun::star::uno::Reference<
com::sun::star::uno::XInterface>& xDim );
+
+ void UpdateMemberVisibility(const ::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rData);
+
+ bool HasInvisibleMember() const;
};
@@ -179,6 +197,12 @@ private:
BOOL bFilterButton; // not passed to DataPilotSource
BOOL bDrillDown; // not passed to DataPilotSource
+ /** if true, all dimensions already have all of their member instances
+ * created. */
+ bool mbDimensionMembersBuilt;
+
+ ::std::auto_ptr<rtl::OUString> mpGrandTotalName;
+
public:
SC_DLLPUBLIC ScDPSaveData();
ScDPSaveData(const ScDPSaveData& r);
@@ -188,21 +212,26 @@ public:
BOOL operator== ( const ScDPSaveData& r ) const;
+ SC_DLLPUBLIC void SetGrandTotalName(const ::rtl::OUString& rName);
+ SC_DLLPUBLIC const ::rtl::OUString* GetGrandTotalName() const;
+
const List& GetDimensions() const { return aDimList; }
void AddDimension(ScDPSaveDimension* pDim) { aDimList.Insert(pDim, LIST_APPEND); }
ScDPSaveDimension* GetDimensionByName(const String& rName);
SC_DLLPUBLIC ScDPSaveDimension* GetDataLayoutDimension();
+ SC_DLLPUBLIC ScDPSaveDimension* GetExistingDataLayoutDimension() const;
ScDPSaveDimension* DuplicateDimension(const String& rName);
SC_DLLPUBLIC ScDPSaveDimension& DuplicateDimension(const ScDPSaveDimension& rDim);
- SC_DLLPUBLIC ScDPSaveDimension* GetExistingDimensionByName(const String& rName);
+ SC_DLLPUBLIC ScDPSaveDimension* GetExistingDimensionByName(const String& rName) const;
SC_DLLPUBLIC ScDPSaveDimension* GetNewDimensionByName(const String& rName);
void RemoveDimensionByName(const String& rName);
ScDPSaveDimension* GetInnermostDimension(USHORT nOrientation);
+ ScDPSaveDimension* GetFirstDimension(::com::sun::star::sheet::DataPilotFieldOrientation eOrientation);
long GetDataDimensionCount() const;
@@ -229,6 +258,14 @@ public:
const ScDPDimensionSaveData* GetExistingDimensionData() const { return pDimensionData; }
SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there
void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied
+ void BuildAllDimensionMembers(ScDPTableData* pData);
+
+ /**
+ * Check whether a dimension has one or more invisible members.
+ *
+ * @param rDimName dimension name
+ */
+ SC_DLLPUBLIC bool HasInvisibleMember(const ::rtl::OUString& rDimName) const;
};
diff --git a/sc/inc/dptabres.hxx b/sc/inc/dptabres.hxx
index b18ea8e56b76..a2574820da4a 100644
--- a/sc/inc/dptabres.hxx
+++ b/sc/inc/dptabres.hxx
@@ -41,6 +41,7 @@
#include <hash_map>
#include <hash_set>
#include <vector>
+#include <memory>
namespace com { namespace sun { namespace star { namespace sheet {
struct DataPilotFieldReference;
@@ -262,7 +263,7 @@ public:
long GetMeasureCount() const { return nMeasCount; }
ScSubTotalFunc GetMeasureFunction(long nMeasure) const;
- String GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc) const;
+ String GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const;
String GetMeasureDimensionName(long nMeasure) const;
const ::com::sun::star::sheet::DataPilotFieldReference& GetMeasureRefVal(long nMeasure) const;
USHORT GetMeasureRefOrient(long nMeasure) const;
@@ -284,6 +285,8 @@ public:
const ScDPItemData& rBaseData, long nBaseIndex ) const;
BOOL HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex,
const ScDPItemData& rSecondData, long nSecondIndex ) const;
+
+ const ScDPSource* GetSource() const;
};
diff --git a/sc/inc/dptabsrc.hxx b/sc/inc/dptabsrc.hxx
index 3b1d8e0e206e..94229f5b1d35 100644
--- a/sc/inc/dptabsrc.hxx
+++ b/sc/inc/dptabsrc.hxx
@@ -33,6 +33,7 @@
#include <vector>
#include <hash_map>
+#include <memory>
#include <tools/string.hxx>
#include <tools/list.hxx>
#include "global.hxx" // enum ScSubTotalFunc
@@ -108,7 +109,7 @@ class ScDPSource : public cppu::WeakImplHelper6<
com::sun::star::lang::XServiceInfo >
{
private:
- ScDPTableData* pData; // data source
+ ScDPTableData* pData; // data source (ScDPObject manages its life time)
ScDPDimensions* pDimensions; // api objects
// settings:
long nColDims[SC_DAPI_MAXFIELDS];
@@ -136,6 +137,8 @@ private:
List aRowLevelList;
BOOL bResultOverflow;
+ ::std::auto_ptr<rtl::OUString> mpGrandTotalName;
+
void CreateRes_Impl();
void FillMemberResults();
void FillLevelList( USHORT nOrientation, List& rList );
@@ -162,11 +165,15 @@ public:
ScDPTableData* GetData() { return pData; }
const ScDPTableData* GetData() const { return pData; }
+ void SetGrandTotalName(const ::rtl::OUString& rName);
+ const ::rtl::OUString* GetGrandTotalName() const;
+
USHORT GetOrientation(long nColumn);
void SetOrientation(long nColumn, USHORT nNew);
long GetPosition(long nColumn);
long GetDataDimensionCount();
+ ScDPDimension* GetDataDimension(long nIndex);
String GetDataDimName(long nIndex);
BOOL IsDataLayoutDimension(long nDim);
USHORT GetDataLayoutOrientation();
@@ -333,12 +340,15 @@ private:
long nUsedHier;
USHORT nFunction; // enum GeneralFunction
String aName; // if empty, take from source
+ ::std::auto_ptr<rtl::OUString> mpLayoutName;
+ ::std::auto_ptr<rtl::OUString> mpSubtotalName;
long nSourceDim; // >=0 if dup'ed
::com::sun::star::sheet::DataPilotFieldReference
aReferenceValue; // settings for "show data as" / "displayed value"
BOOL bHasSelectedPage;
String aSelectedPage;
ScDPItemData* pSelectedData; // internal, temporary, created from aSelectedPage
+ sal_Bool mbHasHiddenMember;
public:
ScDPDimension( ScDPSource* pSrc, long nD );
@@ -350,6 +360,9 @@ public:
ScDPDimension* CreateCloneObject();
ScDPHierarchies* GetHierarchiesObject();
+ SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const;
+ const ::rtl::OUString* GetSubtotalName() const;
+
// XNamed
virtual ::rtl::OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
virtual void SAL_CALL setName( const ::rtl::OUString& aName )
@@ -736,7 +749,7 @@ private:
long nLev;
ScDPItemData maData;
-// String aCaption; // visible name (changeable by user)
+ ::std::auto_ptr<rtl::OUString> mpLayoutName;
sal_Int32 nPosition; // manual sorting
BOOL bVisible;
@@ -750,6 +763,7 @@ public:
BOOL IsNamedItem( const ScDPItemData& r ) const;
String GetNameStr() const;
void FillItemData( ScDPItemData& rData ) const;
+ SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const;
sal_Int32 Compare( const ScDPMember& rOther ) const; // visible order
diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx
index b6d48254d06a..d0be5b0cb897 100644
--- a/sc/inc/fillinfo.hxx
+++ b/sc/inc/fillinfo.hxx
@@ -99,6 +99,8 @@ struct CellInfo
BOOL bVOverlapped : 1;
BOOL bAutoFilter : 1;
BOOL bPushButton : 1;
+ bool bPopupButton: 1;
+ bool bFilterActive:1;
BOOL bPrinted : 1; // bei Bedarf (Pagebreak-Modus)
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index 1f6dc13d04ce..c938968ddfef 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -87,8 +87,6 @@ extern "C" {
#endif
//------------------------------------------------------------------------
-struct LabelData;
-//------------------------------------------------------------------------
// die 1000 Namen des Calc...
// Clipboard-Namen sind jetzt in so3/soapp.hxx
diff --git a/sc/inc/miscuno.hxx b/sc/inc/miscuno.hxx
index 1486d3ce480b..df60b2822cb8 100644
--- a/sc/inc/miscuno.hxx
+++ b/sc/inc/miscuno.hxx
@@ -285,12 +285,29 @@ public:
static sal_Int32 GetEnumProperty( const com::sun::star::uno::Reference<
com::sun::star::beans::XPropertySet>& xProp,
const ::rtl::OUString& rName, long nDefault );
+ static ::rtl::OUString GetStringProperty(
+ const com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xProp,
+ const ::rtl::OUString& rName, const ::rtl::OUString& rDefault );
static sal_Bool GetBoolFromAny( const com::sun::star::uno::Any& aAny );
static sal_Int16 GetInt16FromAny( const com::sun::star::uno::Any& aAny );
static sal_Int32 GetInt32FromAny( const com::sun::star::uno::Any& aAny );
static sal_Int32 GetEnumFromAny( const com::sun::star::uno::Any& aAny );
static void SetBoolInAny( com::sun::star::uno::Any& rAny, sal_Bool bValue );
+
+ static void SetOptionalPropertyValue(
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rPropSet,
+ const sal_Char* pPropName, const ::com::sun::star::uno::Any& rVal );
+
+ template<typename ValueType>
+ static void SetOptionalPropertyValue(
+ ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& rPropSet,
+ const sal_Char* pPropName, const ValueType& rVal )
+ {
+ ::com::sun::star::uno::Any any;
+ any <<= rVal;
+ SetOptionalPropertyValue(rPropSet, pPropName, any);
+ }
};
diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx
index e77dd60f18bb..100463cb5542 100644
--- a/sc/inc/pivot.hxx
+++ b/sc/inc/pivot.hxx
@@ -53,6 +53,7 @@
#include "address.hxx"
#include <vector>
+#include <boost/shared_ptr.hpp>
class SubTotal;
#include "collect.hxx"
@@ -69,7 +70,9 @@ class SvStream;
class ScDocument;
class ScUserListData;
class ScProgress;
-struct LabelData;
+struct ScDPLabelData;
+
+typedef ::boost::shared_ptr<ScDPLabelData> ScDPLabelDataRef;
// -----------------------------------------------------------------------
@@ -93,8 +96,7 @@ struct ScPivotParam
SCCOL nCol; // Cursor Position /
SCROW nRow; // bzw. Anfang des Zielbereiches
SCTAB nTab;
- LabelData** ppLabelArr;
- SCSIZE nLabels;
+ ::std::vector<ScDPLabelDataRef> maLabelArray;
PivotField aPageArr[PIVOT_MAXPAGEFIELD];
PivotField aColArr[PIVOT_MAXFIELD];
PivotField aRowArr[PIVOT_MAXFIELD];
@@ -115,10 +117,8 @@ struct ScPivotParam
ScPivotParam& operator= ( const ScPivotParam& r );
BOOL operator== ( const ScPivotParam& r ) const;
//UNUSED2009-05 void Clear ();
- void ClearLabelData ();
void ClearPivotArrays();
- void SetLabelData ( LabelData** ppLabArr,
- SCSIZE nLab );
+ void SetLabelData (const ::std::vector<ScDPLabelDataRef>& r);
void SetPivotArrays ( const PivotField* pPageArr,
const PivotField* pColArr,
const PivotField* pRowArr,
@@ -136,24 +136,45 @@ typedef PivotField PivotPageFieldArr[PIVOT_MAXPAGEFIELD];
//------------------------------------------------------------------------
-struct LabelData
+struct ScDPLabelData
{
- String maName; /// Visible name of the dimension.
+ ::rtl::OUString maName; /// Original name of the dimension.
+ ::rtl::OUString maLayoutName; /// Layout name (display name)
SCsCOL mnCol;
USHORT mnFuncMask; /// Page/Column/Row subtotal function.
sal_Int32 mnUsedHier; /// Used hierarchy.
bool mbShowAll; /// true = Show all (also empty) results.
bool mbIsValue; /// true = Sum or count in data field.
+ struct Member
+ {
+ ::rtl::OUString maName;
+ ::rtl::OUString maLayoutName;
+ bool mbVisible;
+ bool mbShowDetails;
+
+ Member();
+
+ /**
+ * return the name that should be displayed in the dp dialogs i.e.
+ * when the layout name is present, use it, or else use the original
+ * name.
+ */
+ ::rtl::OUString SC_DLLPUBLIC getDisplayName() const;
+ };
+ ::std::vector<Member> maMembers;
::com::sun::star::uno::Sequence< ::rtl::OUString > maHiers; /// Hierarchies.
- ::com::sun::star::uno::Sequence< ::rtl::OUString > maMembers; /// Members.
- ::com::sun::star::uno::Sequence< sal_Bool > maVisible; /// Visibility of members.
- ::com::sun::star::uno::Sequence< sal_Bool > maShowDet; /// Show details of members.
::com::sun::star::sheet::DataPilotFieldSortInfo maSortInfo; /// Sorting info.
::com::sun::star::sheet::DataPilotFieldLayoutInfo maLayoutInfo; /// Layout info.
::com::sun::star::sheet::DataPilotFieldAutoShowInfo maShowInfo; /// AutoShow info.
- explicit LabelData( const String& rName, short nCol, bool bIsValue );
+ explicit ScDPLabelData( const String& rName, short nCol, bool bIsValue );
+
+ /**
+ * return the name that should be displayed in the dp dialogs i.e. when
+ * the layout name is present, use it, or else use the original name.
+ */
+ ::rtl::OUString SC_DLLPUBLIC getDisplayName() const;
};
// ============================================================================
@@ -171,7 +192,6 @@ struct ScDPFuncData
// ============================================================================
-typedef LabelData ScDPLabelData;
typedef std::vector< ScDPLabelData > ScDPLabelDataVec;
typedef std::vector< String > ScDPNameVec;
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index 8d3304867f78..62114c892ec3 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -1441,6 +1441,8 @@
#define RID_IMG_H_DROP_URL (BMP_START + 5)
#define RID_IMG_H_DROP_LINK (BMP_START + 6)
#define RID_IMG_H_DROP_COPY (BMP_START + 7)
+#define RID_IMG_SELECT_CURRENT (BMP_START + 8)
+#define RID_IMG_UNSELECT_CURRENT (BMP_START + 9)
#define RID_SCPTR_PIVOTCOL (BMP_START + 81)
#define RID_SCPTR_PIVOTROW (BMP_START + 82)
@@ -1632,8 +1634,9 @@
#define RID_SCDLG_DOCPROTECTION (SC_DIALOGS_START + 149)
#define RID_SCDLG_RETYPEPASS (SC_DIALOGS_START + 150)
#define RID_SCDLG_RETYPEPASS_INPUT (SC_DIALOGS_START + 151)
+#define RID_POPUP_FILTER (SC_DIALOGS_START + 152)
-#define SC_DIALOGS_END (SC_DIALOGS_START + 152)
+#define SC_DIALOGS_END (SC_DIALOGS_START + 153)
#ifndef STD_MASKCOLOR
#define STD_MASKCOLOR Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; }
diff --git a/sc/inc/scabstdlg.hxx b/sc/inc/scabstdlg.hxx
index 94084aab4f1b..ba62b9a5de06 100644
--- a/sc/inc/scabstdlg.hxx
+++ b/sc/inc/scabstdlg.hxx
@@ -238,7 +238,7 @@ class AbstractScDPSubtotalDlg : public VclAbstractDialog //add for ScDPSubtotal
{
public:
virtual USHORT GetFuncMask() const = 0;
- virtual void FillLabelData( LabelData& rLabelData ) const = 0;
+ virtual void FillLabelData( ScDPLabelData& rLabelData ) const = 0;
};
class AbstractScDPNumGroupDlg : public VclAbstractDialog
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 9fda5d522fdc..f400054d00b7 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -294,6 +294,7 @@ public:
}
ScBaseCell* GetCell( SCCOL nCol, SCROW nRow ) const;
+ void GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const;
void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const;
/** Returns the pointer to a cell note object at the passed cell address. */
diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx
index 010e420feb42..18829290eb93 100644
--- a/sc/inc/unonames.hxx
+++ b/sc/inc/unonames.hxx
@@ -561,6 +561,10 @@
#define SC_UNO_ROWFIELDCOUNT "RowFieldCount"
#define SC_UNO_COLUMNFIELDCOUNT "ColumnFieldCount"
#define SC_UNO_DATAFIELDCOUNT "DataFieldCount"
+#define SC_UNO_LAYOUTNAME "LayoutName"
+#define SC_UNO_FIELD_SUBTOTALNAME "FieldSubtotalName"
+#define SC_UNO_GRANDTOTAL_NAME "GrandTotalName"
+#define SC_UNO_HAS_HIDDEN_MEMBER "HasHiddenMember"
// (preliminary:)
#define SC_UNO_REFVALUE "ReferenceValue"
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index 590f278901d6..a4875ba4d1e3 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -2117,7 +2117,8 @@ void ScAttrArray::InsertRow( SCROW nStartRow, SCSIZE nSize )
}
// Don't duplicate the merge flags in the inserted row.
- RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_ALL );
+ // #i108488# SC_MF_SCENARIO has to be allowed.
+ RemoveFlags( nStartRow, nStartRow+nSize-1, SC_MF_HOR | SC_MF_VER | SC_MF_AUTO | SC_MF_BUTTON );
}
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 4205c0f59dcc..3da3d3810f0b 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1376,13 +1376,13 @@ SCSIZE ScColumn::GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirecti
return nLines;
}
-//UNUSED2009-05 SCROW ScColumn::GetFirstDataPos() const
-//UNUSED2009-05 {
-//UNUSED2009-05 if (nCount)
-//UNUSED2009-05 return pItems[0].nRow;
-//UNUSED2009-05 else
-//UNUSED2009-05 return 0;
-//UNUSED2009-05 }
+SCROW ScColumn::GetFirstDataPos() const
+{
+ if (nCount)
+ return pItems[0].nRow;
+ else
+ return 0;
+}
SCROW ScColumn::GetLastDataPos() const
{
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 2b0b3821dcc2..18370d2f5a0f 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -96,6 +96,7 @@
#include "globstr.hrc"
#include "sc.hrc"
#include "charthelper.hxx"
+#include "dpobject.hxx"
#define GET_SCALEVALUE(set,id) ((const SfxUInt16Item&)(set.Get( id ))).GetValue()
@@ -700,8 +701,13 @@ BOOL ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe
// skip everything left of rSpellPos:
while ( pCell && nRow == rSpellPos.Row() && nCol < rSpellPos.Col() )
pCell = aIter.GetNext( nCol, nRow );
- while ( pCell )
+
+ for (; pCell; pCell = aIter.GetNext(nCol, nRow))
{
+ if (pDPCollection && pDPCollection->HasDPTable(nCol, nRow, nTab))
+ // Don't spell check within datapilot table.
+ continue;
+
CellType eType = pCell->GetCellType();
if ( eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT )
{
@@ -786,8 +792,6 @@ BOOL ScDocument::OnlineSpellInRange( const ScRange& rSpellRange, ScAddress& rSpe
if ( ++nCellCount >= SPELL_MAXCELLS ) // seen enough cells?
break;
-
- pCell = aIter.GetNext( nCol, nRow );
}
if ( pCell )
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 4dd3f34e3f0d..f8fa2bc46c9b 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -639,6 +639,32 @@ BOOL ScDocument::GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) cons
return FALSE;
}
+bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow) const
+{
+ if (!ValidTab(nTab) || !pTab[nTab])
+ return false;
+
+ SCCOL nCol1, nCol2;
+ SCROW nRow1, nRow2;
+ pTab[nTab]->GetFirstDataPos(nCol1, nRow1);
+ pTab[nTab]->GetLastDataPos(nCol2, nRow2);
+
+ if (nCol1 > nCol2 || nRow1 > nRow2)
+ // invalid range.
+ return false;
+
+ // Make sure the area only shrinks, and doesn't grow.
+ if (rStartCol < nCol1)
+ rStartCol = nCol1;
+ if (nCol2 < rEndCol)
+ rEndCol = nCol2;
+ if (rStartRow < nRow1)
+ rStartRow = nRow1;
+ if (nRow2 < rEndRow)
+ rEndRow = nRow2;
+
+ return true; // success!
+}
// zusammenhaengender Bereich
diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx
index 09f32b4ba1b1..29284b20e4bb 100644
--- a/sc/source/core/data/dpgroup.cxx
+++ b/sc/source/core/data/dpgroup.cxx
@@ -70,6 +70,7 @@ using ::rtl::OUStringHash;
using ::std::vector;
using ::std::hash_set;
using ::std::hash_map;
+using ::boost::shared_ptr;
#define D_TIMEFACTOR 86400.0
@@ -977,7 +978,7 @@ String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bo
return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter );
}
-ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDocument ) :
+ScDPGroupTableData::ScDPGroupTableData( const shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument ) :
ScDPTableData(pDocument),
pSourceData( pSource ),
pDoc( pDocument )
@@ -992,7 +993,6 @@ ScDPGroupTableData::ScDPGroupTableData( ScDPTableData* pSource, ScDocument* pDoc
ScDPGroupTableData::~ScDPGroupTableData()
{
delete[] pNumGroups;
- delete pSourceData;
}
void ScDPGroupTableData::AddGroupDimension( const ScDPGroupDimension& rGroup )
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index ad9795d11c4d..295ed78159b3 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -75,9 +75,11 @@
#include <svl/zforlist.hxx> // IsNumberFormat
#include <vector>
+#include <stdio.h>
using namespace com::sun::star;
using ::std::vector;
+using ::boost::shared_ptr;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
@@ -162,11 +164,14 @@ ScDPObject::ScDPObject( ScDocument* pD ) :
pSheetDesc( NULL ),
pImpDesc( NULL ),
pServDesc( NULL ),
+ mpTableData(static_cast<ScDPTableData*>(NULL)),
pOutput( NULL ),
bSettingsChanged( FALSE ),
bAlive( FALSE ),
+ mnAutoFormatIndex( 65535 ),
bAllowMove( FALSE ),
- nHeaderRows( 0 )
+ nHeaderRows( 0 ),
+ mbHeaderLayout(false)
{
}
@@ -180,11 +185,14 @@ ScDPObject::ScDPObject(const ScDPObject& r) :
pSheetDesc( NULL ),
pImpDesc( NULL ),
pServDesc( NULL ),
+ mpTableData(static_cast<ScDPTableData*>(NULL)),
pOutput( NULL ),
bSettingsChanged( FALSE ),
bAlive( FALSE ),
+ mnAutoFormatIndex( r.mnAutoFormatIndex ),
bAllowMove( FALSE ),
- nHeaderRows( r.nHeaderRows )
+ nHeaderRows( r.nHeaderRows ),
+ mbHeaderLayout( r.mbHeaderLayout )
{
if (r.pSaveData)
pSaveData = new ScDPSaveData(*r.pSaveData);
@@ -232,6 +240,26 @@ void ScDPObject::SetSaveData(const ScDPSaveData& rData)
InvalidateData(); // re-init source from SaveData
}
+void ScDPObject::SetAutoFormatIndex(const sal_uInt16 nIndex)
+{
+ mnAutoFormatIndex = nIndex;
+}
+
+sal_uInt16 ScDPObject::GetAutoFormatIndex() const
+{
+ return mnAutoFormatIndex;
+}
+
+void ScDPObject::SetHeaderLayout (bool bUseGrid)
+{
+ mbHeaderLayout = bUseGrid;
+}
+
+bool ScDPObject::GetHeaderLayout() const
+{
+ return mbHeaderLayout;
+}
+
void ScDPObject::SetOutRange(const ScRange& rRange)
{
aOutRange = rRange;
@@ -325,6 +353,22 @@ void ScDPObject::SetTag(const String& rNew)
aTableTag = rNew;
}
+bool ScDPObject::IsDataDescriptionCell(const ScAddress& rPos)
+{
+ if (!pSaveData)
+ return false;
+
+ long nDataDimCount = pSaveData->GetDataDimensionCount();
+ if (nDataDimCount != 1)
+ // There has to be exactly one data dimension for the description to
+ // appear at top-left corner.
+ return false;
+
+ CreateOutput();
+ ScRange aTabRange = pOutput->GetOutputRange(sheet::DataPilotOutputRangeType::TABLE);
+ return (rPos == aTabRange.aStart);
+}
+
uno::Reference<sheet::XDimensionsSupplier> ScDPObject::GetSource()
{
CreateObjects();
@@ -338,6 +382,7 @@ void ScDPObject::CreateOutput()
{
BOOL bFilterButton = IsSheetData() && pSaveData && pSaveData->GetFilterButton();
pOutput = new ScDPOutput( pDoc, xSource, aOutRange.aStart, bFilterButton );
+ pOutput->SetHeaderLayout ( mbHeaderLayout );
long nOldRows = nHeaderRows;
nHeaderRows = pOutput->GetHeaderRows();
@@ -365,11 +410,43 @@ void ScDPObject::CreateOutput()
}
}
+ScDPTableData* ScDPObject::GetTableData()
+{
+ if (!mpTableData)
+ {
+ if ( pImpDesc )
+ {
+ // database data
+ mpTableData.reset(new ScDatabaseDPData(pDoc, *pImpDesc));
+ }
+ else
+ {
+ // cell data
+ if (!pSheetDesc)
+ {
+ DBG_ERROR("no source descriptor");
+ pSheetDesc = new ScSheetSourceDesc; // dummy defaults
+ }
+ mpTableData.reset(new ScSheetDPData(pDoc, *pSheetDesc));
+ }
+
+ // grouping (for cell or database data)
+ if ( pSaveData && pSaveData->GetExistingDimensionData() )
+ {
+ shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(mpTableData, pDoc));
+ pSaveData->GetExistingDimensionData()->WriteToData(*pGroupData);
+ mpTableData = pGroupData;
+ }
+ }
+
+ return mpTableData.get();
+}
+
void ScDPObject::CreateObjects()
{
// if groups are involved, create a new source with the ScDPGroupTableData
if ( bSettingsChanged && pSaveData && pSaveData->GetExistingDimensionData() )
- xSource = NULL;
+ InvalidateSource();
if (!xSource.is())
{
@@ -387,33 +464,9 @@ void ScDPObject::CreateObjects()
if ( !xSource.is() ) // database or sheet data, or error in CreateSource
{
DBG_ASSERT( !pServDesc, "DPSource could not be created" );
-
- ScDPTableData* pData = NULL;
- if ( pImpDesc )
- {
- // database data
- pData = new ScDatabaseDPData( pDoc, *pImpDesc );
- }
- else
- {
- // cell data
- if (!pSheetDesc)
- {
- DBG_ERROR("no source descriptor");
- pSheetDesc = new ScSheetSourceDesc; // dummy defaults
- }
- pData = new ScSheetDPData( pDoc, *pSheetDesc );
- }
-
- // grouping (for cell or database data)
- if ( pSaveData && pSaveData->GetExistingDimensionData() )
- {
- ScDPGroupTableData* pGroupData = new ScDPGroupTableData( pData, pDoc );
- pSaveData->GetExistingDimensionData()->WriteToData( *pGroupData );
- pData = pGroupData;
- }
-
- xSource = new ScDPSource( pData );
+ ScDPTableData* pData = GetTableData();
+ ScDPSource* pSource = new ScDPSource( pData );
+ xSource = pSource;
}
if (pSaveData)
@@ -450,6 +503,7 @@ void ScDPObject::InvalidateData()
void ScDPObject::InvalidateSource()
{
xSource = NULL;
+ mpTableData.reset();
}
ScRange ScDPObject::GetNewOutputRange( BOOL& rOverflow )
@@ -484,6 +538,9 @@ void ScDPObject::Output( const ScAddress& rPos )
// aOutRange is always the range that was last output to the document
aOutRange = pOutput->GetOutputRange();
+ const ScAddress& s = aOutRange.aStart;
+ const ScAddress& e = aOutRange.aEnd;
+ pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
}
const ScRange ScDPObject::GetOutputRangeByType( sal_Int32 nType )
@@ -533,6 +590,63 @@ void ScDPObject::RefreshAfterLoad()
nHeaderRows = 0; // nothing found, no drop-down lists
}
+void ScDPObject::BuildAllDimensionMembers()
+{
+ if (!pSaveData)
+ return;
+
+ pSaveData->BuildAllDimensionMembers(GetTableData());
+}
+
+bool ScDPObject::GetMemberNames( sal_Int32 nDim, Sequence<OUString>& rNames )
+{
+ vector<ScDPLabelData::Member> aMembers;
+ if (!GetMembers(nDim, GetUsedHierarchy(nDim), aMembers))
+ return false;
+
+ size_t n = aMembers.size();
+ rNames.realloc(n);
+ for (size_t i = 0; i < n; ++i)
+ rNames[i] = aMembers[i].maName;
+
+ return true;
+}
+
+bool ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier, vector<ScDPLabelData::Member>& rMembers )
+{
+ Reference< container::XNameAccess > xMembersNA;
+ if (!GetMembersNA( nDim, nHier, xMembersNA ))
+ return false;
+
+ Reference<container::XIndexAccess> xMembersIA( new ScNameToIndexAccess(xMembersNA) );
+ sal_Int32 nCount = xMembersIA->getCount();
+ vector<ScDPLabelData::Member> aMembers;
+ aMembers.reserve(nCount);
+
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ {
+ Reference<container::XNamed> xMember(xMembersIA->getByIndex(i), UNO_QUERY);
+ ScDPLabelData::Member aMem;
+
+ if (xMember.is())
+ aMem.maName = xMember->getName();
+
+ Reference<beans::XPropertySet> xMemProp(xMember, UNO_QUERY);
+ if (xMemProp.is())
+ {
+ aMem.mbVisible = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_ISVISIBL));
+ aMem.mbShowDetails = ScUnoHelpFunctions::GetBoolProperty(xMemProp, OUString::createFromAscii(SC_UNO_SHOWDETA));
+
+ aMem.maLayoutName = ScUnoHelpFunctions::GetStringProperty(
+ xMemProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
+ }
+
+ aMembers.push_back(aMem);
+ }
+ rMembers.swap(aMembers);
+ return true;
+}
+
void ScDPObject::UpdateReference( UpdateRefMode eUpdateRefMode,
const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
{
@@ -655,23 +769,33 @@ void ScDPObject::GetDrillDownData(const ScAddress& rPos, Sequence< Sequence<Any>
rTableData = xDrillDownData->getDrillDownData(filters);
}
-BOOL ScDPObject::IsDimNameInUse( const String& rName ) const
+bool ScDPObject::IsDimNameInUse(const OUString& rName) const
{
- if ( xSource.is() )
+ if (!xSource.is())
+ return false;
+
+ Reference<container::XNameAccess> xDims = xSource->getDimensions();
+ Sequence<OUString> aDimNames = xDims->getElementNames();
+ sal_Int32 n = aDimNames.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
{
- uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
- if ( xDimsName.is() )
+ const OUString& rDimName = aDimNames[i];
+ if (rDimName.equalsIgnoreAsciiCase(rName))
+ return true;
+
+ Reference<beans::XPropertySet> xPropSet(xDims->getByName(rDimName), UNO_QUERY);
+ if (!xPropSet.is())
+ continue;
+
+ Any any = xPropSet->getPropertyValue(OUString::createFromAscii(SC_UNO_LAYOUTNAME));
+ OUString aLayoutName;
+ if (any >>= aLayoutName)
{
- rtl::OUString aCompare( rName );
- uno::Sequence<rtl::OUString> aNames = xDimsName->getElementNames();
- long nCount = aNames.getLength();
- const rtl::OUString* pArr = aNames.getConstArray();
- for (long nPos=0; nPos<nCount; nPos++)
- if ( pArr[nPos] == aCompare ) //! ignore case
- return TRUE;
+ if (aLayoutName.equalsIgnoreAsciiCase(rName))
+ return true;
}
}
- return FALSE; // not found
+ return false;
}
String ScDPObject::GetDimName( long nDim, BOOL& rIsDataLayout )
@@ -1732,7 +1856,7 @@ BOOL ScDPObject::FillOldParam(ScPivotParam& rParam, BOOL bForFile) const
return TRUE;
}
-void lcl_FillLabelData( LabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp )
+void lcl_FillLabelData( ScDPLabelData& rData, const uno::Reference< beans::XPropertySet >& xDimProp )
{
uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDimProp, uno::UNO_QUERY );
if ( xDimProp.is() && xDimSupp.is() )
@@ -1778,6 +1902,8 @@ void lcl_FillLabelData( LabelData& rData, const uno::Reference< beans::XProperty
BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
{
+ rParam.maLabelArray.clear();
+
((ScDPObject*)this)->CreateObjects();
uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
@@ -1788,8 +1914,6 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
if (!nDimCount)
return FALSE;
- SCSIZE nOutCount = 0;
- LabelData** aLabelArr = new LabelData*[nDimCount];
for (long nDim=0; nDim < nDimCount; nDim++)
{
String aFieldName;
@@ -1819,29 +1943,24 @@ BOOL ScDPObject::FillLabelData(ScPivotParam& rParam)
{
}
+ OUString aLayoutName = ScUnoHelpFunctions::GetStringProperty(
+ xDimProp, OUString::createFromAscii(SC_UNO_LAYOUTNAME), OUString());
+
if ( aFieldName.Len() && !bData && !bDuplicated )
{
SCsCOL nCol = static_cast< SCsCOL >( nDim ); //! ???
bool bIsValue = true; //! check
- aLabelArr[nOutCount] = new LabelData( aFieldName, nCol, bIsValue );
-
- LabelData& rLabelData = *aLabelArr[nOutCount];
- GetHierarchies( nDim, rLabelData.maHiers );
- GetMembers( nDim, rLabelData.maMembers, &rLabelData.maVisible, &rLabelData.maShowDet );
- lcl_FillLabelData( rLabelData, xDimProp );
-
- ++nOutCount;
+ ScDPLabelDataRef pNewLabel(new ScDPLabelData(aFieldName, nCol, bIsValue));
+ pNewLabel->maLayoutName = aLayoutName;
+ GetHierarchies(nDim, pNewLabel->maHiers);
+ GetMembers(nDim, GetUsedHierarchy(nDim), pNewLabel->maMembers);
+ lcl_FillLabelData(*pNewLabel, xDimProp);
+ rParam.maLabelArray.push_back(pNewLabel);
}
}
}
- rParam.SetLabelData( aLabelArr, nOutCount );
-
- for (SCSIZE i=0; i<nOutCount; i++)
- delete aLabelArr[i];
- delete[] aLabelArr;
-
return TRUE;
}
@@ -1890,14 +2009,6 @@ BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, uno::Reference< container::XNameA
return GetMembersNA( nDim, GetUsedHierarchy( nDim ), xMembers );
}
-BOOL ScDPObject::GetMembers( sal_Int32 nDim,
- uno::Sequence< rtl::OUString >& rMembers,
- uno::Sequence< sal_Bool >* pVisible,
- uno::Sequence< sal_Bool >* pShowDet )
-{
- return GetMembers( nDim, GetUsedHierarchy( nDim ), rMembers, pVisible, pShowDet );
-}
-
BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< container::XNameAccess >& xMembers )
{
BOOL bRet = FALSE;
@@ -1933,55 +2044,6 @@ BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference<
return bRet;
}
-BOOL ScDPObject::GetMembers( sal_Int32 nDim, sal_Int32 nHier,
- uno::Sequence< rtl::OUString >& rMembers,
- uno::Sequence< sal_Bool >* pVisible,
- uno::Sequence< sal_Bool >* pShowDet )
-{
- BOOL bRet = FALSE;
- uno::Reference< container::XNameAccess > xMembersNA;
- if( GetMembersNA( nDim, nHier, xMembersNA ) )
- {
- uno::Reference< container::XIndexAccess > xMembersIA( new ScNameToIndexAccess( xMembersNA ) );
- sal_Int32 nCount = xMembersIA->getCount();
- rMembers.realloc( nCount );
- if( pVisible )
- pVisible->realloc( nCount );
- if( pShowDet )
- pShowDet->realloc( nCount );
-
- rtl::OUString* pAry = rMembers.getArray();
- for( sal_Int32 nItem = 0; nItem < nCount; ++nItem )
- {
- uno::Reference< container::XNamed > xMember( xMembersIA->getByIndex( nItem ), uno::UNO_QUERY );
- if( xMember.is() )
- pAry[ nItem ] = xMember->getName();
- if( pVisible || pShowDet )
- {
- uno::Reference< beans::XPropertySet > xMemProp( xMember, uno::UNO_QUERY );
- if( pVisible )
- {
- sal_Bool bVis = sal_True;
- if( xMemProp.is() )
- bVis = ScUnoHelpFunctions::GetBoolProperty( xMemProp,
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_ISVISIBL ) ) );
- (*pVisible)[ nItem ] = bVis;
- }
- if( pShowDet )
- {
- sal_Bool bShow = sal_True;
- if( xMemProp.is() )
- bShow = ScUnoHelpFunctions::GetBoolProperty( xMemProp,
- rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_SHOWDETA ) ) );
- (*pShowDet)[ nItem ] = bShow;
- }
- }
- }
- bRet = TRUE;
- }
- return bRet;
-}
-
//------------------------------------------------------------------------
// convert old pivot tables into new datapilot tables
@@ -2376,7 +2438,7 @@ void ScDPCollection::WriteRefsTo( ScDPCollection& r ) const
ScDPObject* pDestObj = new ScDPObject( *pSourceObj );
pDestObj->SetAlive(TRUE);
- if ( !r.Insert(pDestObj) )
+ if ( !r.InsertNewTable(pDestObj) )
{
DBG_ERROR("cannot insert DPObject");
DELETEZ( pDestObj );
@@ -2411,6 +2473,39 @@ ScSimpleSharedString& ScDPCollection::GetSharedString()
return maSharedString;
}
+void ScDPCollection::FreeTable(ScDPObject* pDPObj)
+{
+ const ScRange& rOutRange = pDPObj->GetOutRange();
+ const ScAddress& s = rOutRange.aStart;
+ const ScAddress& e = rOutRange.aEnd;
+ pDoc->RemoveFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
+ Free(pDPObj);
+}
+
+bool ScDPCollection::InsertNewTable(ScDPObject* pDPObj)
+{
+ bool bSuccess = Insert(pDPObj);
+ if (bSuccess)
+ {
+ const ScRange& rOutRange = pDPObj->GetOutRange();
+ const ScAddress& s = rOutRange.aStart;
+ const ScAddress& e = rOutRange.aEnd;
+ pDoc->ApplyFlagsTab(s.Col(), s.Row(), e.Col(), e.Row(), s.Tab(), SC_MF_DP_TABLE);
+ }
+ return bSuccess;
+}
+
+bool ScDPCollection::HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const
+{
+ const ScMergeFlagAttr* pMergeAttr = static_cast<const ScMergeFlagAttr*>(
+ pDoc->GetAttr(nCol, nRow, nTab, ATTR_MERGE_FLAG));
+
+ if (!pMergeAttr)
+ return false;
+
+ return pMergeAttr->HasDPTable();
+}
+
ScDPCacheCell* ScDPCollection::getCacheCellFromPool(const ScDPCacheCell& rCell)
{
ScDPCacheCell aCell(rCell);
diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx
index d1fad68f16a2..10dcbfa8238e 100644
--- a/sc/source/core/data/dpoutput.cxx
+++ b/sc/source/core/data/dpoutput.cxx
@@ -81,6 +81,7 @@
using namespace com::sun::star;
using ::std::vector;
+using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::uno::Reference;
@@ -98,7 +99,6 @@ using ::rtl::OUString;
#define DP_PROP_ORIENTATION "Orientation"
#define DP_PROP_POSITION "Position"
#define DP_PROP_USEDHIERARCHY "UsedHierarchy"
-#define DP_PROP_DATADESCR "DataDescription"
#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension"
#define DP_PROP_NUMBERFORMAT "NumberFormat"
#define DP_PROP_FILTER "Filter"
@@ -119,9 +119,15 @@ struct ScDPOutLevelData
long nLevel;
long nDimPos;
uno::Sequence<sheet::MemberResult> aResult;
- String aCaption;
+ String maName; /// Name is the internal field name.
+ String aCaption; /// Caption is the name visible in the output table.
+ bool mbHasHiddenMember;
- ScDPOutLevelData() { nDim = nHier = nLevel = nDimPos = -1; }
+ ScDPOutLevelData()
+ {
+ nDim = nHier = nLevel = nDimPos = -1;
+ mbHasHiddenMember = false;
+ }
BOOL operator<(const ScDPOutLevelData& r) const
{ return nDimPos<r.nDimPos || ( nDimPos==r.nDimPos && nHier<r.nHier ) ||
@@ -370,13 +376,15 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
aStartPos( rPos ),
bDoFilter( bFilter ),
bResultsError( FALSE ),
+ mbHasDataLayout(false),
pColNumFmt( NULL ),
pRowNumFmt( NULL ),
nColFmtCount( 0 ),
nRowFmtCount( 0 ),
nSingleNumFmt( 0 ),
bSizesValid( FALSE ),
- bSizeOverflow( FALSE )
+ bSizeOverflow( FALSE ),
+ mbHeaderLayout( false )
{
nTabStartCol = nMemberStartCol = nDataStartCol = nTabEndCol = 0;
nTabStartRow = nMemberStartRow = nDataStartRow = nTabEndRow = 0;
@@ -413,6 +421,8 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
BOOL bIsDataLayout = ScUnoHelpFunctions::GetBoolProperty(
xDimProp,
rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
+ bool bHasHiddenMember = ScUnoHelpFunctions::GetBoolProperty(
+ xDimProp, OUString::createFromAscii(SC_UNO_HAS_HIDDEN_MEMBER));
if ( eDimOrient != sheet::DataPilotFieldOrientation_HIDDEN )
{
@@ -443,7 +453,17 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
xLevel, uno::UNO_QUERY );
if ( xLevNam.is() && xLevRes.is() )
{
- String aCaption = String(xLevNam->getName()); //! Caption...
+ String aName = xLevNam->getName();
+ OUString aCaption = aName; // Caption equals the field name by default.
+ Reference<XPropertySet> xPropSet(xLevel, UNO_QUERY);
+ if (xPropSet.is())
+ {
+ Any any = xPropSet->getPropertyValue(
+ OUString::createFromAscii(SC_UNO_LAYOUTNAME));
+ any >>= aCaption;
+ }
+
+ bool bRowFieldHasMember = false;
switch ( eDimOrient )
{
case sheet::DataPilotFieldOrientation_COLUMN:
@@ -452,7 +472,9 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
pColFields[nColFieldCount].nLevel = nLev;
pColFields[nColFieldCount].nDimPos = nDimPos;
pColFields[nColFieldCount].aResult = xLevRes->getResults();
+ pColFields[nColFieldCount].maName = aName;
pColFields[nColFieldCount].aCaption= aCaption;
+ pColFields[nColFieldCount].mbHasHiddenMember = bHasHiddenMember;
if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult))
++nColFieldCount;
break;
@@ -462,9 +484,14 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
pRowFields[nRowFieldCount].nLevel = nLev;
pRowFields[nRowFieldCount].nDimPos = nDimPos;
pRowFields[nRowFieldCount].aResult = xLevRes->getResults();
+ pRowFields[nRowFieldCount].maName = aName;
pRowFields[nRowFieldCount].aCaption= aCaption;
+ pRowFields[nRowFieldCount].mbHasHiddenMember = bHasHiddenMember;
if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult))
+ {
++nRowFieldCount;
+ bRowFieldHasMember = true;
+ }
break;
case sheet::DataPilotFieldOrientation_PAGE:
pPageFields[nPageFieldCount].nDim = nDim;
@@ -472,7 +499,9 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
pPageFields[nPageFieldCount].nLevel = nLev;
pPageFields[nPageFieldCount].nDimPos = nDimPos;
pPageFields[nPageFieldCount].aResult = lcl_GetSelectedPageAsResult(xDimProp);
+ pPageFields[nPageFieldCount].maName = aName;
pPageFields[nPageFieldCount].aCaption= aCaption;
+ pPageFields[nPageFieldCount].mbHasHiddenMember = bHasHiddenMember;
// no check on results for page fields
++nPageFieldCount;
break;
@@ -485,6 +514,9 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
// get number formats from data dimensions
if ( bIsDataLayout )
{
+ if (bRowFieldHasMember)
+ mbHasDataLayout = true;
+
DBG_ASSERT( nLevCount == 1, "data layout: multiple levels?" );
if ( eDimOrient == sheet::DataPilotFieldOrientation_COLUMN )
lcl_FillNumberFormats( pColNumFmt, nColFmtCount, xLevRes, xDims );
@@ -528,7 +560,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS
try
{
uno::Any aAny = xSrcProp->getPropertyValue(
- rtl::OUString::createFromAscii(DP_PROP_DATADESCR) );
+ rtl::OUString::createFromAscii(SC_UNO_DATADESC) );
rtl::OUString aUStr;
aAny >>= aUStr;
aDataDescription = String( aUStr );
@@ -605,9 +637,16 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
const sheet::MemberResult& rData, BOOL bColHeader, long nLevel )
{
long nFlags = rData.Flags;
+
+ rtl::OUStringBuffer aCaptionBuf;
+ if (!(nFlags & sheet::MemberResultFlags::NUMERIC))
+ // This caption is not a number. Make sure it won't get parsed as one.
+ aCaptionBuf.append(sal_Unicode('\''));
+ aCaptionBuf.append(rData.Caption);
+
if ( nFlags & sheet::MemberResultFlags::HASMEMBER )
{
- pDoc->SetString( nCol, nRow, nTab, rData.Caption );
+ pDoc->SetString( nCol, nRow, nTab, aCaptionBuf.makeStringAndClear() );
}
else
{
@@ -638,14 +677,20 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
}
}
-void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption, BOOL bFrame )
+void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption,
+ bool bInTable, bool bPopup, bool bHasHiddenMember )
{
pDoc->SetString( nCol, nRow, nTab, rCaption );
- if (bFrame)
+ if (bInTable)
lcl_SetFrame( pDoc,nTab, nCol,nRow, nCol,nRow, 20 );
// Button
- pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) );
+ sal_uInt16 nMergeFlag = SC_MF_BUTTON;
+ if (bPopup)
+ nMergeFlag |= SC_MF_BUTTON_POPUP;
+ if (bHasHiddenMember)
+ nMergeFlag |= SC_MF_HIDDEN_MEMBER;
+ pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, nMergeFlag);
lcl_SetStyleById( pDoc,nTab, nCol,nRow, nCol,nRow, STR_PIVOT_STYLE_FIELDNAME );
}
@@ -653,7 +698,7 @@ void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rC
void lcl_DoFilterButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
{
pDoc->SetString( nCol, nRow, nTab, ScGlobal::GetRscString(STR_CELL_FILTER) );
- pDoc->ApplyAttr( nCol, nRow, nTab, ScMergeFlagAttr(SC_MF_BUTTON) );
+ pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON);
}
void ScDPOutput::CalcSizes()
@@ -666,7 +711,11 @@ void ScDPOutput::CalcSizes()
nRowCount = aData.getLength();
const uno::Sequence<sheet::DataResult>* pRowAry = aData.getConstArray();
nColCount = nRowCount ? ( pRowAry[0].getLength() ) : 0;
- nHeaderSize = 1; // one row for field names
+
+ nHeaderSize = 1;
+ if (GetHeaderLayout() && nColFieldCount == 0)
+ // Insert an extra header row only when there is no column field.
+ nHeaderSize = 2;
// calculate output positions and sizes
@@ -775,7 +824,7 @@ void ScDPOutput::Output()
SCCOL nHdrCol = aStartPos.Col();
SCROW nHdrRow = aStartPos.Row() + nField + ( bDoFilter ? 1 : 0 );
// draw without frame for consistency with filter button:
- FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, FALSE );
+ FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, false, false, pPageFields[nField].mbHasHiddenMember );
SCCOL nFldCol = nHdrCol + 1;
String aPageValue;
@@ -814,7 +863,7 @@ void ScDPOutput::Output()
for (nField=0; nField<nColFieldCount; nField++)
{
SCCOL nHdrCol = nDataStartCol + (SCCOL)nField; //! check for overflow
- FieldCell( nHdrCol, nTabStartRow, nTab, pColFields[nField].aCaption );
+ FieldCell( nHdrCol, nTabStartRow, nTab, pColFields[nField].aCaption, true, true, pColFields[nField].mbHasHiddenMember );
SCROW nRowPos = nMemberStartRow + (SCROW)nField; //! check for overflow
const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
@@ -849,9 +898,12 @@ void ScDPOutput::Output()
for (nField=0; nField<nRowFieldCount; nField++)
{
+ bool bDataLayout = mbHasDataLayout && (nField == nRowFieldCount-1);
+
SCCOL nHdrCol = nTabStartCol + (SCCOL)nField; //! check for overflow
SCROW nHdrRow = nDataStartRow - 1;
- FieldCell( nHdrCol, nHdrRow, nTab, pRowFields[nField].aCaption );
+ FieldCell( nHdrCol, nHdrRow, nTab, pRowFields[nField].aCaption, true, !bDataLayout,
+ pRowFields[nField].mbHasHiddenMember );
SCCOL nColPos = nMemberStartCol + (SCCOL)nField; //! check for overflow
const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
@@ -993,6 +1045,16 @@ void ScDPOutput::GetMemberResultNames( ScStrCollection& rNames, long nDimension
}
}
+void ScDPOutput::SetHeaderLayout(bool bUseGrid)
+{
+ mbHeaderLayout = bUseGrid;
+ bSizesValid = false;
+}
+
+bool ScDPOutput::GetHeaderLayout() const
+{
+ return mbHeaderLayout;
+}
void ScDPOutput::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData)
{
@@ -1146,7 +1208,7 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
for (SCCOL nColField = 0; nColField < nColFieldCount && bFilterByCol; ++nColField)
{
sheet::DataPilotFieldFilter filter;
- filter.FieldName = pColFields[nColField].aCaption;
+ filter.FieldName = pColFields[nColField].maName;
const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nColField].aResult;
const sheet::MemberResult* pArray = rSequence.getConstArray();
@@ -1163,10 +1225,15 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>&
}
// row fields
+ bool bDataLayoutExists = (nDataFieldCount > 1);
for (SCROW nRowField = 0; nRowField < nRowFieldCount && bFilterByRow; ++nRowField)
{
+ if (bDataLayoutExists && nRowField == nRowFieldCount - 1)
+ // There is no sense including the data layout field for filtering.
+ continue;
+
sheet::DataPilotFieldFilter filter;
- filter.FieldName = pRowFields[nRowField].aCaption;
+ filter.FieldName = pRowFields[nRowField].maName;
const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nRowField].aResult;
const sheet::MemberResult* pArray = rSequence.getConstArray();
@@ -1198,8 +1265,7 @@ bool lcl_IsNamedDataField( const ScDPGetPivotDataField& rTarget, const String& r
bool lcl_IsNamedCategoryField( const ScDPGetPivotDataField& rFilter, const ScDPOutLevelData& rField )
{
- //! name from source instead of caption?
- return ScGlobal::GetpTransliteration()->isEqual( rFilter.maFieldName, rField.aCaption );
+ return ScGlobal::GetpTransliteration()->isEqual( rFilter.maFieldName, rField.maName );
}
bool lcl_IsCondition( const sheet::MemberResult& rResultEntry, const ScDPGetPivotDataField& rFilter )
diff --git a/sc/source/core/data/dpoutputgeometry.cxx b/sc/source/core/data/dpoutputgeometry.cxx
new file mode 100644
index 000000000000..9eace100c137
--- /dev/null
+++ b/sc/source/core/data/dpoutputgeometry.cxx
@@ -0,0 +1,217 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: xmldpimp.cxx,v $
+ * $Revision: 1.27.134.1 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "dpoutputgeometry.hxx"
+#include "address.hxx"
+
+#include <vector>
+
+using ::std::vector;
+
+ScDPOutputGeometry::ScDPOutputGeometry(const ScRange& rOutRange, bool bShowFilter, ImportType eImportType) :
+ maOutRange(rOutRange),
+ mnRowFields(0),
+ mnColumnFields(0),
+ mnPageFields(0),
+ mnDataFields(0),
+ meImportType(eImportType),
+ mbShowFilter(bShowFilter)
+{
+}
+
+ScDPOutputGeometry::~ScDPOutputGeometry()
+{
+}
+
+void ScDPOutputGeometry::setRowFieldCount(sal_uInt32 nCount)
+{
+ mnRowFields = nCount;
+}
+
+void ScDPOutputGeometry::setColumnFieldCount(sal_uInt32 nCount)
+{
+ mnColumnFields = nCount;
+}
+
+void ScDPOutputGeometry::setPageFieldCount(sal_uInt32 nCount)
+{
+ mnPageFields = nCount;
+}
+
+void ScDPOutputGeometry::setDataFieldCount(sal_uInt32 nCount)
+{
+ mnDataFields = nCount;
+}
+
+void ScDPOutputGeometry::getColumnFieldPositions(vector<ScAddress>& rAddrs) const
+{
+ vector<ScAddress> aAddrs;
+ if (!mnColumnFields)
+ {
+ rAddrs.swap(aAddrs);
+ return;
+ }
+
+ bool bDataLayout = mnDataFields > 1;
+
+ SCROW nCurRow = maOutRange.aStart.Row();
+
+ if (mnPageFields)
+ {
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+ nCurRow = nRowEnd + 2;
+ }
+ else if (mbShowFilter)
+ nCurRow += 2;
+
+ SCROW nRow = nCurRow;
+ SCTAB nTab = maOutRange.aStart.Tab();
+ SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + mnRowFields + (bDataLayout ? 1 : 0));
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1);
+
+ for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
+ aAddrs.push_back(ScAddress(nCol, nRow, nTab));
+ rAddrs.swap(aAddrs);
+}
+
+void ScDPOutputGeometry::getRowFieldPositions(vector<ScAddress>& rAddrs) const
+{
+ vector<ScAddress> aAddrs;
+ if (!mnRowFields)
+ {
+ rAddrs.swap(aAddrs);
+ return;
+ }
+
+ SCROW nRow = getRowFieldHeaderRow();
+ SCTAB nTab = maOutRange.aStart.Tab();
+ SCCOL nColStart = maOutRange.aStart.Col();
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1);
+
+ for (SCCOL nCol = nColStart; nCol <= nColEnd; ++nCol)
+ aAddrs.push_back(ScAddress(nCol, nRow, nTab));
+ rAddrs.swap(aAddrs);
+}
+
+void ScDPOutputGeometry::getPageFieldPositions(vector<ScAddress>& rAddrs) const
+{
+ vector<ScAddress> aAddrs;
+ if (!mnPageFields)
+ {
+ rAddrs.swap(aAddrs);
+ return;
+ }
+
+ SCTAB nTab = maOutRange.aStart.Tab();
+ SCCOL nCol = maOutRange.aStart.Col();
+
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+
+ for (SCROW nRow = nRowStart; nRow <= nRowEnd; ++nRow)
+ aAddrs.push_back(ScAddress(nCol, nRow, nTab));
+ rAddrs.swap(aAddrs);
+}
+
+SCROW ScDPOutputGeometry::getRowFieldHeaderRow() const
+{
+ SCROW nCurRow = maOutRange.aStart.Row();
+
+ if (mnPageFields)
+ {
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+ nCurRow = nRowEnd + 2;
+ }
+ else if (mbShowFilter)
+ nCurRow += 2;
+
+ if (mnColumnFields)
+ nCurRow += static_cast<SCROW>(mnColumnFields);
+ else if (mnRowFields)
+ ++nCurRow;
+
+ return nCurRow;
+}
+
+ScDPOutputGeometry::FieldType ScDPOutputGeometry::getFieldButtonType(const ScAddress& rPos) const
+{
+ // We will ignore the table position for now.
+
+ bool bExtraTitleRow = (mnColumnFields == 0 && meImportType == ScDPOutputGeometry::XLS);
+ bool bDataLayout = mnDataFields > 1;
+
+ SCROW nCurRow = maOutRange.aStart.Row();
+
+ if (mnPageFields)
+ {
+ SCCOL nCol = maOutRange.aStart.Col();
+ SCROW nRowStart = maOutRange.aStart.Row() + mbShowFilter;
+ SCROW nRowEnd = nRowStart + static_cast<SCCOL>(mnPageFields-1);
+ if (rPos.Col() == nCol && nRowStart <= rPos.Row() && rPos.Row() <= nRowEnd)
+ return Page;
+
+ nCurRow = nRowEnd + 2;
+ }
+ else if (mbShowFilter)
+ nCurRow += 2;
+
+ if (mnColumnFields)
+ {
+ SCROW nRow = nCurRow;
+ SCCOL nColStart = static_cast<SCCOL>(maOutRange.aStart.Col() + mnRowFields + (bDataLayout ? 1 : 0));
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnColumnFields-1);
+ if (rPos.Row() == nRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd)
+ return Column;
+
+ nCurRow += static_cast<SCROW>(mnColumnFields);
+ }
+
+ if (bExtraTitleRow)
+ ++nCurRow;
+
+ if (mnRowFields)
+ {
+ SCCOL nColStart = maOutRange.aStart.Col();
+ SCCOL nColEnd = nColStart + static_cast<SCCOL>(mnRowFields-1);
+ if (rPos.Row() == nCurRow && nColStart <= rPos.Col() && rPos.Col() <= nColEnd)
+ return Row;
+ }
+
+ return None;
+}
diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx
index 62798076afb9..e66bd8dfe705 100644
--- a/sc/source/core/data/dpsave.cxx
+++ b/sc/source/core/data/dpsave.cxx
@@ -58,7 +58,15 @@
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/util/XCloneable.hpp>
+#include <hash_map>
+
using namespace com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::std::hash_map;
+using ::std::auto_ptr;
// -----------------------------------------------------------------------
@@ -99,6 +107,7 @@ void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp,
ScDPSaveMember::ScDPSaveMember(const String& rName) :
aName( rName ),
+ mpLayoutName(NULL),
nVisibleMode( SC_DPSAVEMODE_DONTKNOW ),
nShowDetailsMode( SC_DPSAVEMODE_DONTKNOW )
{
@@ -106,9 +115,12 @@ ScDPSaveMember::ScDPSaveMember(const String& rName) :
ScDPSaveMember::ScDPSaveMember(const ScDPSaveMember& r) :
aName( r.aName ),
+ mpLayoutName(NULL),
nVisibleMode( r.nVisibleMode ),
nShowDetailsMode( r.nShowDetailsMode )
{
+ if (r.mpLayoutName.get())
+ mpLayoutName.reset(new OUString(*r.mpLayoutName));
}
ScDPSaveMember::~ScDPSaveMember()
@@ -153,12 +165,23 @@ void ScDPSaveMember::SetName( const String& rNew )
aName = rNew;
}
-void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
+void ScDPSaveMember::SetLayoutName( const OUString& rName )
{
- // nothing to do?
- if ( nVisibleMode == SC_DPSAVEMODE_DONTKNOW && nShowDetailsMode == SC_DPSAVEMODE_DONTKNOW && nPosition < 0 )
- return;
+ mpLayoutName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveMember::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+void ScDPSaveMember::RemoveLayoutName()
+{
+ mpLayoutName.reset(NULL);
+}
+void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMember, sal_Int32 nPosition )
+{
uno::Reference<beans::XPropertySet> xMembProp( xMember, uno::UNO_QUERY );
DBG_ASSERT( xMembProp.is(), "no properties at member" );
if ( xMembProp.is() )
@@ -173,17 +196,11 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb
lcl_SetBoolProperty( xMembProp,
rtl::OUString::createFromAscii(DP_PROP_SHOWDETAILS), (BOOL)nShowDetailsMode );
+ if (mpLayoutName.get())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
+
if ( nPosition >= 0 )
- {
- try
- {
- xMembProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_POSITION), uno::Any(nPosition) );
- }
- catch ( uno::Exception& )
- {
- // position is optional - exception must be ignored
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xMembProp, DP_PROP_POSITION, nPosition);
}
}
@@ -191,8 +208,9 @@ void ScDPSaveMember::WriteToSource( const uno::Reference<uno::XInterface>& xMemb
ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) :
aName( rName ),
- pLayoutName( NULL ),
pSelectedPage( NULL ),
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
bIsDataLayout( bDataLayout ),
bDupFlag( FALSE ),
nOrientation( sheet::DataPilotFieldOrientation_HIDDEN ),
@@ -211,6 +229,8 @@ ScDPSaveDimension::ScDPSaveDimension(const String& rName, BOOL bDataLayout) :
ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
aName( r.aName ),
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
bIsDataLayout( r.bIsDataLayout ),
bDupFlag( r.bDupFlag ),
nOrientation( r.nOrientation ),
@@ -251,14 +271,14 @@ ScDPSaveDimension::ScDPSaveDimension(const ScDPSaveDimension& r) :
pLayoutInfo = new sheet::DataPilotFieldLayoutInfo( *(r.pLayoutInfo) );
else
pLayoutInfo = NULL;
- if (r.pLayoutName)
- pLayoutName = new String( *(r.pLayoutName) );
- else
- pLayoutName = NULL;
if (r.pSelectedPage)
pSelectedPage = new String( *(r.pSelectedPage) );
else
pSelectedPage = NULL;
+ if (r.mpLayoutName.get())
+ mpLayoutName.reset(new OUString(*r.mpLayoutName));
+ if (r.mpSubtotalName.get())
+ mpSubtotalName.reset(new OUString(*r.mpSubtotalName));
}
ScDPSaveDimension::~ScDPSaveDimension()
@@ -269,7 +289,6 @@ ScDPSaveDimension::~ScDPSaveDimension()
delete pSortInfo;
delete pAutoShowInfo;
delete pLayoutInfo;
- delete pLayoutName;
delete pSelectedPage;
delete [] pSubTotalFuncs;
}
@@ -370,25 +389,45 @@ void ScDPSaveDimension::SetUsedHierarchy(long nNew)
nUsedHierarchy = nNew;
}
-BOOL ScDPSaveDimension::HasLayoutName() const
+void ScDPSaveDimension::SetSubtotalName(const OUString& rName)
{
- return ( pLayoutName != NULL );
+ mpSubtotalName.reset(new OUString(rName));
}
-void ScDPSaveDimension::SetLayoutName(const String* pName)
+const OUString* ScDPSaveDimension::GetSubtotalName() const
{
- delete pLayoutName;
- if (pName)
- pLayoutName = new String( *pName );
- else
- pLayoutName = NULL;
+ return mpSubtotalName.get();
+}
+
+bool ScDPSaveDimension::IsMemberNameInUse(const OUString& rName) const
+{
+ MemberList::const_iterator itr = maMemberList.begin(), itrEnd = maMemberList.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ const ScDPSaveMember* pMem = *itr;
+ if (rName.equalsIgnoreAsciiCase(pMem->GetName()))
+ return true;
+
+ const OUString* pLayoutName = pMem->GetLayoutName();
+ if (pLayoutName && rName.equalsIgnoreAsciiCase(*pLayoutName))
+ return true;
+ }
+ return false;
+}
+
+void ScDPSaveDimension::SetLayoutName(const OUString& rName)
+{
+ mpLayoutName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveDimension::GetLayoutName() const
+{
+ return mpLayoutName.get();
}
-const String& ScDPSaveDimension::GetLayoutName() const
+void ScDPSaveDimension::RemoveLayoutName()
{
- if (pLayoutName)
- return *pLayoutName;
- return aName;
+ mpLayoutName.reset(NULL);
}
void ScDPSaveDimension::SetReferenceValue(const sheet::DataPilotFieldReference* pNew)
@@ -520,15 +559,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
aFilter = uno::Sequence<sheet::TableFilterField>( &aField, 1 );
}
// else keep empty sequence
- try
- {
- aAny <<= aFilter;
- xDimProp->setPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
+
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, DP_PROP_FILTER, aFilter);
+ if (mpLayoutName.get())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_LAYOUTNAME, *mpLayoutName);
+
+ const OUString* pSubTotalName = GetSubtotalName();
+ if (pSubTotalName)
+ // Custom subtotal name, with '?' being replaced by the visible field name later.
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_FIELD_SUBTOTALNAME, *pSubTotalName);
}
// Level loop outside of maMemberList loop
@@ -546,6 +585,8 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
nHierCount = xHiers->getCount();
}
+ sal_Bool bHasHiddenMember = false;
+
for (long nHier=0; nHier<nHierCount; nHier++)
{
uno::Reference<uno::XInterface> xHierarchy = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex(nHier) );
@@ -585,41 +626,13 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
rtl::OUString::createFromAscii(DP_PROP_SHOWEMPTY), (BOOL)nShowEmptyMode );
if ( pSortInfo )
- {
- aAny <<= *pSortInfo;
- try
- {
- xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_SORTING), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_SORTING, *pSortInfo);
+
if ( pAutoShowInfo )
- {
- aAny <<= *pAutoShowInfo;
- try
- {
- xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_AUTOSHOW), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_AUTOSHOW, *pAutoShowInfo);
+
if ( pLayoutInfo )
- {
- aAny <<= *pLayoutInfo;
- try
- {
- xLevProp->setPropertyValue( rtl::OUString::createFromAscii(SC_UNO_LAYOUT), aAny );
- }
- catch ( beans::UnknownPropertyException& )
- {
- // recent addition - allow source to not handle it (no error)
- }
- }
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xLevProp, SC_UNO_LAYOUT, *pLayoutInfo);
// exceptions are caught at ScDPSaveData::WriteToSource
}
@@ -638,12 +651,15 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
for (MemberList::const_iterator i=maMemberList.begin(); i != maMemberList.end() ; i++)
{
- rtl::OUString aMemberName = (*i)->GetName();
+ ScDPSaveMember* pMember = *i;
+ if (!pMember->GetIsVisible())
+ bHasHiddenMember = true;
+ rtl::OUString aMemberName = pMember->GetName();
if ( xMembers->hasByName( aMemberName ) )
{
uno::Reference<uno::XInterface> xMemberInt = ScUnoHelpFunctions::AnyToInterface(
xMembers->getByName( aMemberName ) );
- (*i)->WriteToSource( xMemberInt, nPosition );
+ pMember->WriteToSource( xMemberInt, nPosition );
if ( nPosition >= 0 )
++nPosition; // increase if initialized
@@ -655,6 +671,35 @@ void ScDPSaveDimension::WriteToSource( const uno::Reference<uno::XInterface>& xD
}
}
}
+
+ if (xDimProp.is())
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xDimProp, SC_UNO_HAS_HIDDEN_MEMBER, bHasHiddenMember);
+}
+
+void ScDPSaveDimension::UpdateMemberVisibility(const hash_map<OUString, bool, OUStringHash>& rData)
+{
+ typedef hash_map<OUString, bool, OUStringHash> DataMap;
+ MemberList::iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
+ for (; itrMem != itrMemEnd; ++itrMem)
+ {
+ ScDPSaveMember* pMem = *itrMem;
+ const String& rMemName = pMem->GetName();
+ DataMap::const_iterator itr = rData.find(rMemName);
+ if (itr != rData.end())
+ pMem->SetIsVisible(itr->second);
+ }
+}
+
+bool ScDPSaveDimension::HasInvisibleMember() const
+{
+ MemberList::const_iterator itrMem = maMemberList.begin(), itrMemEnd = maMemberList.end();
+ for (; itrMem != itrMemEnd; ++itrMem)
+ {
+ const ScDPSaveMember* pMem = *itrMem;
+ if (!pMem->GetIsVisible())
+ return true;
+ }
+ return false;
}
// -----------------------------------------------------------------------
@@ -666,7 +711,9 @@ ScDPSaveData::ScDPSaveData() :
nIgnoreEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ),
bFilterButton( TRUE ),
- bDrillDown( TRUE )
+ bDrillDown( TRUE ),
+ mbDimensionMembersBuilt(false),
+ mpGrandTotalName(NULL)
{
}
@@ -676,7 +723,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
nIgnoreEmptyMode( r.nIgnoreEmptyMode ),
nRepeatEmptyMode( r.nRepeatEmptyMode ),
bFilterButton( r.bFilterButton ),
- bDrillDown( r.bDrillDown )
+ bDrillDown( r.bDrillDown ),
+ mbDimensionMembersBuilt(r.mbDimensionMembersBuilt),
+ mpGrandTotalName(NULL)
{
if ( r.pDimensionData )
pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData );
@@ -689,6 +738,9 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) :
ScDPSaveDimension* pNew = new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) );
aDimList.Insert( pNew, LIST_APPEND );
}
+
+ if (r.mpGrandTotalName.get())
+ mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
}
ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
@@ -707,6 +759,7 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
nRepeatEmptyMode = r.nRepeatEmptyMode;
bFilterButton = r.bFilterButton;
bDrillDown = r.bDrillDown;
+ mbDimensionMembersBuilt = r.mbDimensionMembersBuilt;
// remove old dimensions
@@ -725,6 +778,9 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r )
new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) );
aDimList.Insert( pNew, LIST_APPEND );
}
+
+ if (r.mpGrandTotalName.get())
+ mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName));
}
return *this;
}
@@ -736,7 +792,8 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const
nIgnoreEmptyMode != r.nIgnoreEmptyMode ||
nRepeatEmptyMode != r.nRepeatEmptyMode ||
bFilterButton != r.bFilterButton ||
- bDrillDown != r.bDrillDown )
+ bDrillDown != r.bDrillDown ||
+ mbDimensionMembersBuilt != r.mbDimensionMembersBuilt)
return FALSE;
if ( pDimensionData || r.pDimensionData )
@@ -752,6 +809,16 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const
*(ScDPSaveDimension*)r.aDimList.GetObject(i) ) )
return FALSE;
+ if (mpGrandTotalName.get())
+ {
+ if (!r.mpGrandTotalName.get())
+ return false;
+ if (!mpGrandTotalName->equals(*r.mpGrandTotalName))
+ return false;
+ }
+ else if (r.mpGrandTotalName.get())
+ return false;
+
return TRUE;
}
@@ -765,6 +832,16 @@ ScDPSaveData::~ScDPSaveData()
delete pDimensionData;
}
+void ScDPSaveData::SetGrandTotalName(const OUString& rName)
+{
+ mpGrandTotalName.reset(new OUString(rName));
+}
+
+const OUString* ScDPSaveData::GetGrandTotalName() const
+{
+ return mpGrandTotalName.get();
+}
+
ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
{
long nCount = aDimList.Count();
@@ -779,7 +856,7 @@ ScDPSaveDimension* ScDPSaveData::GetDimensionByName(const String& rName)
return pNew;
}
-ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName)
+ScDPSaveDimension* ScDPSaveData::GetExistingDimensionByName(const String& rName) const
{
long nCount = aDimList.Count();
for (long i=0; i<nCount; i++)
@@ -807,16 +884,25 @@ ScDPSaveDimension* ScDPSaveData::GetNewDimensionByName(const String& rName)
ScDPSaveDimension* ScDPSaveData::GetDataLayoutDimension()
{
- ULONG nCount = aDimList.Count();
- for (ULONG i=0; i<nCount; i++)
+ ScDPSaveDimension* pDim = GetExistingDataLayoutDimension();
+ if (pDim)
+ return pDim;
+
+ ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE );
+ aDimList.Insert( pNew, LIST_APPEND );
+ return pNew;
+}
+
+ScDPSaveDimension* ScDPSaveData::GetExistingDataLayoutDimension() const
+{
+ long nCount = aDimList.Count();
+ for (long i=0; i<nCount; i++)
{
ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i);
if ( pDim->IsDataLayout() )
return pDim;
}
- ScDPSaveDimension* pNew = new ScDPSaveDimension( String(), TRUE );
- aDimList.Insert( pNew, LIST_APPEND );
- return pNew;
+ return NULL;
}
ScDPSaveDimension* ScDPSaveData::DuplicateDimension(const String& rName)
@@ -870,6 +956,18 @@ ScDPSaveDimension* ScDPSaveData::GetInnermostDimension(USHORT nOrientation)
return pInner; // the last matching one
}
+ScDPSaveDimension* ScDPSaveData::GetFirstDimension(sheet::DataPilotFieldOrientation eOrientation)
+{
+ long nCount = aDimList.Count();
+ for (long i = 0; i < nCount; ++i)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ if (pDim->GetOrientation() == eOrientation && !pDim->IsDataLayout())
+ return pDim;
+ }
+ return NULL;
+}
+
long ScDPSaveData::GetDataDimensionCount() const
{
long nDataCount = 0;
@@ -982,6 +1080,10 @@ void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplie
{
// no error
}
+
+ const OUString* pGrandTotalName = GetGrandTotalName();
+ if (pGrandTotalName)
+ ScUnoHelpFunctions::SetOptionalPropertyValue(xSourceProp, SC_UNO_GRANDTOTAL_NAME, *pGrandTotalName);
}
// exceptions in the other calls are errors
@@ -1100,3 +1202,58 @@ void ScDPSaveData::SetDimensionData( const ScDPDimensionSaveData* pNew )
pDimensionData = NULL;
}
+void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData)
+{
+ if (mbDimensionMembersBuilt)
+ return;
+
+ // First, build a dimension name-to-index map.
+ typedef hash_map<OUString, long, ::rtl::OUStringHash> NameIndexMap;
+ NameIndexMap aMap;
+ long nColCount = pData->GetColumnCount();
+ for (long i = 0; i < nColCount; ++i)
+ aMap.insert( NameIndexMap::value_type(pData->getDimensionName(i), i));
+
+ NameIndexMap::const_iterator itrEnd = aMap.end();
+
+ sal_uInt32 n = aDimList.Count();
+ for (sal_uInt32 i = 0; i < n; ++i)
+ {
+ ScDPSaveDimension* pDim = static_cast<ScDPSaveDimension*>(aDimList.GetObject(i));
+ const String& rDimName = pDim->GetName();
+ if (!rDimName.Len())
+ // empty dimension name. It must be data layout.
+ continue;
+
+ NameIndexMap::const_iterator itr = aMap.find(rDimName);
+ if (itr == itrEnd)
+ // dimension name not in the data. This should never happen!
+ continue;
+
+ long nDimIndex = itr->second;
+ const TypedScStrCollection& rMembers = pData->GetColumnEntries(nDimIndex);
+ sal_uInt16 nMemberCount = rMembers.GetCount();
+ for (sal_uInt16 j = 0; j < nMemberCount; ++j)
+ {
+ const String& rMemName = rMembers[j]->GetString();
+ if (pDim->GetExistingMemberByName(rMemName))
+ // this member instance already exists. nothing to do.
+ continue;
+
+ auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(rMemName));
+ pNewMember->SetIsVisible(true);
+ pDim->AddMember(pNewMember.release());
+ }
+ }
+
+ mbDimensionMembersBuilt = true;
+}
+
+bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const
+{
+ ScDPSaveDimension* pDim = GetExistingDimensionByName(rDimName);
+ if (!pDim)
+ return false;
+
+ return pDim->HasInvisibleMember();
+}
diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx
index 398d4d1c7e01..e548db56d7ff 100644
--- a/sc/source/core/data/dptabres.cxx
+++ b/sc/source/core/data/dptabres.cxx
@@ -67,6 +67,7 @@ using ::std::vector;
using ::std::pair;
using ::std::hash_map;
using ::com::sun::star::uno::Sequence;
+using ::rtl::OUString;
// -----------------------------------------------------------------------
@@ -825,11 +826,11 @@ USHORT ScDPResultData::GetMeasureRefOrient(long nMeasure) const
return pMeasRefOrient[nMeasure];
}
-String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc) const
+String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFunc eForceFunc, bool& rbTotalResult) const
{
// with bForce==TRUE, return function instead of "result" for single measure
// with eForceFunc != SUBTOTAL_FUNC_NONE, always use eForceFunc
-
+ rbTotalResult = false;
if ( nMeasure < 0 || ( nMeasCount == 1 && !bForce && eForceFunc == SUBTOTAL_FUNC_NONE ) )
{
// for user-specified subtotal function with all measures,
@@ -837,12 +838,19 @@ String ScDPResultData::GetMeasureString(long nMeasure, BOOL bForce, ScSubTotalFu
if ( eForceFunc != SUBTOTAL_FUNC_NONE )
return ScGlobal::GetRscString(nFuncStrIds[eForceFunc]);
+ rbTotalResult = true;
return ScGlobal::GetRscString(STR_TABLE_ERGEBNIS);
}
else
{
DBG_ASSERT( pMeasNames && nMeasure < nMeasCount, "bumm" );
-
+ ScDPDimension* pDataDim = pSource->GetDataDimension(nMeasure);
+ if (pDataDim)
+ {
+ const OUString* pLayoutName = pDataDim->GetLayoutName();
+ if (pLayoutName)
+ return *pLayoutName;
+ }
String aRet;
ScSubTotalFunc eFunc = ( eForceFunc == SUBTOTAL_FUNC_NONE ) ?
GetMeasureFunction(nMeasure) : eForceFunc;
@@ -896,6 +904,11 @@ BOOL ScDPResultData::HasCommonElement( const ScDPItemData& rFirstData, long nFir
return pSource->GetData()->HasCommonElement( rFirstData, nFirstIndex, rSecondData, nSecondIndex );
}
+const ScDPSource* ScDPResultData::GetSource() const
+{
+ return pSource;
+}
+
// -----------------------------------------------------------------------
@@ -1172,6 +1185,33 @@ void ScDPResultMember::ProcessData( const vector<ScDPItemData>& aChildMembers, c
}
}
+/**
+ * Parse subtotal string and replace all occurrences of '?' with the caption
+ * string. Do ensure that escaped characters are not translated.
+ */
+static String lcl_parseSubtotalName(const String& rSubStr, const String& rCaption)
+{
+ String aNewStr;
+ xub_StrLen n = rSubStr.Len();
+ bool bEscaped = false;
+ for (xub_StrLen i = 0; i < n; ++i)
+ {
+ sal_Unicode c = rSubStr.GetChar(i);
+ if (!bEscaped && c == sal_Unicode('\\'))
+ {
+ bEscaped = true;
+ continue;
+ }
+
+ if (!bEscaped && c == sal_Unicode('?'))
+ aNewStr.Append(rCaption);
+ else
+ aNewStr.Append(c);
+ bEscaped = false;
+ }
+ return aNewStr;
+}
+
void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pSequences,
long& rPos, long nMeasure, BOOL bRoot,
const String* pMemberName,
@@ -1204,17 +1244,25 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
}
String aCaption = aName;
+ if (pMemberDesc)
+ {
+ const OUString* pLayoutName = pMemberDesc->GetLayoutName();
+ if (pLayoutName)
+ {
+ aCaption = *pLayoutName;
+ bIsNumeric = false; // layout name is always non-numeric.
+ }
+ }
+
if ( pMemberCaption ) // use pMemberCaption if != NULL
aCaption = *pMemberCaption;
if (!aCaption.Len())
aCaption = ScGlobal::GetRscString(STR_EMPTYDATA);
- if ( !bIsNumeric )
- {
- // add a "'" character so a string isn't parsed as value in the output cell
- //! have a separate bit in Flags (MemberResultFlags) instead?
- aCaption.Insert( (sal_Unicode) '\'', 0 );
- }
+ if (bIsNumeric)
+ pArray[rPos].Flags |= sheet::MemberResultFlags::NUMERIC;
+ else
+ pArray[rPos].Flags &= ~sheet::MemberResultFlags::NUMERIC;
if ( nSize && !bRoot ) // root is overwritten by first dimension
{
@@ -1277,9 +1325,30 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS
if (bHasChild)
eForce = lcl_GetForceFunc( pParentLevel, nUserPos );
- String aSubStr = aName; //! caption?
+ bool bTotalResult = false;
+ String aSubStr = aCaption;
aSubStr += ' ';
- aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce);
+ aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce, bTotalResult);
+
+ if (bTotalResult)
+ {
+ if (pMemberDesc)
+ {
+ // single data field layout.
+ const OUString* pSubtotalName = pParentDim->GetSubtotalName();
+ if (pSubtotalName)
+ aSubStr = lcl_parseSubtotalName(*pSubtotalName, aCaption);
+ pArray[rPos].Flags &= ~sheet::MemberResultFlags::GRANDTOTAL;
+ }
+ else
+ {
+ // root member - subtotal (grand total?) for multi-data field layout.
+ const rtl::OUString* pGrandTotalName = pResultData->GetSource()->GetGrandTotalName();
+ if (pGrandTotalName)
+ aSubStr = *pGrandTotalName;
+ pArray[rPos].Flags |= sheet::MemberResultFlags::GRANDTOTAL;
+ }
+ }
pArray[rPos].Name = rtl::OUString(aName);
pArray[rPos].Caption = rtl::OUString(aSubStr);
@@ -2796,8 +2865,9 @@ void ScDPResultDimension::FillMemberResults( uno::Sequence<sheet::MemberResult>*
// in data layout dimension, use first member with different measures/names
if ( bIsDataLayout )
{
+ bool bTotalResult = false;
String aMbrName = pResultData->GetMeasureDimensionName( nSorted );
- String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE );
+ String aMbrCapt = pResultData->GetMeasureString( nSorted, FALSE, SUBTOTAL_FUNC_NONE, bTotalResult );
maMemberArray[0]->FillMemberResults( pSequences, nPos, nSorted, FALSE, &aMbrName, &aMbrCapt );
}
else if ( pMember->IsVisible() )
diff --git a/sc/source/core/data/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx
index e123e74a20e6..2a091c8b45b5 100644
--- a/sc/source/core/data/dptabsrc.cxx
+++ b/sc/source/core/data/dptabsrc.cxx
@@ -85,6 +85,7 @@ using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Any;
using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
+using ::rtl::OUString;
// -----------------------------------------------------------------------
@@ -141,15 +142,14 @@ ScDPSource::ScDPSource( ScDPTableData* pD ) :
pRowResRoot( NULL ),
pColResults( NULL ),
pRowResults( NULL ),
- bResultOverflow( FALSE )
+ bResultOverflow( FALSE ),
+ mpGrandTotalName(NULL)
{
pData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty );
}
ScDPSource::~ScDPSource()
{
- delete pData; // ScDPTableData is not ref-counted
-
if (pDimensions)
pDimensions->release(); // ref-counted
@@ -163,6 +163,16 @@ ScDPSource::~ScDPSource()
delete pResData;
}
+void ScDPSource::SetGrandTotalName(const ::rtl::OUString& rName)
+{
+ mpGrandTotalName.reset(new ::rtl::OUString(rName));
+}
+
+const ::rtl::OUString* ScDPSource::GetGrandTotalName() const
+{
+ return mpGrandTotalName.get();
+}
+
USHORT ScDPSource::GetOrientation(long nColumn)
{
long i;
@@ -186,16 +196,21 @@ long ScDPSource::GetDataDimensionCount()
return nDataDimCount;
}
+ScDPDimension* ScDPSource::GetDataDimension(long nIndex)
+{
+ if (nIndex < 0 || nIndex >= nDataDimCount)
+ return NULL;
+
+ long nDimIndex = nDataDims[nIndex];
+ return GetDimensionsObject()->getByIndex(nDimIndex);
+}
+
String ScDPSource::GetDataDimName( long nIndex )
{
String aRet;
- if ( nIndex >= 0 && nIndex < nDataDimCount )
- {
- long nDimIndex = nDataDims[nIndex];
- ScDPDimension* pDim = GetDimensionsObject()->getByIndex(nDimIndex);
- if (pDim)
- aRet = String( pDim->getName() );
- }
+ ScDPDimension* pDim = GetDataDimension(nIndex);
+ if (pDim)
+ aRet = String(pDim->getName());
return aRet;
}
@@ -488,7 +503,10 @@ String ScDPSource::getDataDescription()
String aRet;
if ( pResData->GetMeasureCount() == 1 )
- aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE );
+ {
+ bool bTotalResult = false;
+ aRet = pResData->GetMeasureString( 0, TRUE, SUBTOTAL_FUNC_NONE, bTotalResult );
+ }
// empty for more than one measure
@@ -1132,6 +1150,7 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo(
throw(uno::RuntimeException)
{
ScUnoGuard aGuard;
+ using beans::PropertyAttribute::READONLY;
static SfxItemPropertyMapEntry aDPSourceMap_Impl[] =
{
@@ -1140,6 +1159,10 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPSource::getPropertySetInfo(
{MAP_CHAR_LEN(SC_UNO_IGNOREEM), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
{MAP_CHAR_LEN(SC_UNO_REPEATIF), 0, &getBooleanCppuType(), 0, 0 }, // for sheet data only
{MAP_CHAR_LEN(SC_UNO_ROWGRAND), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_ROWFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_COLUMNFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_DATAFIELDCOUNT), 0, &getCppuType(static_cast<sal_Int32*>(0)), READONLY, 0 },
+ {MAP_CHAR_LEN(SC_UNO_GRANDTOTAL_NAME), 0, &getCppuType(static_cast<OUString*>(0)), 0, 0 },
{0,0,0,0,0,0}
};
static uno::Reference<beans::XPropertySetInfo> aRef =
@@ -1161,6 +1184,12 @@ void SAL_CALL ScDPSource::setPropertyValue( const rtl::OUString& aPropertyName,
setIgnoreEmptyRows( lcl_GetBoolFromAny( aValue ) );
else if ( aNameStr.EqualsAscii( SC_UNO_REPEATIF ) )
setRepeatIfEmpty( lcl_GetBoolFromAny( aValue ) );
+ else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
+ {
+ OUString aName;
+ if (aValue >>= aName)
+ mpGrandTotalName.reset(new OUString(aName));
+ }
else
{
DBG_ERROR("unknown property");
@@ -1190,6 +1219,11 @@ uno::Any SAL_CALL ScDPSource::getPropertyValue( const rtl::OUString& aPropertyNa
aRet <<= static_cast<sal_Int32>(nColDimCount);
else if ( aNameStr.EqualsAscii( SC_UNO_DATAFIELDCOUNT ) ) // read-only
aRet <<= static_cast<sal_Int32>(nDataDimCount);
+ else if (aNameStr.EqualsAscii(SC_UNO_GRANDTOTAL_NAME))
+ {
+ if (mpGrandTotalName.get())
+ aRet <<= *mpGrandTotalName;
+ }
else
{
DBG_ERROR("unknown property");
@@ -1337,9 +1371,12 @@ ScDPDimension::ScDPDimension( ScDPSource* pSrc, long nD ) :
pHierarchies( NULL ),
nUsedHier( 0 ),
nFunction( SUBTOTAL_FUNC_SUM ), // sum is default
+ mpLayoutName(NULL),
+ mpSubtotalName(NULL),
nSourceDim( -1 ),
bHasSelectedPage( FALSE ),
- pSelectedData( NULL )
+ pSelectedData( NULL ),
+ mbHasHiddenMember(false)
{
//! hold pSource
}
@@ -1364,6 +1401,16 @@ ScDPHierarchies* ScDPDimension::GetHierarchiesObject()
return pHierarchies;
}
+const rtl::OUString* ScDPDimension::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
+const rtl::OUString* ScDPDimension::GetSubtotalName() const
+{
+ return mpSubtotalName.get();
+}
+
uno::Reference<container::XNameAccess> SAL_CALL ScDPDimension::getHierarchies()
throw(uno::RuntimeException)
{
@@ -1523,6 +1570,9 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPDimension::getPropertySetIn
{MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_REFVALUE), 0, &getCppuType((sheet::DataPilotFieldReference*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_USEDHIER), 0, &getCppuType((sal_Int32*)0), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_FIELD_SUBTOTALNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_HAS_HIDDEN_MEMBER), 0, &getBooleanCppuType(), 0, 0 },
{0,0,0,0,0,0}
};
static uno::Reference<beans::XPropertySetInfo> aRef =
@@ -1593,6 +1643,20 @@ void SAL_CALL ScDPDimension::setPropertyValue( const rtl::OUString& aPropertyNam
}
DELETEZ( pSelectedData ); // invalid after changing aSelectedPage
}
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ OUString aTmpName;
+ if (aValue >>= aTmpName)
+ mpLayoutName.reset(new OUString(aTmpName));
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
+ {
+ OUString aTmpName;
+ if (aValue >>= aTmpName)
+ mpSubtotalName.reset(new OUString(aTmpName));
+ }
+ else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER))
+ aValue >>= mbHasHiddenMember;
else
{
DBG_ERROR("unknown property");
@@ -1652,6 +1716,12 @@ uno::Any SAL_CALL ScDPDimension::getPropertyValue( const rtl::OUString& aPropert
else
aRet <<= uno::Sequence<sheet::TableFilterField>(0);
}
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ aRet <<= mpLayoutName.get() ? *mpLayoutName : OUString::createFromAscii("");
+ else if (aNameStr.EqualsAscii(SC_UNO_FIELD_SUBTOTALNAME))
+ aRet <<= mpSubtotalName.get() ? *mpSubtotalName : OUString::createFromAscii("");
+ else if (aNameStr.EqualsAscii(SC_UNO_HAS_HIDDEN_MEMBER))
+ aRet <<= mbHasHiddenMember;
else
{
DBG_ERROR("unknown property");
@@ -2155,7 +2225,11 @@ uno::Sequence<sheet::MemberResult> SAL_CALL ScDPLevel::getResults() throw(uno::R
return aRet;
}
- return pSource->GetData()->getDimensionName( nSrcDim ); // (original) dimension name
+ ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
+ if (!pDim)
+ return rtl::OUString();
+
+ return pDim->getName();
}
void SAL_CALL ScDPLevel::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException)
@@ -2258,6 +2332,20 @@ uno::Any SAL_CALL ScDPLevel::getPropertyValue( const rtl::OUString& aPropertyNam
aRet <<= aAutoShowInfo;
else if ( aNameStr.EqualsAscii( SC_UNO_LAYOUT ) )
aRet <<= aLayoutInfo;
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ // read only property
+ long nSrcDim = pSource->GetSourceDim(nDim);
+ ScDPDimension* pDim = pSource->GetDimensionsObject()->getByIndex(nSrcDim);
+ if (!pDim)
+ return aRet;
+
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (!pLayoutName)
+ return aRet;
+
+ aRet <<= *pLayoutName;
+ }
else
{
DBG_ERROR("unknown property");
@@ -2550,6 +2638,7 @@ ScDPMember::ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL,
nHier( nH ),
nLev( nL ),
maData( rN, fV, bHV ),
+ mpLayoutName(NULL),
nPosition( -1 ),
bVisible( TRUE ),
bShowDet( TRUE )
@@ -2610,6 +2699,11 @@ void ScDPMember::FillItemData( ScDPItemData& rData ) const
rData = maData;
}
+const OUString* ScDPMember::GetLayoutName() const
+{
+ return mpLayoutName.get();
+}
+
String ScDPMember::GetNameStr() const
{
return maData.aString;
@@ -2669,6 +2763,7 @@ uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPMember::getPropertySetInfo(
{MAP_CHAR_LEN(SC_UNO_ISVISIBL), 0, &getBooleanCppuType(), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_POSITION), 0, &getCppuType((sal_Int32*)0), 0, 0 },
{MAP_CHAR_LEN(SC_UNO_SHOWDETA), 0, &getBooleanCppuType(), 0, 0 },
+ {MAP_CHAR_LEN(SC_UNO_LAYOUTNAME), 0, &getCppuType(static_cast<rtl::OUString*>(0)), 0, 0 },
{0,0,0,0,0,0}
};
static uno::Reference<beans::XPropertySetInfo> aRef =
@@ -2692,6 +2787,12 @@ void SAL_CALL ScDPMember::setPropertyValue( const rtl::OUString& aPropertyName,
if (aValue >>= nInt)
setPosition( nInt );
}
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ {
+ rtl::OUString aName;
+ if (aValue >>= aName)
+ mpLayoutName.reset(new rtl::OUString(aName));
+ }
else
{
DBG_ERROR("unknown property");
@@ -2711,6 +2812,8 @@ uno::Any SAL_CALL ScDPMember::getPropertyValue( const rtl::OUString& aPropertyNa
lcl_SetBoolInAny( aRet, getShowDetails() );
else if ( aNameStr.EqualsAscii( SC_UNO_POSITION ) )
aRet <<= (sal_Int32) getPosition();
+ else if (aNameStr.EqualsAscii(SC_UNO_LAYOUTNAME))
+ aRet <<= mpLayoutName.get() ? *mpLayoutName : rtl::OUString();
else
{
DBG_ERROR("unknown property");
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index c8eba91d2cc1..ac4cb9908a3f 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -332,6 +332,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
pInfo->bVOverlapped = FALSE;
pInfo->bAutoFilter = FALSE;
pInfo->bPushButton = FALSE;
+ pInfo->bPopupButton = false;
+ pInfo->bFilterActive = false;
pInfo->nRotateDir = SC_ROTDIR_NONE;
pInfo->bPrinted = FALSE; // view-intern
@@ -458,6 +460,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
BOOL bAutoFilter = ((nOverlap & SC_MF_AUTO) != 0);
BOOL bPushButton = ((nOverlap & SC_MF_BUTTON) != 0);
BOOL bScenario = ((nOverlap & SC_MF_SCENARIO) != 0);
+ bool bPopupButton = ((nOverlap & SC_MF_BUTTON_POPUP) != 0);
+ bool bFilterActive = ((nOverlap & SC_MF_HIDDEN_MEMBER) != 0);
if (bMerged||bHOverlapped||bVOverlapped)
bAnyMerged = TRUE; // intern
@@ -498,6 +502,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
pInfo->bVOverlapped = bVOverlapped;
pInfo->bAutoFilter = bAutoFilter;
pInfo->bPushButton = bPushButton;
+ pInfo->bPopupButton = bPopupButton;
+ pInfo->bFilterActive = bFilterActive;
pInfo->pLinesAttr = pLinesAttr;
pInfo->mpTLBRLine = pTLBRLine;
pInfo->mpBLTRLine = pBLTRLine;
@@ -512,7 +518,7 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX
nCurRow >= aEmbedRange.aStart.Row() &&
nCurRow <= aEmbedRange.aEnd.Row();
- if (bPushButton || bScenario)
+ if (bScenario)
{
pInfo->pBackground = ScGlobal::GetButtonBrushItem();
pThisRowInfo->bEmptyBack = FALSE;
diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx
index e6f8523a3c42..ffeb6cc0684c 100644
--- a/sc/source/core/data/global2.cxx
+++ b/sc/source/core/data/global2.cxx
@@ -56,6 +56,7 @@
#include "sc.hrc"
#include "globstr.hrc"
+using ::std::vector;
// -----------------------------------------------------------------------
@@ -817,7 +818,6 @@ bool PivotField::operator==( const PivotField& r ) const
ScPivotParam::ScPivotParam()
: nCol(0), nRow(0), nTab(0),
- ppLabelArr( NULL ), nLabels(0),
nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0),
bIgnoreEmptyRows(FALSE), bDetectCategories(FALSE),
bMakeTotalCol(TRUE), bMakeTotalRow(TRUE)
@@ -828,23 +828,22 @@ ScPivotParam::ScPivotParam()
ScPivotParam::ScPivotParam( const ScPivotParam& r )
: nCol( r.nCol ), nRow( r.nRow ), nTab( r.nTab ),
- ppLabelArr( NULL ), nLabels(0),
nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0),
bIgnoreEmptyRows(r.bIgnoreEmptyRows),
bDetectCategories(r.bDetectCategories),
bMakeTotalCol(r.bMakeTotalCol),
bMakeTotalRow(r.bMakeTotalRow)
{
- SetLabelData ( r.ppLabelArr, r.nLabels );
SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr,
r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount );
+
+ SetLabelData(r.maLabelArray);
}
//------------------------------------------------------------------------
__EXPORT ScPivotParam::~ScPivotParam()
{
- ClearLabelData();
}
//------------------------------------------------------------------------
@@ -860,22 +859,6 @@ __EXPORT ScPivotParam::~ScPivotParam()
//UNUSED2009-05 ClearPivotArrays();
//UNUSED2009-05 }
-//------------------------------------------------------------------------
-
-void __EXPORT ScPivotParam::ClearLabelData()
-{
- if ( (nLabels > 0) && ppLabelArr )
- {
- for ( SCSIZE i=0; i<nLabels; i++ )
- delete ppLabelArr[i];
- delete [] ppLabelArr;
- ppLabelArr = NULL;
- nLabels = 0;
- }
-}
-
-//------------------------------------------------------------------------
-
void __EXPORT ScPivotParam::ClearPivotArrays()
{
memset( aPageArr, 0, PIVOT_MAXPAGEFIELD * sizeof(PivotField) );
@@ -888,20 +871,17 @@ void __EXPORT ScPivotParam::ClearPivotArrays()
nDataCount = 0;
}
-//------------------------------------------------------------------------
-
-void __EXPORT ScPivotParam::SetLabelData( LabelData** pLabArr,
- SCSIZE nLab )
+void ScPivotParam::SetLabelData(const vector<ScDPLabelDataRef>& r)
{
- ClearLabelData();
-
- if ( (nLab > 0) && pLabArr )
+ vector<ScDPLabelDataRef> aNewArray;
+ aNewArray.reserve(r.size());
+ for (vector<ScDPLabelDataRef>::const_iterator itr = r.begin(), itrEnd = r.end();
+ itr != itrEnd; ++itr)
{
- nLabels = (nLab>MAX_LABELS) ? MAX_LABELS : nLab;
- ppLabelArr = new LabelData*[nLabels];
- for ( SCSIZE i=0; i<nLabels; i++ )
- ppLabelArr[i] = new LabelData( *(pLabArr[i]) );
+ ScDPLabelDataRef p(new ScDPLabelData(**itr));
+ aNewArray.push_back(p);
}
+ maLabelArray.swap(aNewArray);
}
//------------------------------------------------------------------------
@@ -943,10 +923,9 @@ ScPivotParam& __EXPORT ScPivotParam::operator=( const ScPivotParam& r )
bMakeTotalCol = r.bMakeTotalCol;
bMakeTotalRow = r.bMakeTotalRow;
- SetLabelData ( r.ppLabelArr, r.nLabels );
SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr,
r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount );
-
+ SetLabelData(r.maLabelArray);
return *this;
}
@@ -961,7 +940,7 @@ BOOL __EXPORT ScPivotParam::operator==( const ScPivotParam& r ) const
&& (bDetectCategories == r.bDetectCategories)
&& (bMakeTotalCol == r.bMakeTotalCol)
&& (bMakeTotalRow == r.bMakeTotalRow)
- && (nLabels == r.nLabels)
+ && (maLabelArray.size() == r.maLabelArray.size())
&& (nPageCount == r.nPageCount)
&& (nColCount == r.nColCount)
&& (nRowCount == r.nRowCount)
diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk
index d2c700c5f95d..ecd3aad07c0b 100644
--- a/sc/source/core/data/makefile.mk
+++ b/sc/source/core/data/makefile.mk
@@ -79,6 +79,7 @@ SLOFILES = \
$(SLO)$/dpgroup.obj \
$(SLO)$/dpobject.obj \
$(SLO)$/dpoutput.obj \
+ $(SLO)$/dpoutputgeometry.obj \
$(SLO)$/dpsave.obj \
$(SLO)$/dpsdbtab.obj \
$(SLO)$/dpshttab.obj \
@@ -142,6 +143,7 @@ EXCEPTIONSFILES= \
$(SLO)$/dpsdbtab.obj \
$(SLO)$/dpobject.obj \
$(SLO)$/dpoutput.obj \
+ $(SLO)$/dpoutputgeometry.obj \
$(SLO)$/dpsave.obj \
$(SLO)$/dbdocutl.obj \
$(SLO)$/dptabsrc.obj \
diff --git a/sc/source/core/data/pivot2.cxx b/sc/source/core/data/pivot2.cxx
index e12df0cda6e5..951a656d841d 100644
--- a/sc/source/core/data/pivot2.cxx
+++ b/sc/source/core/data/pivot2.cxx
@@ -61,11 +61,26 @@
#include "stlsheet.hxx"
using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::rtl::OUString;
// STATIC DATA -----------------------------------------------------------
// ============================================================================
-LabelData::LabelData( const String& rName, short nCol, bool bIsValue ) :
+ScDPLabelData::Member::Member() :
+ mbVisible(true),
+ mbShowDetails(true)
+{
+}
+
+OUString ScDPLabelData::Member::getDisplayName() const
+{
+ if (maLayoutName.getLength())
+ return maLayoutName;
+
+ return maName;
+}
+
+ScDPLabelData::ScDPLabelData( const String& rName, short nCol, bool bIsValue ) :
maName( rName ),
mnCol( nCol ),
mnFuncMask( PIVOT_FUNC_NONE ),
@@ -75,6 +90,14 @@ LabelData::LabelData( const String& rName, short nCol, bool bIsValue ) :
{
}
+OUString ScDPLabelData::getDisplayName() const
+{
+ if (maLayoutName.getLength())
+ return maLayoutName;
+
+ return maName;
+}
+
// ============================================================================
ScDPFuncData::ScDPFuncData( short nCol, USHORT nFuncMask ) :
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 31f9c18e3d3a..4d0eaf76a976 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -972,6 +972,14 @@ ScBaseCell* ScTable::GetCell( SCCOL nCol, SCROW nRow ) const
return NULL;
}
+void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
+{
+ rCol = 0;
+ rRow = 0;
+ while (aCol[rCol].IsEmptyData() && rCol < MAXCOL)
+ ++rCol;
+ rRow = aCol[rCol].GetFirstDataPos();
+}
void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
{
diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx
index afa66422ca44..6f0f214d3938 100644
--- a/sc/source/filter/excel/read.cxx
+++ b/sc/source/filter/excel/read.cxx
@@ -1192,6 +1192,7 @@ FltError ImportExcel8::Read( void )
case EXC_ID_SXDI: rPTableMgr.ReadSxdi( maStrm ); break;
case EXC_ID_SXVDEX: rPTableMgr.ReadSxvdex( maStrm ); break;
case EXC_ID_SXEX: rPTableMgr.ReadSxex( maStrm ); break;
+ case EXC_ID_SXVIEWEX9: rPTableMgr.ReadSxViewEx9( maStrm ); break;
}
}
break;
@@ -1226,6 +1227,9 @@ FltError ImportExcel8::Read( void )
eLastErr = SCWARN_IMPORT_ROW_OVERFLOW;
else if( rAddrConv.IsColTruncated() )
eLastErr = SCWARN_IMPORT_COLUMN_OVERFLOW;
+
+ if( GetBiff() == EXC_BIFF8 )
+ GetPivotTableManager().MaybeRefreshPivotTables();
}
return eLastErr;
diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx
index bc694d01725e..8680623dc29b 100644
--- a/sc/source/filter/excel/xepivot.cxx
+++ b/sc/source/filter/excel/xepivot.cxx
@@ -67,6 +67,7 @@ using ::com::sun::star::sheet::DataPilotFieldSortInfo;
using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
using ::com::sun::star::sheet::DataPilotFieldLayoutInfo;
using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::rtl::OUString;
using ::rtl::OString;
using ::rtl::OUString;
@@ -975,6 +976,11 @@ void XclExpPTItem::SetPropertiesFromMember( const ScDPSaveMember& rSaveMem )
{
::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN, !rSaveMem.GetIsVisible() );
::set_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL, !rSaveMem.GetShowDetails() );
+
+ // visible name
+ const OUString* pVisName = rSaveMem.GetLayoutName();
+ if (pVisName && !pVisName->equals(GetItemName()))
+ maItemInfo.SetVisName(*pVisName);
}
void XclExpPTItem::WriteBody( XclExpStream& rStrm )
@@ -1032,6 +1038,31 @@ sal_uInt16 XclExpPTField::GetItemIndex( const String& rName, sal_uInt16 nDefault
// fill data --------------------------------------------------------------
+/**
+ * Calc's subtotal names are escaped with backslashes ('\'), while Excel's
+ * are not escaped at all.
+ */
+static OUString lcl_convertCalcSubtotalName(const OUString& rName)
+{
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rName.getStr();
+ sal_Int32 n = rName.getLength();
+ bool bEscaped = false;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (!bEscaped && c == sal_Unicode('\\'))
+ {
+ bEscaped = true;
+ continue;
+ }
+
+ aBuf.append(c);
+ bEscaped = false;
+ }
+ return aBuf.makeStringAndClear();
+}
+
void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
{
// orientation
@@ -1043,8 +1074,16 @@ void XclExpPTField::SetPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
::set_flag( maFieldExtInfo.mnFlags, EXC_SXVDEX_SHOWALL, rSaveDim.GetShowEmpty() );
// visible name
- if( rSaveDim.HasLayoutName() && (rSaveDim.GetLayoutName() != GetFieldName()) )
- maFieldInfo.SetVisName( rSaveDim.GetLayoutName() );
+ const OUString* pLayoutName = rSaveDim.GetLayoutName();
+ if (pLayoutName && !pLayoutName->equals(GetFieldName()))
+ maFieldInfo.SetVisName(*pLayoutName);
+
+ const rtl::OUString* pSubtotalName = rSaveDim.GetSubtotalName();
+ if (pSubtotalName)
+ {
+ OUString aSubName = lcl_convertCalcSubtotalName(*pSubtotalName);
+ maFieldExtInfo.mpFieldTotalName.reset(new rtl::OUString(aSubName));
+ }
// subtotals
XclPTSubtotalVec aSubtotals;
@@ -1111,7 +1150,11 @@ void XclExpPTField::SetDataPropertiesFromDim( const ScDPSaveDimension& rSaveDim
rDataInfo.SetApiAggFunc( eFunc );
// visible name
- rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) );
+ const rtl::OUString* pVisName = rSaveDim.GetLayoutName();
+ if (pVisName)
+ rDataInfo.SetVisName(*pVisName);
+ else
+ rDataInfo.SetVisName( lclGetDataFieldCaption( GetFieldName(), eFunc ) );
// result field reference
if( const DataPilotFieldReference* pFieldRef = rSaveDim.GetReferenceValue() )
@@ -1220,9 +1263,10 @@ XclExpPivotTable::XclExpPivotTable( const XclExpRoot& rRoot, const ScDPObject& r
// pivot table properties from DP object
mnOutScTab = rOutScRange.aStart.Tab();
maPTInfo.maTableName = rDPObj.GetName();
- maPTInfo.maDataName = ScGlobal::GetRscString( STR_PIVOT_DATA );
maPTInfo.mnCacheIdx = mrPCache.GetCacheIndex();
+ maPTViewEx9Info.Init( rDPObj );
+
if( const ScDPSaveData* pSaveData = rDPObj.GetSaveData() )
{
// additional properties from ScDPSaveData
@@ -1302,6 +1346,10 @@ void XclExpPivotTable::Save( XclExpStream& rStrm )
WriteSxli( rStrm, maPTInfo.mnDataCols, maPTInfo.mnColFields );
// SXEX
WriteSxex( rStrm );
+ // QSISXTAG
+ WriteQsiSxTag( rStrm );
+ // SXVIEWEX9
+ WriteSxViewEx9( rStrm );
}
}
@@ -1335,6 +1383,15 @@ void XclExpPivotTable::SetPropertiesFromDP( const ScDPSaveData& rSaveData )
::set_flag( maPTInfo.mnFlags, EXC_SXVIEW_COLGRAND, rSaveData.GetColumnGrand() );
::set_flag( maPTExtInfo.mnFlags, EXC_SXEX_DRILLDOWN, rSaveData.GetDrillDown() );
mbFilterBtn = rSaveData.GetFilterButton();
+ const ScDPSaveDimension* pDim = rSaveData.GetExistingDataLayoutDimension();
+ if (!pDim)
+ return;
+
+ const rtl::OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ maPTInfo.maDataName = *pLayoutName;
+ else
+ maPTInfo.maDataName = ScGlobal::GetRscString(STR_PIVOT_DATA);
}
void XclExpPivotTable::SetFieldPropertiesFromDim( const ScDPSaveDimension& rSaveDim )
@@ -1442,13 +1499,21 @@ void XclExpPivotTable::Finalize()
rnDataXclRow = rnXclRow1 + maPTInfo.mnColFields + 1;
if( maDataFields.empty() )
++rnDataXclRow;
+
+ bool bExtraHeaderRow = (0 == maPTViewEx9Info.mnGridLayout && maPTInfo.mnColFields == 0);
+ if (bExtraHeaderRow)
+ // Insert an extra row only when there is no column field.
+ ++rnDataXclRow;
+
rnXclCol2 = ::std::max( rnXclCol2, rnDataXclCol );
rnXclRow2 = ::std::max( rnXclRow2, rnDataXclRow );
maPTInfo.mnDataCols = rnXclCol2 - rnDataXclCol + 1;
maPTInfo.mnDataRows = rnXclRow2 - rnDataXclRow + 1;
// first heading
- maPTInfo.mnFirstHeadRow = rnXclRow1 + 1;
+ maPTInfo.mnFirstHeadRow = rnXclRow1;
+ if (bExtraHeaderRow)
+ maPTInfo.mnFirstHeadRow += 2;
}
// records ----------------------------------------------------------------
@@ -1528,6 +1593,72 @@ void XclExpPivotTable::WriteSxex( XclExpStream& rStrm ) const
rStrm.EndRecord();
}
+void XclExpPivotTable::WriteQsiSxTag( XclExpStream& rStrm ) const
+{
+ rStrm.StartRecord( 0x0802, 32 );
+
+ sal_uInt16 nRecordType = 0x0802;
+ sal_uInt16 nDummyFlags = 0x0000;
+ sal_uInt16 nTableType = 1; // 0 = query table : 1 = pivot table
+
+ rStrm << nRecordType << nDummyFlags << nTableType;
+
+ // General flags
+ bool bEnableRefresh = true;
+ bool bPCacheInvalid = false;
+ bool bOlapPTReport = false;
+
+ sal_uInt16 nFlags = 0x0000;
+ if (bEnableRefresh) nFlags |= 0x0001;
+ if (bPCacheInvalid) nFlags |= 0x0002;
+ if (bOlapPTReport) nFlags |= 0x0004;
+ rStrm << nFlags;
+
+ // Feature-specific options. The value differs depending on the table
+ // type, but we assume the table type is always pivot table.
+ sal_uInt32 nOptions = 0x00000000;
+ bool bNoStencil = false;
+ bool bHideTotal = false;
+ bool bEmptyRows = false;
+ bool bEmptyCols = false;
+ if (bNoStencil) nOptions |= 0x00000001;
+ if (bHideTotal) nOptions |= 0x00000002;
+ if (bEmptyRows) nOptions |= 0x00000008;
+ if (bEmptyCols) nOptions |= 0x00000010;
+ rStrm << nOptions;
+
+ enum ExcelVersion
+ {
+ Excel2000 = 0,
+ ExcelXP = 1,
+ Excel2003 = 2,
+ Excel2007 = 3
+ };
+ ExcelVersion eXclVer = Excel2000;
+ sal_uInt8 nOffsetBytes = 16;
+ rStrm << static_cast<sal_uInt8>(eXclVer) // version table last refreshed
+ << static_cast<sal_uInt8>(eXclVer) // minimum version to refresh
+ << nOffsetBytes
+ << static_cast<sal_uInt8>(eXclVer); // first version created
+
+ rStrm << XclExpString(maPTInfo.maTableName);
+ rStrm << static_cast<sal_uInt16>(0x0001); // no idea what this is for.
+
+ rStrm.EndRecord();
+}
+
+void XclExpPivotTable::WriteSxViewEx9( XclExpStream& rStrm ) const
+{
+ // Until we sync the autoformat ids only export if using grid header layout
+ // That could only have been set via xls import so far.
+ if ( 0 == maPTViewEx9Info.mnGridLayout )
+ {
+ rStrm.StartRecord( EXC_ID_SXVIEWEX9, 17 );
+ rStrm << maPTViewEx9Info;
+ rStrm.EndRecord();
+ }
+}
+
// ============================================================================
namespace {
diff --git a/sc/source/filter/excel/xestring.cxx b/sc/source/filter/excel/xestring.cxx
index 9af8dbfdd851..b657e3b1f1d0 100644
--- a/sc/source/filter/excel/xestring.cxx
+++ b/sc/source/filter/excel/xestring.cxx
@@ -423,7 +423,8 @@ void XclExpString::WriteFormats( XclExpStream& rStrm, bool bWriteSize ) const
void XclExpString::Write( XclExpStream& rStrm ) const
{
- WriteHeader( rStrm );
+ if (!mbSkipHeader)
+ WriteHeader( rStrm );
WriteBuffer( rStrm );
if( IsWriteFormats() ) // only in BIFF8 included in string
WriteFormats( rStrm );
@@ -589,6 +590,7 @@ void XclExpString::Init( sal_Int32 nCurrLen, XclStrFlags nFlags, sal_uInt16 nMax
mbSmartFlags = bBiff8 && ::get_flag( nFlags, EXC_STR_SMARTFLAGS );
mbSkipFormats = ::get_flag( nFlags, EXC_STR_SEPARATEFORMATS );
mbWrapped = false;
+ mbSkipHeader = ::get_flag( nFlags, EXC_STR_NOHEADER );
mnMaxLen = nMaxLen;
SetStrLen( nCurrLen );
diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx
index 419cbb3d6168..dece34280d8b 100644
--- a/sc/source/filter/excel/xiescher.cxx
+++ b/sc/source/filter/excel/xiescher.cxx
@@ -1422,38 +1422,121 @@ void XclImpTextObj::DoProcessSdrObj( SdrObject& rSdrObj ) const
(with no content) while exporting to XLS, which can cause a
corrupted exported document. */
- // horizontal text alignment
SvxAdjust eHorAlign = SVX_ADJUST_LEFT;
- switch( maTextData.maData.GetHorAlign() )
- {
- case EXC_OBJ_HOR_LEFT: eHorAlign = SVX_ADJUST_LEFT; break;
- case EXC_OBJ_HOR_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
- case EXC_OBJ_HOR_RIGHT: eHorAlign = SVX_ADJUST_RIGHT; break;
- case EXC_OBJ_HOR_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
- }
- rSdrObj.SetMergedItem( SvxAdjustItem( eHorAlign, EE_PARA_JUST ) );
-
- // vertical text alignment
SdrTextVertAdjust eVerAlign = SDRTEXTVERTADJUST_TOP;
- switch( maTextData.maData.GetVerAlign() )
- {
- case EXC_OBJ_VER_TOP: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
- case EXC_OBJ_VER_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
- case EXC_OBJ_VER_BOTTOM: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
- case EXC_OBJ_VER_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
- }
- rSdrObj.SetMergedItem( SdrTextVertAdjustItem( eVerAlign ) );
// orientation (this is only a fake, drawing does not support real text orientation)
namespace csst = ::com::sun::star::text;
csst::WritingMode eWriteMode = csst::WritingMode_LR_TB;
switch( maTextData.maData.mnOrient )
{
- case EXC_OBJ_ORIENT_NONE: eWriteMode = csst::WritingMode_LR_TB; break;
- case EXC_OBJ_ORIENT_STACKED: eWriteMode = csst::WritingMode_TB_RL; break;
- case EXC_OBJ_ORIENT_90CCW: eWriteMode = csst::WritingMode_TB_RL; break;
- case EXC_OBJ_ORIENT_90CW: eWriteMode = csst::WritingMode_TB_RL; break;
+ default:
+ case EXC_OBJ_ORIENT_NONE:
+ {
+ eWriteMode = csst::WritingMode_LR_TB;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: eHorAlign = SVX_ADJUST_LEFT; break;
+ case EXC_OBJ_HOR_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
+ case EXC_OBJ_HOR_RIGHT: eHorAlign = SVX_ADJUST_RIGHT; break;
+ case EXC_OBJ_HOR_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
+ }
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
+ case EXC_OBJ_VER_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
+ case EXC_OBJ_VER_BOTTOM: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
+ case EXC_OBJ_VER_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
+ }
+ }
+ break;
+
+ case EXC_OBJ_ORIENT_90CCW:
+ {
+ if( SdrObjCustomShape* pObjCustomShape = dynamic_cast< SdrObjCustomShape* >( &rSdrObj ) )
+ {
+ double fAngle = 180.0;
+ com::sun::star::beans::PropertyValue aTextRotateAngle;
+ aTextRotateAngle.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
+ aTextRotateAngle.Value <<= fAngle;
+ SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)pObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
+ aGeometryItem.SetPropertyValue( aTextRotateAngle );
+ pObjCustomShape->SetMergedItem( aGeometryItem );
+ }
+ eWriteMode = csst::WritingMode_TB_RL;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
+ case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
+ case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
+ case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
+ }
+ MSO_Anchor eTextAnchor = (MSO_Anchor)GetObjectManager().GetDffManager().GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+ switch( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ {
+ eHorAlign = SVX_ADJUST_CENTER;
+ }
+ break;
+
+ default:
+ {
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_RIGHT; break;
+ case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
+ case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_LEFT; break;
+ case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
+ }
+ }
+ }
+ }
+ break;
+
+ case EXC_OBJ_ORIENT_STACKED: // PASSTHROUGH INTENDED
+ {
+ // sj: STACKED is not supported, maybe it can be optimized here a bit
+ }
+ case EXC_OBJ_ORIENT_90CW:
+ {
+ eWriteMode = csst::WritingMode_TB_RL;
+ switch( maTextData.maData.GetHorAlign() )
+ {
+ case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
+ case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
+ case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
+ case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
+ }
+ MSO_Anchor eTextAnchor = (MSO_Anchor)GetObjectManager().GetDffManager().GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
+ switch ( eTextAnchor )
+ {
+ case mso_anchorTopCentered :
+ case mso_anchorMiddleCentered :
+ case mso_anchorBottomCentered :
+ {
+ eHorAlign = SVX_ADJUST_CENTER;
+ }
+ break;
+
+ default:
+ {
+ switch( maTextData.maData.GetVerAlign() )
+ {
+ case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_LEFT; break;
+ case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
+ case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_RIGHT; break;
+ case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
+ }
+ }
+ }
+ }
+ break;
}
+ rSdrObj.SetMergedItem( SvxAdjustItem( eHorAlign, EE_PARA_JUST ) );
+ rSdrObj.SetMergedItem( SdrTextVertAdjustItem( eVerAlign ) );
rSdrObj.SetMergedItem( SvxWritingModeItem( eWriteMode, SDRATTR_TEXTDIRECTION ) );
}
}
diff --git a/sc/source/filter/excel/xipivot.cxx b/sc/source/filter/excel/xipivot.cxx
index 56532f1281cc..687dfb9333fe 100644
--- a/sc/source/filter/excel/xipivot.cxx
+++ b/sc/source/filter/excel/xipivot.cxx
@@ -48,7 +48,9 @@
#include "dpdimsave.hxx"
#include "dpobject.hxx"
#include "dpshttab.hxx"
+#include "dpoutputgeometry.hxx"
#include "scitems.hxx"
+#include "attrib.hxx"
#include "xltracer.hxx"
#include "xistream.hxx"
@@ -60,13 +62,17 @@
#include "excform.hxx"
#include "xltable.hxx"
+#include <vector>
+
using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
using ::com::sun::star::sheet::DataPilotFieldOrientation;
using ::com::sun::star::sheet::DataPilotFieldOrientation_DATA;
using ::com::sun::star::sheet::DataPilotFieldSortInfo;
using ::com::sun::star::sheet::DataPilotFieldAutoShowInfo;
using ::com::sun::star::sheet::DataPilotFieldLayoutInfo;
using ::com::sun::star::sheet::DataPilotFieldReference;
+using ::std::vector;
// ============================================================================
// Pivot cache
@@ -847,6 +853,11 @@ void XclImpPivotCache::ReadPivotCacheStream( XclImpStream& rStrm )
}
}
+bool XclImpPivotCache::IsRefreshOnLoad() const
+{
+ return static_cast<bool>(maPCInfo.mnFlags & 0x0004);
+}
+
// ============================================================================
// Pivot table
// ============================================================================
@@ -882,6 +893,8 @@ void XclImpPTItem::ConvertItem( ScDPSaveDimension& rSaveDim ) const
ScDPSaveMember& rMember = *rSaveDim.GetMemberByName( *pItemName );
rMember.SetIsVisible( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDDEN ) );
rMember.SetShowDetails( !::get_flag( maItemInfo.mnFlags, EXC_SXVI_HIDEDETAIL ) );
+ if (maItemInfo.HasVisName())
+ rMember.SetLayoutName(*maItemInfo.GetVisName());
}
}
@@ -1022,6 +1035,28 @@ void XclImpPTField::ConvertDataField( ScDPSaveData& rSaveData ) const
// private --------------------------------------------------------------------
+/**
+ * Convert Excel-encoded subtotal name to a Calc-encoded one.
+ */
+static OUString lcl_convertExcelSubtotalName(const OUString& rName)
+{
+ OUStringBuffer aBuf;
+ const sal_Unicode* p = rName.getStr();
+ sal_Int32 n = rName.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ const sal_Unicode c = p[i];
+ if (c == sal_Unicode('\\'))
+ {
+ aBuf.append(c);
+ aBuf.append(c);
+ }
+ else
+ aBuf.append(c);
+ }
+ return aBuf.makeStringAndClear();
+}
+
ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) const
{
const String& rFieldName = GetFieldName();
@@ -1043,7 +1078,7 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con
// visible name
if( const String* pVisName = maFieldInfo.GetVisName() )
if( pVisName->Len() > 0 )
- rSaveDim.SetLayoutName( pVisName );
+ rSaveDim.SetLayoutName( *pVisName );
// subtotal function(s)
XclPTSubtotalVec aSubtotalVec;
@@ -1075,6 +1110,13 @@ ScDPSaveDimension* XclImpPTField::ConvertRCPField( ScDPSaveData& rSaveData ) con
// grouping info
pCacheField->ConvertGroupField( rSaveData, mrPTable.GetVisFieldNames() );
+ // custom subtotal name
+ if (maFieldExtInfo.mpFieldTotalName.get())
+ {
+ OUString aSubName = lcl_convertExcelSubtotalName(*maFieldExtInfo.mpFieldTotalName);
+ rSaveDim.SetSubtotalName(aSubName);
+ }
+
return &rSaveDim;
}
@@ -1099,7 +1141,7 @@ void XclImpPTField::ConvertDataFieldInfo( ScDPSaveDimension& rSaveDim, const Xcl
// visible name
if( const String* pVisName = rDataInfo.GetVisName() )
if( pVisName->Len() > 0 )
- rSaveDim.SetLayoutName( pVisName );
+ rSaveDim.SetLayoutName( *pVisName );
// aggregation function
rSaveDim.SetFunction( static_cast< USHORT >( rDataInfo.GetApiAggFunc() ) );
@@ -1134,7 +1176,8 @@ void XclImpPTField::ConvertItems( ScDPSaveDimension& rSaveDim ) const
XclImpPivotTable::XclImpPivotTable( const XclImpRoot& rRoot ) :
XclImpRoot( rRoot ),
- maDataOrientField( *this, EXC_SXIVD_DATA )
+ maDataOrientField( *this, EXC_SXIVD_DATA ),
+ mpDPObj(NULL)
{
}
@@ -1296,6 +1339,11 @@ void XclImpPivotTable::ReadSxex( XclImpStream& rStrm )
rStrm >> maPTExtInfo;
}
+void XclImpPivotTable::ReadSxViewEx9( XclImpStream& rStrm )
+{
+ rStrm >> maPTViewEx9Info;
+}
+
// ----------------------------------------------------------------------------
void XclImpPivotTable::Convert()
@@ -1331,6 +1379,10 @@ void XclImpPivotTable::Convert()
if( const XclImpPTField* pField = GetField( *aIt ) )
pField->ConvertPageField( aSaveData );
+ // We need to import hidden fields because hidden fields may contain
+ // special settings for subtotals (aggregation function, filters, custom
+ // name etc.) and members (hidden, custom name etc.).
+
// hidden fields
for( sal_uInt16 nField = 0, nCount = GetFieldCount(); nField < nCount; ++nField )
if( const XclImpPTField* pField = GetField( nField ) )
@@ -1359,11 +1411,112 @@ void XclImpPivotTable::Convert()
// create the DataPilot
ScDPObject* pDPObj = new ScDPObject( GetDocPtr() );
pDPObj->SetName( maPTInfo.maTableName );
+ if (maPTInfo.maDataName.Len() > 0)
+ aSaveData.GetDataLayoutDimension()->SetLayoutName(maPTInfo.maDataName);
+
+ if (maPTViewEx9Info.maGrandTotalName.Len() > 0)
+ aSaveData.SetGrandTotalName(maPTViewEx9Info.maGrandTotalName);
+
pDPObj->SetSaveData( aSaveData );
pDPObj->SetSheetDesc( aDesc );
pDPObj->SetOutRange( aOutRange );
pDPObj->SetAlive( TRUE );
- GetDoc().GetDPCollection()->Insert( pDPObj );
+ pDPObj->SetHeaderLayout( maPTViewEx9Info.mnGridLayout == 0 );
+
+ GetDoc().GetDPCollection()->InsertNewTable(pDPObj);
+ mpDPObj = pDPObj;
+
+ ApplyMergeFlags(aOutRange, aSaveData);
+}
+
+void XclImpPivotTable::MaybeRefresh()
+{
+ if (mpDPObj && mxPCache->IsRefreshOnLoad())
+ {
+ // 'refresh table on load' flag is set. Refresh the table now. Some
+ // Excel files contain partial table output when this flag is set.
+ ScRange aOutRange = mpDPObj->GetOutRange();
+ mpDPObj->Output(aOutRange.aStart);
+ }
+}
+
+void XclImpPivotTable::ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData)
+{
+ // Apply merge flags for varoius datapilot controls.
+
+ ScDPOutputGeometry aGeometry(rOutRange, false, ScDPOutputGeometry::XLS);
+ aGeometry.setColumnFieldCount(maPTInfo.mnColFields);
+ aGeometry.setPageFieldCount(maPTInfo.mnPageFields);
+ aGeometry.setDataFieldCount(maPTInfo.mnDataFields);
+
+ // Excel includes data layout field in the row field count. We need to
+ // subtract it.
+ bool bDataLayout = maPTInfo.mnDataFields > 1;
+ aGeometry.setRowFieldCount(maPTInfo.mnRowFields - static_cast<sal_uInt32>(bDataLayout));
+
+ ScDocument& rDoc = GetDoc();
+
+ vector<ScAddress> aPageBtns;
+ aGeometry.getPageFieldPositions(aPageBtns);
+ vector<ScAddress>::const_iterator itr = aPageBtns.begin(), itrEnd = aPageBtns.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ sal_uInt16 nMFlag = SC_MF_BUTTON;
+ String aName;
+ rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
+ if (rSaveData.HasInvisibleMember(aName))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
+ rDoc.ApplyFlagsTab(itr->Col()+1, itr->Row(), itr->Col()+1, itr->Row(), itr->Tab(), SC_MF_AUTO);
+ }
+
+ vector<ScAddress> aColBtns;
+ aGeometry.getColumnFieldPositions(aColBtns);
+ itr = aColBtns.begin();
+ itrEnd = aColBtns.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP;
+ String aName;
+ rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
+ if (rSaveData.HasInvisibleMember(aName))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
+ }
+
+ vector<ScAddress> aRowBtns;
+ aGeometry.getRowFieldPositions(aRowBtns);
+ if (aRowBtns.empty())
+ {
+ if (bDataLayout)
+ {
+ // No row fields, but the data layout button exists.
+ SCROW nRow = aGeometry.getRowFieldHeaderRow();
+ SCCOL nCol = rOutRange.aStart.Col();
+ SCTAB nTab = rOutRange.aStart.Tab();
+ rDoc.ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON);
+ }
+ }
+ else
+ {
+ itr = aRowBtns.begin();
+ itrEnd = aRowBtns.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ sal_Int16 nMFlag = SC_MF_BUTTON | SC_MF_BUTTON_POPUP;
+ String aName;
+ rDoc.GetString(itr->Col(), itr->Row(), itr->Tab(), aName);
+ if (rSaveData.HasInvisibleMember(aName))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), nMFlag);
+ }
+ if (bDataLayout)
+ {
+ --itr; // move back to the last row field position.
+ rDoc.ApplyFlagsTab(itr->Col(), itr->Row(), itr->Col(), itr->Row(), itr->Tab(), SC_MF_BUTTON);
+ }
+ }
}
// ============================================================================
@@ -1458,6 +1611,12 @@ void XclImpPivotTableManager::ReadSxex( XclImpStream& rStrm )
maPTables.back()->ReadSxex( rStrm );
}
+void XclImpPivotTableManager::ReadSxViewEx9( XclImpStream& rStrm )
+{
+ if( !maPTables.empty() )
+ maPTables.back()->ReadSxViewEx9( rStrm );
+}
+
// ----------------------------------------------------------------------------
void XclImpPivotTableManager::ReadPivotCaches( XclImpStream& rStrm )
@@ -1472,5 +1631,11 @@ void XclImpPivotTableManager::ConvertPivotTables()
(*aIt)->Convert();
}
+void XclImpPivotTableManager::MaybeRefreshPivotTables()
+{
+ for( XclImpPivotTableVec::iterator aIt = maPTables.begin(), aEnd = maPTables.end(); aIt != aEnd; ++aIt )
+ (*aIt)->MaybeRefresh();
+}
+
// ============================================================================
diff --git a/sc/source/filter/excel/xlpivot.cxx b/sc/source/filter/excel/xlpivot.cxx
index d36950b2494d..8f5d026379d9 100644
--- a/sc/source/filter/excel/xlpivot.cxx
+++ b/sc/source/filter/excel/xlpivot.cxx
@@ -31,6 +31,7 @@
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
#include "dpgroup.hxx"
+#include "dpsave.hxx"
#include "xestream.hxx"
#include "xistream.hxx"
#include "xestring.hxx"
@@ -581,7 +582,9 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldInfo& rInfo )
XclPTFieldExtInfo::XclPTFieldExtInfo() :
mnFlags( EXC_SXVDEX_DEFAULTFLAGS ),
mnSortField( EXC_SXVDEX_SORT_OWN ),
- mnShowField( EXC_SXVDEX_SHOW_NONE )
+ mnShowField( EXC_SXVDEX_SHOW_NONE ),
+ mnNumFmt(0),
+ mpFieldTotalName(NULL)
{
}
@@ -639,10 +642,19 @@ void XclPTFieldExtInfo::SetApiLayoutMode( sal_Int32 nLayoutMode )
XclImpStream& operator>>( XclImpStream& rStrm, XclPTFieldExtInfo& rInfo )
{
- return rStrm
- >> rInfo.mnFlags
- >> rInfo.mnSortField
- >> rInfo.mnShowField;
+ sal_uInt8 nNameLen = 0;
+ rStrm >> rInfo.mnFlags
+ >> rInfo.mnSortField
+ >> rInfo.mnShowField
+ >> rInfo.mnNumFmt
+ >> nNameLen;
+
+ rStrm.Ignore(10);
+ if (nNameLen != 0xFF)
+ // Custom field total name is used. Pick it up.
+ rInfo.mpFieldTotalName.reset(new rtl::OUString(rStrm.ReadUniString(nNameLen, 0)));
+
+ return rStrm;
}
XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
@@ -650,9 +662,23 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTFieldExtInfo& rInfo )
rStrm << rInfo.mnFlags
<< rInfo.mnSortField
<< rInfo.mnShowField
- << EXC_SXVDEX_FORMAT_NONE
- << sal_uInt16( 0xFFFF ); // unknown
- rStrm.WriteZeroBytes( 8 ); // unknown
+ << EXC_SXVDEX_FORMAT_NONE;
+
+ if (rInfo.mpFieldTotalName.get() && rInfo.mpFieldTotalName->getLength() > 0)
+ {
+ rtl::OUString aFinalName = *rInfo.mpFieldTotalName;
+ if (aFinalName.getLength() >= 254)
+ aFinalName = aFinalName.copy(0, 254);
+ sal_uInt8 nNameLen = static_cast<sal_uInt8>(aFinalName.getLength());
+ rStrm << nNameLen;
+ rStrm.WriteZeroBytes(10);
+ rStrm << XclExpString(aFinalName, EXC_STR_NOHEADER);
+ }
+ else
+ {
+ rStrm << sal_uInt16(0xFFFF);
+ rStrm.WriteZeroBytes(8);
+ }
return rStrm;
}
@@ -923,3 +949,86 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo )
// ============================================================================
+// Pivot table autoformat settings ============================================
+
+/**
+classic : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
+default : 10 08 00 00 00 00 00 00 20 00 00 00 01 00 00 00 00
+report01 : 10 08 02 00 00 00 00 00 20 00 00 00 00 10 00 00 00
+report02 : 10 08 02 00 00 00 00 00 20 00 00 00 01 10 00 00 00
+report03 : 10 08 02 00 00 00 00 00 20 00 00 00 02 10 00 00 00
+report04 : 10 08 02 00 00 00 00 00 20 00 00 00 03 10 00 00 00
+report05 : 10 08 02 00 00 00 00 00 20 00 00 00 04 10 00 00 00
+report06 : 10 08 02 00 00 00 00 00 20 00 00 00 05 10 00 00 00
+report07 : 10 08 02 00 00 00 00 00 20 00 00 00 06 10 00 00 00
+report08 : 10 08 02 00 00 00 00 00 20 00 00 00 07 10 00 00 00
+report09 : 10 08 02 00 00 00 00 00 20 00 00 00 08 10 00 00 00
+report10 : 10 08 02 00 00 00 00 00 20 00 00 00 09 10 00 00 00
+table01 : 10 08 00 00 00 00 00 00 20 00 00 00 0a 10 00 00 00
+table02 : 10 08 00 00 00 00 00 00 20 00 00 00 0b 10 00 00 00
+table03 : 10 08 00 00 00 00 00 00 20 00 00 00 0c 10 00 00 00
+table04 : 10 08 00 00 00 00 00 00 20 00 00 00 0d 10 00 00 00
+table05 : 10 08 00 00 00 00 00 00 20 00 00 00 0e 10 00 00 00
+table06 : 10 08 00 00 00 00 00 00 20 00 00 00 0f 10 00 00 00
+table07 : 10 08 00 00 00 00 00 00 20 00 00 00 10 10 00 00 00
+table08 : 10 08 00 00 00 00 00 00 20 00 00 00 11 10 00 00 00
+table09 : 10 08 00 00 00 00 00 00 20 00 00 00 12 10 00 00 00
+table10 : 10 08 00 00 00 00 00 00 20 00 00 00 13 10 00 00 00
+none : 10 08 00 00 00 00 00 00 20 00 00 00 15 10 00 00 00
+**/
+
+XclPTViewEx9Info::XclPTViewEx9Info() :
+ mbReport( 0 ),
+ mnAutoFormat( 0 ),
+ mnGridLayout( 0x10 )
+{
+}
+
+void XclPTViewEx9Info::Init( const ScDPObject& rDPObj )
+{
+ if( rDPObj.GetHeaderLayout() )
+ {
+ mbReport = 0;
+ mnAutoFormat = 1;
+ mnGridLayout = 0;
+ }
+ else
+ {
+ // Report1 for now
+ // TODO : sync with autoformat indicies
+ mbReport = 2;
+ mnAutoFormat = 1;
+ mnGridLayout = 0x10;
+ }
+
+ const ScDPSaveData* pData = rDPObj.GetSaveData();
+ if (pData)
+ {
+ const rtl::OUString* pGrandTotal = pData->GetGrandTotalName();
+ if (pGrandTotal)
+ maGrandTotalName = *pGrandTotal;
+ }
+}
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo )
+{
+ rStrm.Ignore( 2 );
+ rStrm >> rInfo.mbReport; /// 2 for report* fmts ?
+ rStrm.Ignore( 6 );
+ rStrm >> rInfo.mnAutoFormat >> rInfo.mnGridLayout;
+ rInfo.maGrandTotalName = rStrm.ReadUniString();
+ return rStrm;
+}
+
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo )
+{
+ return rStrm
+ << EXC_PT_AUTOFMT_HEADER
+ << rInfo.mbReport
+ << EXC_PT_AUTOFMT_ZERO
+ << EXC_PT_AUTOFMT_FLAGS
+ << rInfo.mnAutoFormat
+ << rInfo.mnGridLayout
+ << XclExpString(rInfo.maGrandTotalName, EXC_STR_DEFAULT, EXC_PT_MAXSTRLEN);
+}
+
diff --git a/sc/source/filter/inc/xepivot.hxx b/sc/source/filter/inc/xepivot.hxx
index 28df1586cdcb..716f0bf7a515 100644
--- a/sc/source/filter/inc/xepivot.hxx
+++ b/sc/source/filter/inc/xepivot.hxx
@@ -413,6 +413,10 @@ private:
/** Writes the SXEX records containing additional pivot table info. */
void WriteSxex( XclExpStream& rStrm ) const;
+ void WriteQsiSxTag( XclExpStream& rStrm ) const;
+ /** Writes the SX_AUTOFORMAT records with the autoformat id and header layout */
+ void WriteSxViewEx9( XclExpStream& rStrm ) const;
+
// ------------------------------------------------------------------------
private:
typedef XclExpRecordList< XclExpPTField > XclExpPTFieldList;
@@ -422,6 +426,7 @@ private:
const XclExpPivotCache& mrPCache; /// The pivot cache this pivot table bases on.
XclPTInfo maPTInfo; /// Info about the pivot table (SXVIEW record).
XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
+ XclPTViewEx9Info maPTViewEx9Info; /// The selected autoformat (SXVIEWEX9)
XclExpPTFieldList maFieldList; /// All fields in pivot cache order.
ScfUInt16Vec maRowFields; /// Row field indexes.
ScfUInt16Vec maColFields; /// Column field indexes.
diff --git a/sc/source/filter/inc/xestring.hxx b/sc/source/filter/inc/xestring.hxx
index 69a1a7af09fb..5fe5e4fb813f 100644
--- a/sc/source/filter/inc/xestring.hxx
+++ b/sc/source/filter/inc/xestring.hxx
@@ -323,6 +323,7 @@ private:
bool mbSmartFlags; /// true = omit flags on empty string; false = always write flags.
bool mbSkipFormats; /// true = skip formats on export; false = write complete formatted string.
bool mbWrapped; /// true = text contains several paragraphs.
+ bool mbSkipHeader; /// ture = skip length and flags when writing string bytes.
};
inline bool operator==( const XclExpString& rLeft, const XclExpString& rRight )
diff --git a/sc/source/filter/inc/xiescher.hxx b/sc/source/filter/inc/xiescher.hxx
index 3eb5a7257630..f551b90e10f7 100644
--- a/sc/source/filter/inc/xiescher.hxx
+++ b/sc/source/filter/inc/xiescher.hxx
@@ -979,7 +979,7 @@ class SdrObjList;
/** Derived from SvxMSDffManager and SvxMSConvertOCXControls, contains core
implementation of DFF stream import and OCX form control import.
*/
-class XclImpDffManager : protected XclImpSimpleDffManager, protected SvxMSConvertOCXControls
+class XclImpDffManager : public XclImpSimpleDffManager, protected SvxMSConvertOCXControls
{
public:
explicit XclImpDffManager(
diff --git a/sc/source/filter/inc/xipivot.hxx b/sc/source/filter/inc/xipivot.hxx
index 52b55509219b..9e0e577b1756 100644
--- a/sc/source/filter/inc/xipivot.hxx
+++ b/sc/source/filter/inc/xipivot.hxx
@@ -186,6 +186,8 @@ public:
/** Reads the entire pivot cache stream. Uses decrypter from passed stream. */
void ReadPivotCacheStream( XclImpStream& rStrm );
+ bool IsRefreshOnLoad() const;
+
private:
typedef ::std::vector< XclImpPCFieldRef > XclImpPCFieldVec;
@@ -350,12 +352,19 @@ public:
void ReadSxdi( XclImpStream& rStrm );
/** Reads an SXEX record containing additional settings for the pivot table. */
void ReadSxex( XclImpStream& rStrm );
+ /** Reads an SXVIEWEX9 record that specifies the pivot tables
+ * autoformat. */
+ void ReadSxViewEx9( XclImpStream& rStrm );
// ------------------------------------------------------------------------
/** Inserts the pivot table into the Calc document. */
void Convert();
+ void MaybeRefresh();
+
+ void ApplyMergeFlags(const ScRange& rOutRange, const ScDPSaveData& rSaveData);
+
// ------------------------------------------------------------------------
private:
typedef ::std::vector< XclImpPTFieldRef > XclImpPTFieldVec;
@@ -364,6 +373,7 @@ private:
XclPTInfo maPTInfo; /// General info about the pivot table (SXVIEW record).
XclPTExtInfo maPTExtInfo; /// Extended info about the pivot table (SXEX record).
+ XclPTViewEx9Info maPTViewEx9Info; /// (SXVIEWEX9 record)
XclImpPTFieldVec maFields; /// Vector containing all fields.
XclImpPTFieldRef mxCurrField; /// Current field for importing additional info.
ScfStringVec maVisFieldNames; /// Vector containing all visible field names.
@@ -374,6 +384,7 @@ private:
ScfUInt16Vec maFiltDataFields; /// Filtered data field indexes.
XclImpPTField maDataOrientField; /// Special data field orientation field.
ScRange maOutScRange; /// Output range in the Calc document.
+ ScDPObject* mpDPObj;
};
typedef ScfRef< XclImpPivotTable > XclImpPivotTableRef;
@@ -422,6 +433,9 @@ public:
void ReadSxvi( XclImpStream& rStrm );
/** Reads an SXEX record containing additional settings for a pivot table. */
void ReadSxex( XclImpStream& rStrm );
+ /** Reads an SXVIEWEX9 record that specifies the pivot tables
+ * autoformat. */
+ void ReadSxViewEx9( XclImpStream& rStrm );
// ------------------------------------------------------------------------
@@ -430,6 +444,8 @@ public:
/** Inserts all pivot tables into the Calc document. */
void ConvertPivotTables();
+ void MaybeRefreshPivotTables();
+
private:
typedef ::std::vector< XclImpPivotCacheRef > XclImpPivotCacheVec;
typedef ::std::vector< XclImpPivotTableRef > XclImpPivotTableVec;
diff --git a/sc/source/filter/inc/xlpivot.hxx b/sc/source/filter/inc/xlpivot.hxx
index 9604c7b1d17d..3ea464e7b919 100644
--- a/sc/source/filter/inc/xlpivot.hxx
+++ b/sc/source/filter/inc/xlpivot.hxx
@@ -41,6 +41,9 @@
#include <tools/datetime.hxx>
#include "ftools.hxx"
#include "xladdress.hxx"
+#include "dpobject.hxx"
+
+#include <memory>
class XclImpStream;
class XclExpStream;
@@ -73,6 +76,10 @@ const sal_uInt16 EXC_PT_MAXDATACOUNT = 256;
// pivot table items
const sal_uInt16 EXC_PT_MAXITEMCOUNT = 32500;
+const sal_uInt16 EXC_PT_AUTOFMT_HEADER = 0x810;
+const sal_uInt16 EXC_PT_AUTOFMT_ZERO = 0;
+const sal_uInt32 EXC_PT_AUTOFMT_FLAGS = 0x20;
+
/** Data type of a pivot cache item. */
enum XclPCItemType
{
@@ -396,6 +403,9 @@ const double EXC_SXDBEX_CREATION_DATE = 51901.029652778;
const sal_uInt16 EXC_ID_SXFDBTYPE = 0x01BB;
const sal_uInt16 EXC_SXFDBTYPE_DEFAULT = 0x0000;
+// (0x0810) SXVIEWEX9 ---------------------------------------------------------
+const sal_uInt16 EXC_ID_SXVIEWEX9 = 0x0810;
+
// ============================================================================
// Pivot cache
// ============================================================================
@@ -663,6 +673,8 @@ struct XclPTFieldExtInfo
sal_uInt32 mnFlags; /// Several flags and number of items for AutoShow.
sal_uInt16 mnSortField; /// Index to data field sorting bases on.
sal_uInt16 mnShowField; /// Index to data field AutoShow bases on.
+ sal_uInt16 mnNumFmt;
+ ::std::auto_ptr<rtl::OUString> mpFieldTotalName;
explicit XclPTFieldExtInfo();
@@ -786,5 +798,23 @@ XclExpStream& operator<<( XclExpStream& rStrm, const XclPTExtInfo& rInfo );
// ============================================================================
+// Pivot table autoformat settings ==============================================
+
+/** Pivot table autoformat settings (SXVIEWEX9 record). */
+struct XclPTViewEx9Info
+{
+ sal_uInt32 mbReport; /// 2 for report* fmts ?
+ sal_uInt8 mnAutoFormat; /// AutoFormat ID
+ sal_uInt8 mnGridLayout; /// 0 == gridlayout, 0x10 == modern
+ String maGrandTotalName;
+
+ explicit XclPTViewEx9Info();
+ void Init( const ScDPObject& rDPObj );
+};
+
+XclImpStream& operator>>( XclImpStream& rStrm, XclPTViewEx9Info& rInfo );
+XclExpStream& operator<<( XclExpStream& rStrm, const XclPTViewEx9Info& rInfo );
+
+// ============================================================================
#endif
diff --git a/sc/source/filter/inc/xlstring.hxx b/sc/source/filter/inc/xlstring.hxx
index 0970fafd1ed6..32ee23f83d85 100644
--- a/sc/source/filter/inc/xlstring.hxx
+++ b/sc/source/filter/inc/xlstring.hxx
@@ -43,6 +43,7 @@ const XclStrFlags EXC_STR_FORCEUNICODE = 0x0001; /// Always use UCS-2 cha
const XclStrFlags EXC_STR_8BITLENGTH = 0x0002; /// 8-bit string length field (default: 16-bit).
const XclStrFlags EXC_STR_SMARTFLAGS = 0x0004; /// Omit flags on empty string (default: read/write always). BIFF8 only.
const XclStrFlags EXC_STR_SEPARATEFORMATS = 0x0008; /// Import: Keep old formats when reading unformatted string (default: clear formats); Export: Write unformatted string.
+const XclStrFlags EXC_STR_NOHEADER = 0x0010; /// Export: Don't write the length and flag fields.
// ----------------------------------------------------------------------------
diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx
index 32cf92e08d1a..97926ee7113f 100644
--- a/sc/source/filter/xml/XMLExportDataPilot.cxx
+++ b/sc/source/filter/xml/XMLExportDataPilot.cxx
@@ -68,6 +68,7 @@
using namespace com::sun::star;
using namespace xmloff::token;
+using ::rtl::OUString;
ScXMLExportDataPilot::ScXMLExportDataPilot(ScXMLExport& rTempExport)
: rExport(rTempExport),
@@ -448,7 +449,14 @@ void ScXMLExportDataPilot::WriteLayoutInfo(ScDPSaveDimension* pDim)
void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
{
+ using sheet::GeneralFunction;
+
sal_Int32 nSubTotalCount = pDim->GetSubTotalsCount();
+ const OUString* pLayoutName = NULL;
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ // Export display names only for 1.2 extended or later.
+ pLayoutName = pDim->GetSubtotalName();
+
if (nSubTotalCount > 0)
{
SvXMLElementExport aElemSTs(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTALS, sal_True, sal_True);
@@ -456,8 +464,11 @@ void ScXMLExportDataPilot::WriteSubTotals(ScDPSaveDimension* pDim)
for (sal_Int32 nSubTotal = 0; nSubTotal < nSubTotalCount; nSubTotal++)
{
rtl::OUString sFunction;
- ScXMLConverter::GetStringFromFunction( sFunction, (sheet::GeneralFunction)pDim->GetSubTotalFunc(nSubTotal) );
+ GeneralFunction nFunc = static_cast<GeneralFunction>(pDim->GetSubTotalFunc(nSubTotal));
+ ScXMLConverter::GetStringFromFunction( sFunction, nFunc);
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FUNCTION, sFunction);
+ if (pLayoutName && nFunc == sheet::GeneralFunction_AUTO)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
SvXMLElementExport aElemST(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_SUBTOTAL, sal_True, sal_True);
}
}
@@ -473,6 +484,15 @@ void ScXMLExportDataPilot::WriteMembers(ScDPSaveDimension* pDim)
for (ScDPSaveDimension::MemberList::const_iterator i=rMembers.begin(); i != rMembers.end() ; i++)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_NAME, rtl::OUString((*i)->GetName()));
+
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ // Export display names only for ODF 1.2 extended or later.
+ const OUString* pLayoutName = (*i)->GetLayoutName();
+ if (pLayoutName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
+ }
+
rtl::OUStringBuffer sBuffer;
SvXMLUnitConverter::convertBool(sBuffer, (*i)->GetIsVisible());
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, sBuffer.makeStringAndClear());
@@ -670,6 +690,14 @@ void ScXMLExportDataPilot::WriteGroupDimElements(ScDPSaveDimension* pDim, const
void ScXMLExportDataPilot::WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData)
{
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, rtl::OUString(pDim->GetName()));
+ if (rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ // Export display names only for ODF 1.2 extended or later.
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pLayoutName);
+ }
+
if (pDim->IsDataLayout())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TRUE);
rtl::OUString sValueStr;
@@ -707,6 +735,16 @@ void ScXMLExportDataPilot::WriteDimensions(ScDPSaveData* pDPSave)
}
}
+void ScXMLExportDataPilot::WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const OUString* pGrandTotal)
+{
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, bVisible ? XML_TRUE : XML_FALSE);
+ rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORIENTATION, eOrient);
+ if (pGrandTotal)
+ rExport.AddAttribute(XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, *pGrandTotal);
+
+ SvXMLElementExport aElemGrandTotal(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, sal_True, sal_True);
+}
+
void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreadsheetDocument>& /* xSpreadDoc */)
{
pDoc = rExport.GetDocument();
@@ -775,6 +813,24 @@ void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreads
if (!pDPSave->GetDrillDown())
rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_DRILL_DOWN_ON_DOUBLE_CLICK, XML_FALSE);
SvXMLElementExport aElemDP(rExport, XML_NAMESPACE_TABLE, XML_DATA_PILOT_TABLE, sal_True, sal_True);
+
+ // grand total elements.
+
+ const OUString* pGrandTotalName = pDPSave->GetGrandTotalName();
+ if (pGrandTotalName && rExport.getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST)
+ {
+ // Use the new data-pilot-grand-total element.
+ if (bRowGrand && bColumnGrand)
+ {
+ WriteGrandTotal(XML_BOTH, true, pGrandTotalName);
+ }
+ else
+ {
+ WriteGrandTotal(XML_ROW, bRowGrand, pGrandTotalName);
+ WriteGrandTotal(XML_COLUMN, bColumnGrand, pGrandTotalName);
+ }
+ }
+
rExport.CheckAttrList();
if ((*pDPs)[i]->IsSheetData())
{
diff --git a/sc/source/filter/xml/XMLExportDataPilot.hxx b/sc/source/filter/xml/XMLExportDataPilot.hxx
index fb78a59d616b..8bf884ab2fd6 100644
--- a/sc/source/filter/xml/XMLExportDataPilot.hxx
+++ b/sc/source/filter/xml/XMLExportDataPilot.hxx
@@ -34,6 +34,7 @@
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <rtl/ustring.hxx>
#include "global.hxx"
+#include "xmloff/xmltoken.hxx"
class ScXMLExport;
class ScDocument;
@@ -69,6 +70,8 @@ class ScXMLExportDataPilot
void WriteDimension(ScDPSaveDimension* pDim, const ScDPDimensionSaveData* pDimData);
void WriteDimensions(ScDPSaveData* pDPSave);
+ void WriteGrandTotal(::xmloff::token::XMLTokenEnum eOrient, bool bVisible, const ::rtl::OUString* pGrandTotal);
+
public:
ScXMLExportDataPilot(ScXMLExport& rExport);
~ScXMLExportDataPilot();
diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx
index 428e369a94dc..08e8633978b1 100644
--- a/sc/source/filter/xml/xmldpimp.cxx
+++ b/sc/source/filter/xml/xmldpimp.cxx
@@ -48,6 +48,7 @@
#include "dpgroup.hxx"
#include "dpdimsave.hxx"
#include "rangeutl.hxx"
+#include "dpoutputgeometry.hxx"
#include <xmloff/xmltkmap.hxx>
#include <xmloff/nmspmap.hxx>
@@ -65,6 +66,8 @@
using namespace com::sun::star;
using namespace xmloff::token;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::xml::sax::XAttributeList;
using ::rtl::OUString;
//------------------------------------------------------------------
@@ -113,6 +116,9 @@ void ScXMLDataPilotTablesContext::EndElement()
{
}
+ScXMLDataPilotTableContext::GrandTotalItem::GrandTotalItem() :
+ mbVisible(true) {}
+
ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
@@ -126,6 +132,10 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
sDataPilotTableName(),
sApplicationData(),
sGrandTotal(GetXMLToken(XML_BOTH)),
+ mnRowFieldCount(0),
+ mnColFieldCount(0),
+ mnPageFieldCount(0),
+ mnDataFieldCount(0),
bIsNative(sal_True),
bIgnoreEmptyRows(sal_False),
bIdentifyCategories(sal_False),
@@ -159,6 +169,26 @@ ScXMLDataPilotTableContext::ScXMLDataPilotTableContext( ScXMLImport& rImport,
case XML_TOK_DATA_PILOT_TABLE_ATTR_GRAND_TOTAL :
{
sGrandTotal = sValue;
+ if (IsXMLToken(sValue, XML_BOTH))
+ {
+ maRowGrandTotal.mbVisible = true;
+ maColGrandTotal.mbVisible = true;
+ }
+ else if (IsXMLToken(sValue, XML_ROW))
+ {
+ maRowGrandTotal.mbVisible = true;
+ maColGrandTotal.mbVisible = false;
+ }
+ else if (IsXMLToken(sValue, XML_COLUMN))
+ {
+ maRowGrandTotal.mbVisible = false;
+ maColGrandTotal.mbVisible = true;
+ }
+ else
+ {
+ maRowGrandTotal.mbVisible = false;
+ maColGrandTotal.mbVisible = false;
+ }
}
break;
case XML_TOK_DATA_PILOT_TABLE_ATTR_IGNORE_EMPTY_ROWS :
@@ -238,6 +268,11 @@ SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( USHORT nPref
nSourceType = SERVICE;
}
break;
+ case XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL:
+ {
+ pContext = new ScXMLDataPilotGrandTotalContext(GetScImport(), nPrefix, rLName, xAttrList, this);
+ }
+ break;
case XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE :
{
pContext = new ScXMLSourceCellRangeContext(GetScImport(), nPrefix, rLName, xAttrList, this);
@@ -257,6 +292,12 @@ SvXMLImportContext *ScXMLDataPilotTableContext::CreateChildContext( USHORT nPref
void ScXMLDataPilotTableContext::SetButtons()
{
+ ScDPOutputGeometry aGeometry(aTargetRangeAddress, bShowFilter, ScDPOutputGeometry::ODF);
+ aGeometry.setColumnFieldCount(mnColFieldCount);
+ aGeometry.setRowFieldCount(mnRowFieldCount);
+ aGeometry.setPageFieldCount(mnPageFieldCount);
+ aGeometry.setDataFieldCount(mnDataFieldCount);
+
OUString sAddress;
sal_Int32 nOffset = 0;
while( nOffset >= 0 )
@@ -268,8 +309,21 @@ void ScXMLDataPilotTableContext::SetButtons()
sal_Int32 nAddrOffset(0);
if (pDoc && ScRangeStringConverter::GetAddressFromString( aScAddress, sAddress, pDoc, ::formula::FormulaGrammar::CONV_OOO, nAddrOffset ))
{
- ScMergeFlagAttr aAttr( SC_MF_BUTTON );
- pDoc->ApplyAttr( aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), aAttr );
+ ScDPOutputGeometry::FieldType eType = aGeometry.getFieldButtonType(aScAddress);
+
+ sal_Int16 nMFlag = SC_MF_BUTTON;
+ if (eType == ScDPOutputGeometry::Column || eType == ScDPOutputGeometry::Row)
+ nMFlag |= SC_MF_BUTTON_POPUP;
+
+ // Use the cell's string value to see if this field contains a
+ // hidden member. Isn't there a better way? GetString() is
+ // quite expensive...
+ String aCellStr;
+ pDoc->GetString(aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), aCellStr);
+ if (maHiddenMemberFields.count(aCellStr))
+ nMFlag |= SC_MF_HIDDEN_MEMBER;
+
+ pDoc->ApplyFlagsTab(aScAddress.Col(), aScAddress.Row(), aScAddress.Col(), aScAddress.Row(), aScAddress.Tab(), nMFlag);
}
}
}
@@ -278,7 +332,7 @@ void ScXMLDataPilotTableContext::SetButtons()
pDPObject->RefreshAfterLoad();
}
-void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim)
+void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember)
{
if (pDPSave)
{
@@ -288,6 +342,38 @@ void ScXMLDataPilotTableContext::AddDimension(ScDPSaveDimension* pDim)
pDPSave->GetExistingDimensionByName(pDim->GetName()) )
pDim->SetDupFlag( TRUE );
+ if (!pDim->IsDataLayout())
+ {
+ switch (pDim->GetOrientation())
+ {
+ case sheet::DataPilotFieldOrientation_ROW:
+ ++mnRowFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ ++mnColFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_PAGE:
+ ++mnPageFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_DATA:
+ ++mnDataFieldCount;
+ break;
+ case sheet::DataPilotFieldOrientation_HIDDEN:
+ default:
+ ;
+ }
+
+ if (bHasHiddenMember)
+ {
+ // the layout name takes priority over the original name,
+ // since this data is used against cell values.
+ const OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ maHiddenMemberFields.insert(*pLayoutName);
+ else
+ maHiddenMemberFields.insert(pDim->GetName());
+ }
+ }
pDPSave->AddDimension(pDim);
}
}
@@ -362,26 +448,15 @@ void ScXMLDataPilotTableContext::EndElement()
}
break;
}
- if (IsXMLToken(sGrandTotal, XML_BOTH))
- {
- pDPSave->SetRowGrand(sal_True);
- pDPSave->SetColumnGrand(sal_True);
- }
- else if (IsXMLToken(sGrandTotal, XML_ROW))
- {
- pDPSave->SetRowGrand(sal_True);
- pDPSave->SetColumnGrand(sal_False);
- }
- else if (IsXMLToken(sGrandTotal, XML_COLUMN))
- {
- pDPSave->SetRowGrand(sal_False);
- pDPSave->SetColumnGrand(sal_True);
- }
- else
- {
- pDPSave->SetRowGrand(sal_False);
- pDPSave->SetColumnGrand(sal_False);
- }
+
+ pDPSave->SetRowGrand(maRowGrandTotal.mbVisible);
+ pDPSave->SetColumnGrand(maColGrandTotal.mbVisible);
+ if (maRowGrandTotal.maDisplayName.getLength())
+ // TODO: Right now, we only support one grand total name for both
+ // column and row totals. Take the value from the row total for
+ // now.
+ pDPSave->SetGrandTotalName(maRowGrandTotal.maDisplayName);
+
pDPSave->SetIgnoreEmptyRows(bIgnoreEmptyRows);
pDPSave->SetRepeatIfEmpty(bIdentifyCategories);
pDPSave->SetFilterButton(bShowFilter);
@@ -393,12 +468,36 @@ void ScXMLDataPilotTableContext::EndElement()
{
ScDPCollection* pDPCollection = pDoc->GetDPCollection();
pDPObject->SetAlive(sal_True);
- pDPCollection->Insert(pDPObject);
+ pDPCollection->InsertNewTable(pDPObject);
}
SetButtons();
}
}
+void ScXMLDataPilotTableContext::SetGrandTotal(
+ XMLTokenEnum eOrientation, bool bVisible, const OUString& rDisplayName)
+{
+ switch (eOrientation)
+ {
+ case XML_BOTH:
+ maRowGrandTotal.mbVisible = bVisible;
+ maRowGrandTotal.maDisplayName = rDisplayName;
+ maColGrandTotal.mbVisible = bVisible;
+ maColGrandTotal.maDisplayName = rDisplayName;
+ break;
+ case XML_ROW:
+ maRowGrandTotal.mbVisible = bVisible;
+ maRowGrandTotal.maDisplayName = rDisplayName;
+ break;
+ case XML_COLUMN:
+ maColGrandTotal.mbVisible = bVisible;
+ maColGrandTotal.maDisplayName = rDisplayName;
+ break;
+ default:
+ ;
+ }
+}
+
ScXMLDPSourceSQLContext::ScXMLDPSourceSQLContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
@@ -643,6 +742,81 @@ void ScXMLSourceServiceContext::EndElement()
{
}
+ScXMLImport& ScXMLDataPilotGrandTotalContext::GetScImport()
+{
+ return static_cast<ScXMLImport&>(GetImport());
+}
+
+ScXMLDataPilotGrandTotalContext::ScXMLDataPilotGrandTotalContext(
+ ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName, const Reference<XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTableContext ) :
+ SvXMLImportContext( rImport, nPrefix, rLName ),
+ mpTableContext(pTableContext),
+ meOrientation(NONE),
+ mbVisible(false)
+{
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotGrandTotalAttrTokenMap();
+ for (sal_Int16 i = 0; i < nAttrCount; ++i)
+ {
+ const OUString& rAttrName = xAttrList->getNameByIndex(i);
+ const OUString& rAttrValue = xAttrList->getValueByIndex(i);
+
+ OUString aLocalName;
+ USHORT nLocalPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(rAttrName, &aLocalName);
+ switch (rAttrTokenMap.Get(nLocalPrefix, aLocalName))
+ {
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY:
+ mbVisible = IsXMLToken(rAttrValue, XML_TRUE);
+ break;
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION:
+ if (IsXMLToken(rAttrValue, XML_BOTH))
+ meOrientation = BOTH;
+ else if (IsXMLToken(rAttrValue, XML_ROW))
+ meOrientation = ROW;
+ else if (IsXMLToken(rAttrValue, XML_COLUMN))
+ meOrientation = COLUMN;
+ break;
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT:
+ maDisplayName = rAttrValue;
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+ScXMLDataPilotGrandTotalContext::~ScXMLDataPilotGrandTotalContext()
+{
+}
+
+SvXMLImportContext* ScXMLDataPilotGrandTotalContext::CreateChildContext(
+ USHORT /*nPrefix*/, const ::rtl::OUString& /*rLocalName*/, const Reference<XAttributeList>& /*xAttrList*/ )
+{
+ return NULL;
+}
+
+void ScXMLDataPilotGrandTotalContext::EndElement()
+{
+ XMLTokenEnum eOrient = XML_NONE;
+ switch (meOrientation)
+ {
+ case BOTH:
+ eOrient = XML_BOTH;
+ break;
+ case ROW:
+ eOrient = XML_ROW;
+ break;
+ case COLUMN:
+ eOrient = XML_COLUMN;
+ break;
+ default:
+ ;
+ }
+ mpTableContext->SetGrandTotal(eOrient, mbVisible, maDisplayName);
+}
+
ScXMLSourceCellRangeContext::ScXMLSourceCellRangeContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
@@ -723,10 +897,12 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
bIsGroupField(sal_False),
bDateValue(sal_False),
bAutoStart(sal_False),
- bAutoEnd(sal_False)
+ bAutoEnd(sal_False),
+ mbHasHiddenMember(false)
{
sal_Bool bHasName(sal_False);
sal_Bool bDataLayout(sal_False);
+ OUString aDisplayName;
sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetDataPilotFieldAttrTokenMap();
for( sal_Int16 i=0; i < nAttrCount; ++i )
@@ -745,6 +921,12 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
bHasName = sal_True;
}
break;
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT:
+ {
+ aDisplayName = sValue;
+ }
+ break;
case XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD :
{
bDataLayout = IsXMLToken(sValue, XML_TRUE);
@@ -774,7 +956,11 @@ ScXMLDataPilotFieldContext::ScXMLDataPilotFieldContext( ScXMLImport& rImport,
}
}
if (bHasName)
+ {
pDim = new ScDPSaveDimension(String(sName), bDataLayout);
+ if (aDisplayName.getLength())
+ pDim->SetLayoutName(aDisplayName);
+ }
}
ScXMLDataPilotFieldContext::~ScXMLDataPilotFieldContext()
@@ -808,6 +994,22 @@ SvXMLImportContext *ScXMLDataPilotFieldContext::CreateChildContext( USHORT nPref
return pContext;
}
+void ScXMLDataPilotFieldContext::AddMember(ScDPSaveMember* pMember)
+{
+ if (pDim)
+ pDim->AddMember(pMember);
+
+ if (!pMember->GetIsVisible())
+ // This member is hidden.
+ mbHasHiddenMember = true;
+}
+
+void ScXMLDataPilotFieldContext::SetSubTotalName(const OUString& rName)
+{
+ if (pDim)
+ pDim->SetSubtotalName(rName);
+}
+
void ScXMLDataPilotFieldContext::AddGroup(const ::std::vector<rtl::OUString>& rMembers, const rtl::OUString& rName)
{
ScXMLDataPilotGroup aGroup;
@@ -828,7 +1030,7 @@ void ScXMLDataPilotFieldContext::EndElement()
String sPage(sSelectedPage);
pDim->SetCurrentPage(&sPage);
}
- pDataPilotTable->AddDimension(pDim);
+ pDataPilotTable->AddDimension(pDim, mbHasHiddenMember);
if (bIsGroupField)
{
ScDPNumGroupInfo aInfo;
@@ -1199,6 +1401,8 @@ SvXMLImportContext *ScXMLDataPilotSubTotalsContext::CreateChildContext( USHORT n
void ScXMLDataPilotSubTotalsContext::EndElement()
{
pDataPilotField->SetSubTotals(pFunctions, nFunctionCount);
+ if (maDisplayName.getLength())
+ pDataPilotField->SetSubTotalName(maDisplayName);
}
void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction)
@@ -1221,6 +1425,11 @@ void ScXMLDataPilotSubTotalsContext::AddFunction(sal_Int16 nFunction)
}
}
+void ScXMLDataPilotSubTotalsContext::SetDisplayName(const OUString& rName)
+{
+ maDisplayName = rName;
+}
+
ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImport,
USHORT nPrfx,
const ::rtl::OUString& rLName,
@@ -1247,6 +1456,9 @@ ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImpo
pDataPilotSubTotals->AddFunction( sal::static_int_cast<sal_Int16>(
ScXMLConverter::GetFunctionFromString( sValue ) ) );
}
+ case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT:
+ pDataPilotSubTotals->SetDisplayName(sValue);
break;
}
}
@@ -1344,6 +1556,11 @@ ScXMLDataPilotMemberContext::ScXMLDataPilotMemberContext( ScXMLImport& rImport,
bHasName = sal_True;
}
break;
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME:
+ case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT:
+ {
+ maDisplayName = sValue;
+ }
case XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY :
{
bDisplay = IsXMLToken(sValue, XML_TRUE);
@@ -1380,6 +1597,8 @@ void ScXMLDataPilotMemberContext::EndElement()
if (bHasName) // #i53407# don't check sName, empty name is allowed
{
ScDPSaveMember* pMember = new ScDPSaveMember(String(sName));
+ if (maDisplayName.getLength())
+ pMember->SetLayoutName(maDisplayName);
pMember->SetIsVisible(bDisplay);
pMember->SetShowDetails(bDisplayDetails);
pDataPilotField->AddMember(pMember);
diff --git a/sc/source/filter/xml/xmldpimp.hxx b/sc/source/filter/xml/xmldpimp.hxx
index 874fe27654ba..50dc7e6d9c0d 100644
--- a/sc/source/filter/xml/xmldpimp.hxx
+++ b/sc/source/filter/xml/xmldpimp.hxx
@@ -41,6 +41,8 @@
#include "dpobject.hxx"
#include "dpsave.hxx"
+#include <hash_set>
+
class ScXMLImport;
class ScDPSaveNumGroupDimension;
class ScDPSaveGroupDimension;
@@ -79,10 +81,21 @@ public:
class ScXMLDataPilotTableContext : public SvXMLImportContext
{
+ typedef ::std::hash_set< ::rtl::OUString, ::rtl::OUStringHash > StringSet;
+ StringSet maHiddenMemberFields;
+
+ struct GrandTotalItem
+ {
+ ::rtl::OUString maDisplayName;
+ bool mbVisible;
+ GrandTotalItem();
+ };
ScDocument* pDoc;
ScDPObject* pDPObject;
ScDPSaveData* pDPSave;
ScDPDimensionSaveData* pDPDimSaveData;
+ GrandTotalItem maRowGrandTotal;
+ GrandTotalItem maColGrandTotal;
rtl::OUString sDataPilotTableName;
rtl::OUString sApplicationData;
rtl::OUString sGrandTotal;
@@ -100,6 +113,10 @@ class ScXMLDataPilotTableContext : public SvXMLImportContext
ScAddress aFilterOutputPosition;
ScQueryParam aSourceQueryParam;
ScMySourceType nSourceType;
+ sal_uInt32 mnRowFieldCount;
+ sal_uInt32 mnColFieldCount;
+ sal_uInt32 mnPageFieldCount;
+ sal_uInt32 mnDataFieldCount;
sal_Bool bIsNative;
sal_Bool bIgnoreEmptyRows;
sal_Bool bIdentifyCategories;
@@ -131,6 +148,7 @@ public:
virtual void EndElement();
+ void SetGrandTotal(::xmloff::token::XMLTokenEnum eOrientation, bool bVisible, const ::rtl::OUString& rDisplayName);
void SetDatabaseName(const rtl::OUString& sValue) { sDatabaseName = sValue; }
void SetSourceObject(const rtl::OUString& sValue) { sSourceObject = sValue; }
void SetNative(const sal_Bool bValue) { bIsNative = bValue; }
@@ -147,7 +165,7 @@ public:
void SetFilterSourceRange(const ScRange& aValue) { aFilterSourceRange = aValue; }
// void SetFilterIsCaseSensitive(const sal_Bool bValue) { aSourceQueryParam.bCaseSens = bValue; }
// void SetFilterSkipDuplicates(const sal_Bool bValue) { aSourceQueryParam.bDuplicate = !bValue; }
- void AddDimension(ScDPSaveDimension* pDim);
+ void AddDimension(ScDPSaveDimension* pDim, bool bHasHiddenMember);
void AddGroupDim(const ScDPSaveNumGroupDimension& aNumGroupDim);
void AddGroupDim(const ScDPSaveGroupDimension& aGroupDim);
void SetButtons();
@@ -253,6 +271,34 @@ public:
virtual void EndElement();
};
+class ScXMLDataPilotGrandTotalContext : public SvXMLImportContext
+{
+ enum Orientation { COLUMN, ROW, BOTH, NONE };
+
+ ScXMLImport& GetScImport();
+
+ ScXMLDataPilotTableContext* mpTableContext;
+ ::rtl::OUString maDisplayName;
+ Orientation meOrientation;
+ bool mbVisible;
+
+public:
+ ScXMLDataPilotGrandTotalContext(
+ ScXMLImport& rImport, USHORT nPrefix, const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+ ScXMLDataPilotTableContext* pTableContext );
+
+ virtual ~ScXMLDataPilotGrandTotalContext();
+
+ virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+ const ::rtl::OUString& rLocalName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+ virtual void EndElement();
+};
+
class ScXMLSourceCellRangeContext : public SvXMLImportContext
{
ScXMLDataPilotTableContext* pDataPilotTable;
@@ -300,12 +346,13 @@ class ScXMLDataPilotFieldContext : public SvXMLImportContext
sal_Int32 nGroupPart;
sal_Int16 nFunction;
sal_Int16 nOrientation;
- sal_Bool bShowEmpty;
- sal_Bool bSelectedPage;
- sal_Bool bIsGroupField;
- sal_Bool bDateValue;
- sal_Bool bAutoStart;
- sal_Bool bAutoEnd;
+ sal_Bool bShowEmpty:1;
+ sal_Bool bSelectedPage:1;
+ sal_Bool bIsGroupField:1;
+ sal_Bool bDateValue:1;
+ sal_Bool bAutoStart:1;
+ sal_Bool bAutoEnd:1;
+ bool mbHasHiddenMember:1;
const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
@@ -329,7 +376,8 @@ public:
void SetShowEmpty(const sal_Bool bValue) { if (pDim) pDim->SetShowEmpty(bValue); }
void SetSubTotals(const sal_uInt16* pFunctions, const sal_Int16 nCount) { if(pDim) pDim->SetSubTotals(nCount, pFunctions); }
- void AddMember(ScDPSaveMember* pMember) { if (pDim) pDim->AddMember(pMember); }
+ void AddMember(ScDPSaveMember* pMember);
+ void SetSubTotalName(const ::rtl::OUString& rName);
void SetFieldReference(const com::sun::star::sheet::DataPilotFieldReference& aRef) { if (pDim) pDim->SetReferenceValue(&aRef); }
void SetAutoShowInfo(const com::sun::star::sheet::DataPilotFieldAutoShowInfo& aInfo) { if (pDim) pDim->SetAutoShowInfo(&aInfo); }
void SetSortInfo(const com::sun::star::sheet::DataPilotFieldSortInfo& aInfo) { if (pDim) pDim->SetSortInfo(&aInfo); }
@@ -453,6 +501,7 @@ class ScXMLDataPilotSubTotalsContext : public SvXMLImportContext
sal_Int16 nFunctionCount;
sal_uInt16* pFunctions;
+ ::rtl::OUString maDisplayName;
const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
@@ -476,6 +525,7 @@ public:
virtual void EndElement();
void AddFunction(sal_Int16 nFunction);
+ void SetDisplayName(const ::rtl::OUString& rName);
};
class ScXMLDataPilotSubTotalContext : public SvXMLImportContext
@@ -533,6 +583,7 @@ class ScXMLDataPilotMemberContext : public SvXMLImportContext
ScXMLDataPilotFieldContext* pDataPilotField;
rtl::OUString sName;
+ rtl::OUString maDisplayName;
sal_Bool bDisplay;
sal_Bool bDisplayDetails;
sal_Bool bHasName;
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 94613379a32d..c2fd53acb736 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -1575,6 +1575,26 @@ static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xIn
return true; // successful
}
+static void lcl_SkipBytesInBlocks( const uno::Reference< io::XInputStream >& xInput, sal_Int32 nBytesToSkip )
+{
+ // skipBytes in zip stream is implemented as reading.
+ // For now, split into several calls to avoid allocating a large buffer.
+ // Later, skipBytes should be changed.
+
+ const sal_Int32 nMaxSize = 32*1024;
+
+ if ( nBytesToSkip > 0 )
+ {
+ sal_Int32 nRemaining = nBytesToSkip;
+ while ( nRemaining > 0 )
+ {
+ sal_Int32 nSkip = std::min( nRemaining, nMaxSize );
+ xInput->skipBytes( nSkip );
+ nRemaining -= nSkip;
+ }
+ }
+}
+
void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd )
{
uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler();
@@ -1598,7 +1618,7 @@ void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset
rNewStart = (sal_Int32)xDestSeek->getPosition();
if ( nStartOffset > nSourceStreamPos )
- xSourceStream->skipBytes( nStartOffset - nSourceStreamPos );
+ lcl_SkipBytesInBlocks( xSourceStream, nStartOffset - nSourceStreamPos );
if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) )
{
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 5d07670f53a2..f2fe367a2c64 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -1347,6 +1347,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableElemTokenMap()
{
{ XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_SQL, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL },
{ XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_TABLE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE },
+ { XML_NAMESPACE_TABLE, XML_DATA_PILOT_GRAND_TOTAL, XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL },
{ XML_NAMESPACE_TABLE, XML_DATABASE_SOURCE_QUERY, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY },
{ XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE },
{ XML_NAMESPACE_TABLE, XML_SOURCE_CELL_RANGE, XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE },
@@ -1380,6 +1381,25 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceServiceAttrTokenMap()
return *pDataPilotTableSourceServiceAttrTokenMap;
}
+const SvXMLTokenMap& ScXMLImport::GetDataPilotGrandTotalAttrTokenMap()
+{
+ if (!pDataPilotGrandTotalAttrTokenMap)
+ {
+ static __FAR_DATA SvXMLTokenMapEntry aDataPilotGrandTotalAttrTokenMap[] =
+ {
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT },
+ XML_TOKEN_MAP_END
+ };
+
+ pDataPilotGrandTotalAttrTokenMap = new SvXMLTokenMap( aDataPilotGrandTotalAttrTokenMap );
+ }
+
+ return *pDataPilotGrandTotalAttrTokenMap;
+}
+
const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceCellRangeAttrTokenMap()
{
if( !pDataPilotTableSourceCellRangeAttrTokenMap )
@@ -1418,12 +1438,14 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotFieldAttrTokenMap()
{
static __FAR_DATA SvXMLTokenMapEntry aDataPilotFieldAttrTokenMap[] =
{
- { XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME },
- { XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD },
- { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION },
- { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION },
- { XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE },
- { XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY },
+ { XML_NAMESPACE_TABLE, XML_SOURCE_FIELD_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT },
+ { XML_NAMESPACE_TABLE, XML_IS_DATA_LAYOUT_FIELD, XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD },
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_ORIENTATION, XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION },
+ { XML_NAMESPACE_TABLE, XML_SELECTED_PAGE, XML_TOK_DATA_PILOT_FIELD_ATTR_SELECTED_PAGE },
+ { XML_NAMESPACE_TABLE, XML_USED_HIERARCHY, XML_TOK_DATA_PILOT_FIELD_ATTR_USED_HIERARCHY },
XML_TOKEN_MAP_END
};
@@ -1509,7 +1531,9 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotSubTotalAttrTokenMap()
{
static __FAR_DATA SvXMLTokenMapEntry aDataPilotSubTotalAttrTokenMap[] =
{
- { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_FUNCTION, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT },
XML_TOKEN_MAP_END
};
@@ -1541,9 +1565,11 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotMemberAttrTokenMap()
{
static __FAR_DATA SvXMLTokenMapEntry aDataPilotMemberAttrTokenMap[] =
{
- { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME },
- { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY },
- { XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS },
+ { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME },
+ { XML_NAMESPACE_TABLE_EXT, XML_DISPLAY_NAME, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT },
+ { XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY },
+ { XML_NAMESPACE_TABLE, XML_SHOW_DETAILS, XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS },
XML_TOKEN_MAP_END
};
@@ -1677,6 +1703,7 @@ ScXMLImport::ScXMLImport(
pDataPilotTableAttrTokenMap( 0 ),
pDataPilotTableElemTokenMap( 0 ),
pDataPilotTableSourceServiceAttrTokenMap( 0 ),
+ pDataPilotGrandTotalAttrTokenMap(NULL),
pDataPilotTableSourceCellRangeElemTokenMap( 0 ),
pDataPilotTableSourceCellRangeAttrTokenMap( 0 ),
pDataPilotFieldAttrTokenMap( 0 ),
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index c108642d0b68..c110c70f72e2 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -489,6 +489,7 @@ enum ScXMLDataPilotTableElemTokens
{
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SQL,
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_TABLE,
+ XML_TOK_DATA_PILOT_TABLE_ELEM_GRAND_TOTAL,
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_QUERY,
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_SERVICE,
XML_TOK_DATA_PILOT_TABLE_ELEM_SOURCE_CELL_RANGE,
@@ -504,6 +505,14 @@ enum ScXMLDataPilotTableSourceServiceAttrTokens
XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD
};
+enum ScXMLDataPilotGrandTotalAttrTokens
+{
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_ORIENTATION,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_GRAND_TOTAL_ATTR_DISPLAY_NAME_EXT
+};
+
enum ScXMLDataPilotTableSourceCellRangeElemTokens
{
XML_TOK_SOURCE_CELL_RANGE_ELEM_FILTER
@@ -517,6 +526,8 @@ enum ScXMLDataPilotTableSourceCellRangeAttrTokens
enum ScXMLDataPilotFieldAttrTokens
{
XML_TOK_DATA_PILOT_FIELD_ATTR_SOURCE_FIELD_NAME,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_FIELD_ATTR_DISPLAY_NAME_EXT,
XML_TOK_DATA_PILOT_FIELD_ATTR_IS_DATA_LAYOUT_FIELD,
XML_TOK_DATA_PILOT_FIELD_ATTR_FUNCTION,
XML_TOK_DATA_PILOT_FIELD_ATTR_ORIENTATION,
@@ -552,7 +563,9 @@ enum ScXMLDataPilotSubTotalsElemTokens
enum ScXMLDataPilotSubTotalAttrTokens
{
- XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_FUNCTION,
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT
};
enum ScXMLDataPilotMembersElemTokens
@@ -563,6 +576,8 @@ enum ScXMLDataPilotMembersElemTokens
enum ScXMLDataPilotMemberAttrTokens
{
XML_TOK_DATA_PILOT_MEMBER_ATTR_NAME,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME,
+ XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY_NAME_EXT,
XML_TOK_DATA_PILOT_MEMBER_ATTR_DISPLAY,
XML_TOK_DATA_PILOT_MEMBER_ATTR_SHOW_DETAILS
};
@@ -723,6 +738,7 @@ class ScXMLImport: public SvXMLImport
SvXMLTokenMap *pDataPilotTableAttrTokenMap;
SvXMLTokenMap *pDataPilotTableElemTokenMap;
SvXMLTokenMap *pDataPilotTableSourceServiceAttrTokenMap;
+ SvXMLTokenMap *pDataPilotGrandTotalAttrTokenMap;
SvXMLTokenMap *pDataPilotTableSourceCellRangeElemTokenMap;
SvXMLTokenMap *pDataPilotTableSourceCellRangeAttrTokenMap;
SvXMLTokenMap *pDataPilotFieldAttrTokenMap;
@@ -886,6 +902,7 @@ public:
const SvXMLTokenMap& GetDataPilotTableAttrTokenMap();
const SvXMLTokenMap& GetDataPilotTableElemTokenMap();
const SvXMLTokenMap& GetDataPilotTableSourceServiceAttrTokenMap();
+ const SvXMLTokenMap& GetDataPilotGrandTotalAttrTokenMap();
const SvXMLTokenMap& GetDataPilotTableSourceCellRangeElemTokenMap();
const SvXMLTokenMap& GetDataPilotTableSourceCellRangeAttrTokenMap();
const SvXMLTokenMap& GetDataPilotFieldAttrTokenMap();
diff --git a/sc/source/ui/Accessibility/AccessibleContextBase.cxx b/sc/source/ui/Accessibility/AccessibleContextBase.cxx
index b611198974de..c6c08e8a9c65 100644
--- a/sc/source/ui/Accessibility/AccessibleContextBase.cxx
+++ b/sc/source/ui/Accessibility/AccessibleContextBase.cxx
@@ -628,3 +628,8 @@ void ScAccessibleContextBase::IsObjectValid() const
if (rBHelper.bDisposed || rBHelper.bInDispose)
throw lang::DisposedException();
}
+
+void ScAccessibleContextBase::SetRole(sal_Int16 nRole)
+{
+ maRole = nRole;
+}
diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
new file mode 100644
index 000000000000..0c663af87fd1
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
@@ -0,0 +1,401 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleDataPilotControl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleGlobal.hxx"
+#include "AccessibleFilterMenu.hxx"
+#include "AccessibleFilterMenuItem.hxx"
+#include "unoguard.hxx"
+#include "global.hxx"
+#include "document.hxx"
+#include "docpool.hxx"
+
+#include "tools/gen.hxx"
+#include "svx/unoedsrc.hxx"
+#include "svx/editdata.hxx"
+#include "svx/outliner.hxx"
+#include "vcl/unohelp.hxx"
+#include "dpcontrol.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::accessibility::AccessibleStateType;
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::lang::IllegalArgumentException;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+using ::std::for_each;
+using ::std::vector;
+
+// ============================================================================
+
+namespace {
+
+class AddRemoveEventListener : public ::std::unary_function<void, Reference<XAccessible> >
+{
+public:
+ explicit AddRemoveEventListener(const Reference<XAccessibleEventListener>& rListener, bool bAdd) :
+ mxListener(rListener), mbAdd(bAdd) {}
+
+ void operator() (const Reference<XAccessible>& xAccessible) const
+ {
+ if (!xAccessible.is())
+ return;
+
+ Reference<XAccessibleEventBroadcaster> xBc(xAccessible, UNO_QUERY);
+ if (xBc.is())
+ {
+ if (mbAdd)
+ xBc->addEventListener(mxListener);
+ else
+ xBc->removeEventListener(mxListener);
+ }
+ }
+private:
+ Reference<XAccessibleEventListener> mxListener;
+ bool mbAdd;
+};
+
+}
+
+// ============================================================================
+
+ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos, ScDocument* pDoc) :
+ ScAccessibleContextBase(rxParent, AccessibleRole::MENU),
+ mnMenuPos(nMenuPos),
+ mpWindow(pWin),
+ mpDoc(pDoc),
+ mbEnabled(true)
+{
+ SetName(rName);
+}
+
+ScAccessibleFilterMenu::~ScAccessibleFilterMenu()
+{
+}
+
+// XAccessibleComponent
+
+Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point& /*rPoint*/ )
+ throw (RuntimeException)
+{
+ return this;
+}
+
+sal_Bool ScAccessibleFilterMenu::isVisible() throw (RuntimeException)
+{
+ return mpWindow->IsVisible();
+}
+
+void ScAccessibleFilterMenu::grabFocus()
+ throw (RuntimeException)
+{
+}
+
+sal_Int32 ScAccessibleFilterMenu::getForeground()
+ throw (RuntimeException)
+{
+ return 0;
+}
+
+sal_Int32 ScAccessibleFilterMenu::getBackground()
+ throw (RuntimeException)
+{
+ return 0;
+}
+
+// XAccessibleContext
+
+OUString ScAccessibleFilterMenu::getAccessibleName() throw (RuntimeException)
+{
+ return ScAccessibleContextBase::getAccessibleName();
+}
+
+sal_Int32 ScAccessibleFilterMenu::getAccessibleChildCount()
+ throw (RuntimeException)
+{
+ return getMenuItemCount();
+}
+
+Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex)
+ throw (RuntimeException, IndexOutOfBoundsException)
+{
+ if (maMenuItems.size() <= static_cast<size_t>(nIndex))
+ throw IndexOutOfBoundsException();
+
+ return maMenuItems[nIndex];
+}
+
+Reference<XAccessibleStateSet> ScAccessibleFilterMenu::getAccessibleStateSet()
+ throw (RuntimeException)
+{
+ updateStates();
+ return mxStateSet;
+}
+
+OUString ScAccessibleFilterMenu::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString::createFromAscii("ScAccessibleFilterMenu");
+}
+
+// XAccessibleEventBroadcaster
+
+void ScAccessibleFilterMenu::addEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ ScAccessibleContextBase::addEventListener(xListener);
+ for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, true));
+}
+
+void ScAccessibleFilterMenu::removeEventListener(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessibleEventListener>& xListener)
+ throw (com::sun::star::uno::RuntimeException)
+{
+ ScAccessibleContextBase::removeEventListener(xListener);
+ for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, false));
+}
+
+// XAccessibleSelection
+
+void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ mpWindow->setSelectedMenuItem(nChildIndex, false, true);
+}
+
+sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ return mpWindow->isMenuItemSelected(static_cast<size_t>(nChildIndex));
+}
+
+void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException)
+{
+ mpWindow->clearSelectedMenuItem();
+}
+
+void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeException)
+{
+ // not suported - this is a menu, you can't select all menu items.
+}
+
+sal_Int32 ScAccessibleFilterMenu::getSelectedAccessibleChildCount() throw (RuntimeException)
+{
+ // Since this is a menu, either one menu item is selected, or none at all.
+ return mpWindow->getSelectedMenuItem() == ScMenuFloatingWindow::MENU_NOT_SELECTED ? 0 : 1;
+}
+
+Reference<XAccessible> ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ return maMenuItems[nChildIndex];
+}
+
+void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ if (static_cast<size_t>(nChildIndex) >= maMenuItems.size())
+ throw IndexOutOfBoundsException();
+
+ mpWindow->selectMenuItem(nChildIndex, false, false);
+}
+
+// XInterface
+
+uno::Any SAL_CALL ScAccessibleFilterMenu::queryInterface( uno::Type const & rType )
+ throw (RuntimeException)
+{
+ Any any = ScAccessibleContextBase::queryInterface(rType);
+ if (any.hasValue())
+ return any;
+
+ return ScAccessibleFilterMenu_BASE::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleFilterMenu::acquire() throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleFilterMenu::release() throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+// XTypeProvider
+
+Sequence<sal_Int8> ScAccessibleFilterMenu::getImplementationId()
+ throw (RuntimeException)
+{
+ Sequence<sal_Int8> aId(16);
+ return aId;
+}
+
+Rectangle ScAccessibleFilterMenu::GetBoundingBoxOnScreen() const
+ throw (RuntimeException)
+{
+ if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
+ return Rectangle();
+
+ // Menu object's bounding box is the bounding box of the menu item that
+ // launches the menu, which belongs to the parent window.
+ ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
+ if (!pParentWin)
+ return Rectangle();
+
+ if (!pParentWin->IsVisible())
+ return Rectangle();
+
+ Point aPos = pParentWin->OutputToAbsoluteScreenPixel(Point(0,0));
+ Point aMenuPos;
+ Size aMenuSize;
+ pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aPos + aMenuPos, aMenuSize);
+ return aRect;
+}
+
+Rectangle ScAccessibleFilterMenu::GetBoundingBox() const
+ throw (RuntimeException)
+{
+ if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
+ return Rectangle();
+
+ // Menu object's bounding box is the bounding box of the menu item that
+ // launches the menu, which belongs to the parent window.
+ ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
+ if (!pParentWin)
+ return Rectangle();
+
+ if (!pParentWin->IsVisible())
+ return Rectangle();
+
+ Point aMenuPos;
+ Size aMenuSize;
+ pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aMenuPos, aMenuSize);
+ return aRect;
+}
+
+void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, bool bEnabled, size_t nMenuPos)
+{
+ // Check weather this menu item is a sub menu or a regular menu item.
+ ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos);
+ Reference<XAccessible> xAccessible;
+ if (pSubMenu)
+ {
+ xAccessible = pSubMenu->CreateAccessible();
+ ScAccessibleFilterMenu* p =
+ static_cast<ScAccessibleFilterMenu*>(xAccessible.get());
+ p->setEnabled(bEnabled);
+ p->setMenuPos(nMenuPos);
+ }
+ else
+ {
+ xAccessible.set(new ScAccessibleFilterMenuItem(this, mpWindow, rName, nMenuPos));
+ ScAccessibleFilterMenuItem* p =
+ static_cast<ScAccessibleFilterMenuItem*>(xAccessible.get());
+ p->setEnabled(bEnabled);
+ }
+ maMenuItems.push_back(xAccessible);
+}
+
+void ScAccessibleFilterMenu::setMenuPos(size_t nMenuPos)
+{
+ mnMenuPos = nMenuPos;
+}
+
+void ScAccessibleFilterMenu::setEnabled(bool bEnabled)
+{
+ mbEnabled = bEnabled;
+}
+
+sal_Int32 ScAccessibleFilterMenu::getMenuItemCount() const
+{
+ return maMenuItems.size();
+}
+
+bool ScAccessibleFilterMenu::isSelected() const
+{
+ // Check to see if any of the child menu items is selected.
+ return mpWindow->isMenuItemSelected(mnMenuPos);
+}
+
+bool ScAccessibleFilterMenu::isFocused() const
+{
+ return isSelected();
+}
+
+void ScAccessibleFilterMenu::updateStates()
+{
+ if (!mxStateSet.is())
+ mxStateSet.set(new ScAccessibleStateSet);
+
+ ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
+ mxStateSet.get());
+
+ p->clear();
+
+ p->insert(ENABLED);
+ p->insert(FOCUSABLE);
+ p->insert(SELECTABLE);
+ p->insert(SENSITIVE);
+ p->insert(OPAQUE);
+
+ if (isFocused())
+ p->insert(FOCUSED);
+
+ if (isSelected())
+ p->insert(SELECTED);
+}
diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
new file mode 100644
index 000000000000..9f5524dcb8ce
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
@@ -0,0 +1,208 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleDataPilotControl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleGlobal.hxx"
+#include "AccessibleFilterMenuItem.hxx"
+#include "dpcontrol.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+#include <com/sun/star/accessibility/AccessibleEventId.hpp>
+#include <com/sun/star/accessibility/AccessibleEventObject.hpp>
+#include <com/sun/star/accessibility/AccessibleStateType.hpp>
+#include <com/sun/star/accessibility/TextSegment.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using namespace ::com::sun::star::accessibility::AccessibleStateType;
+
+using ::com::sun::star::uno::Any;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::com::sun::star::uno::UNO_QUERY;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+
+ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem(
+ const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) :
+ ScAccessibleContextBase(rxParent, AccessibleRole::MENU_ITEM),
+ mpWindow(pWin),
+ maName(rName),
+ mnMenuPos(nMenuPos),
+ mbEnabled(true)
+{
+ SetName(rName);
+}
+
+ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem()
+{
+}
+
+sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount()
+ throw (RuntimeException)
+{
+ return 0;
+}
+
+Reference<XAccessible> ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 /*nIndex*/)
+ throw (RuntimeException, IndexOutOfBoundsException)
+{
+ throw IndexOutOfBoundsException();
+}
+
+Reference<XAccessibleStateSet> ScAccessibleFilterMenuItem::getAccessibleStateSet()
+ throw (RuntimeException)
+{
+ updateStateSet();
+ return mxStateSet;
+}
+
+OUString ScAccessibleFilterMenuItem::getImplementationName()
+ throw (RuntimeException)
+{
+ return OUString::createFromAscii("ScAccessibleFilterMenuItem");
+}
+
+// XAccessibleAction
+
+sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount() throw (RuntimeException)
+{
+ return 1;
+}
+
+sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 /*nIndex*/)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ mpWindow->executeMenuItem(mnMenuPos);
+ return true;
+}
+
+OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 /*nIndex*/)
+ throw (IndexOutOfBoundsException, RuntimeException)
+{
+ return OUString::createFromAscii("click");
+}
+
+Reference<XAccessibleKeyBinding> ScAccessibleFilterMenuItem::getAccessibleActionKeyBinding(
+ sal_Int32 /*nIndex*/) throw (IndexOutOfBoundsException, RuntimeException)
+{
+ return Reference<XAccessibleKeyBinding>();
+}
+
+Any SAL_CALL ScAccessibleFilterMenuItem::queryInterface( uno::Type const & rType )
+ throw (RuntimeException)
+{
+ Any any = ScAccessibleContextBase::queryInterface(rType);
+ if (any.hasValue())
+ return any;
+
+ return ScAccessibleFilterMenuItem_BASE::queryInterface(rType);
+}
+
+void SAL_CALL ScAccessibleFilterMenuItem::acquire() throw ()
+{
+ ScAccessibleContextBase::acquire();
+}
+
+void SAL_CALL ScAccessibleFilterMenuItem::release() throw ()
+{
+ ScAccessibleContextBase::release();
+}
+
+bool ScAccessibleFilterMenuItem::isSelected() const
+{
+ return mpWindow->isMenuItemSelected(mnMenuPos);
+}
+
+bool ScAccessibleFilterMenuItem::isFocused() const
+{
+ return isSelected();
+}
+
+void ScAccessibleFilterMenuItem::setEnabled(bool bEnabled)
+{
+ mbEnabled = bEnabled;
+}
+
+Rectangle ScAccessibleFilterMenuItem::GetBoundingBoxOnScreen() const
+ throw (RuntimeException)
+{
+ if (!mpWindow->IsVisible())
+ return Rectangle();
+
+ Point aPos = mpWindow->OutputToAbsoluteScreenPixel(Point(0,0));
+ Point aMenuPos;
+ Size aMenuSize;
+ mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aPos + aMenuPos, aMenuSize);
+ return aRect;
+}
+
+Rectangle ScAccessibleFilterMenuItem::GetBoundingBox() const
+ throw (RuntimeException)
+{
+ if (!mpWindow->IsVisible())
+ return Rectangle();
+
+ Point aMenuPos;
+ Size aMenuSize;
+ mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
+ Rectangle aRect(aMenuPos, aMenuSize);
+ return aRect;
+}
+
+void ScAccessibleFilterMenuItem::updateStateSet()
+{
+ if (!mxStateSet.is())
+ mxStateSet.set(new ScAccessibleStateSet);
+
+ ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
+ mxStateSet.get());
+
+ p->clear();
+
+ p->insert(ENABLED);
+ p->insert(FOCUSABLE);
+ p->insert(SELECTABLE);
+ p->insert(SENSITIVE);
+ p->insert(OPAQUE);
+
+ if (isFocused())
+ p->insert(FOCUSED);
+
+ if (isSelected())
+ p->insert(SELECTED);
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
new file mode 100644
index 000000000000..832cb37dd096
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
@@ -0,0 +1,137 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleDataPilotControl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleFilterTopWindow.hxx"
+#include "AccessibleFilterMenu.hxx"
+#include "dpcontrol.hxx"
+
+#include <com/sun/star/accessibility/AccessibleRole.hpp>
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::accessibility;
+using ::com::sun::star::lang::IndexOutOfBoundsException;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::RuntimeException;
+using ::rtl::OUString;
+
+ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow(
+ const Reference<XAccessible>& rxParent, ScDPFieldPopupWindow* pWin, const OUString& rName, ScDocument* pDoc) :
+ ScAccessibleFilterMenu(rxParent, pWin, rName, ScMenuFloatingWindow::MENU_NOT_SELECTED, pDoc),
+ mpWindow(pWin),
+ mpDoc(pDoc)
+{
+ SetName(rName);
+}
+
+ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow()
+{
+}
+
+// XAccessibleContext
+
+sal_Int32 ScAccessibleFilterTopWindow::getAccessibleChildCount() throw (RuntimeException)
+{
+ sal_Int32 nMenuCount = getMenuItemCount();
+ return nMenuCount + 6;
+}
+
+Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChild(
+ sal_Int32 nIndex) throw (RuntimeException, IndexOutOfBoundsException)
+{
+ if (nIndex >= getAccessibleChildCount())
+ throw IndexOutOfBoundsException();
+
+ sal_Int32 nMenuCount = getMenuItemCount();
+ if (nIndex < nMenuCount)
+ return ScAccessibleFilterMenu::getAccessibleChild(nIndex);
+
+ nIndex -= nMenuCount;
+ switch (nIndex)
+ {
+ case 0:
+ return mxAccListBox;
+ case 1:
+ return mxAccToggleAll;
+ case 2:
+ return mxAccSingleOnBtn;
+ case 3:
+ return mxAccSingleOffBtn;
+ case 4:
+ return mxAccOkBtn;
+ case 5:
+ return mxAccCancelBtn;
+ default:
+ ;
+ }
+
+ return Reference<XAccessible>();
+}
+
+OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeException)
+{
+ return OUString::createFromAscii("ScAccessibleFilterTopWindow");
+}
+
+Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChildMenu()
+{
+ if (!mxAccMenu.is())
+ mxAccMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), ScMenuFloatingWindow::MENU_NOT_SELECTED, mpDoc));
+ return mxAccMenu;
+}
+
+void ScAccessibleFilterTopWindow::setAccessibleChild(
+ const Reference<XAccessible>& rAccessible, ChildControlType eType)
+{
+ switch (eType)
+ {
+ case LISTBOX:
+ mxAccListBox = rAccessible;
+ break;
+ case TOGGLE_ALL:
+ mxAccToggleAll = rAccessible;
+ break;
+ case SINGLE_ON_BTN:
+ mxAccSingleOnBtn = rAccessible;
+ break;
+ case SINGLE_OFF_BTN:
+ mxAccSingleOffBtn = rAccessible;
+ break;
+ case OK_BTN:
+ mxAccOkBtn = rAccessible;
+ break;
+ case CANCEL_BTN:
+ mxAccCancelBtn = rAccessible;
+ break;
+ }
+}
+
diff --git a/sc/source/ui/Accessibility/AccessibleGlobal.cxx b/sc/source/ui/Accessibility/AccessibleGlobal.cxx
new file mode 100644
index 000000000000..6ac7190a132b
--- /dev/null
+++ b/sc/source/ui/Accessibility/AccessibleGlobal.cxx
@@ -0,0 +1,98 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: AccessibleDataPilotControl.hxx,v $
+ * $Revision: 1.6 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+
+#include "precompiled_sc.hxx"
+#include "AccessibleGlobal.hxx"
+
+using ::com::sun::star::uno::RuntimeException;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Sequence;
+using ::std::set;
+
+ScAccessibleStateSet::ScAccessibleStateSet()
+{
+}
+
+ScAccessibleStateSet::~ScAccessibleStateSet()
+{
+}
+
+// XAccessibleStateSet
+
+sal_Bool SAL_CALL ScAccessibleStateSet::isEmpty() throw (RuntimeException)
+{
+ return maStates.empty();
+}
+
+sal_Bool SAL_CALL ScAccessibleStateSet::contains(sal_Int16 nState)
+ throw (RuntimeException)
+{
+ return maStates.count(nState) != 0;
+}
+
+sal_Bool SAL_CALL ScAccessibleStateSet::containsAll(
+ const Sequence<sal_Int16>& aStateSet) throw (RuntimeException)
+{
+ sal_Int32 n = aStateSet.getLength();
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ if (!maStates.count(aStateSet[i]))
+ // This state is not set.
+ return false;
+ }
+ // All specified states are set.
+ return true;
+}
+
+Sequence<sal_Int16> SAL_CALL ScAccessibleStateSet::getStates()
+ throw (RuntimeException)
+{
+ Sequence<sal_Int16> aSeq(0);
+ set<sal_Int16>::const_iterator itr = maStates.begin(), itrEnd = maStates.end();
+ for (size_t i = 0; itr != itrEnd; ++itr, ++i)
+ {
+ aSeq.realloc(i+1);
+ aSeq[i] = *itr;
+ }
+ return aSeq;
+}
+
+void ScAccessibleStateSet::insert(sal_Int16 nState)
+{
+ maStates.insert(nState);
+}
+
+void ScAccessibleStateSet::clear()
+{
+ maStates.clear();
+}
+
diff --git a/sc/source/ui/Accessibility/makefile.mk b/sc/source/ui/Accessibility/makefile.mk
index dfa5ac94b63f..1ef6db37e0c1 100644
--- a/sc/source/ui/Accessibility/makefile.mk
+++ b/sc/source/ui/Accessibility/makefile.mk
@@ -47,12 +47,16 @@ SLOFILES = \
$(SLO)$/AccessibleContextBase.obj \
$(SLO)$/AccessibleTableBase.obj \
$(SLO)$/AccessibleDocument.obj \
+ $(SLO)$/AccessibleGlobal.obj \
$(SLO)$/AccessibleSpreadsheet.obj \
$(SLO)$/AccessibleCell.obj \
$(SLO)$/AccessibilityHints.obj \
$(SLO)$/AccessibleDocumentBase.obj \
$(SLO)$/AccessibleCellBase.obj \
$(SLO)$/AccessibleDocumentPagePreview.obj \
+ $(SLO)$/AccessibleFilterMenu.obj \
+ $(SLO)$/AccessibleFilterMenuItem.obj \
+ $(SLO)$/AccessibleFilterTopWindow.obj \
$(SLO)$/AccessiblePreviewTable.obj \
$(SLO)$/AccessiblePreviewCell.obj \
$(SLO)$/AccessiblePreviewHeaderCell.obj \
@@ -68,11 +72,15 @@ EXCEPTIONSFILES= \
$(SLO)$/AccessibleContextBase.obj \
$(SLO)$/AccessibleTableBase.obj \
$(SLO)$/AccessibleDocument.obj \
+ $(SLO)$/AccessibleGlobal.obj \
$(SLO)$/AccessibleSpreadsheet.obj \
$(SLO)$/AccessibleCell.obj \
$(SLO)$/AccessibleDocumentBase.obj \
$(SLO)$/AccessibleCellBase.obj \
$(SLO)$/AccessibleDocumentPagePreview.obj \
+ $(SLO)$/AccessibleFilterMenu.obj \
+ $(SLO)$/AccessibleFilterMenuItem.obj \
+ $(SLO)$/AccessibleFilterTopWindow.obj \
$(SLO)$/AccessiblePreviewTable.obj \
$(SLO)$/AccessiblePreviewCell.obj \
$(SLO)$/AccessiblePreviewHeaderCell.obj \
diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx
new file mode 100644
index 000000000000..a938948e1b26
--- /dev/null
+++ b/sc/source/ui/cctrl/dpcontrol.cxx
@@ -0,0 +1,1419 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: document.hxx,v $
+ * $Revision: 1.115.36.9 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include "dpcontrol.hxx"
+#include "dpcontrol.hrc"
+
+#include "vcl/outdev.hxx"
+#include "vcl/settings.hxx"
+#include "vcl/wintypes.hxx"
+#include "vcl/decoview.hxx"
+#include "strload.hxx"
+#include "global.hxx"
+
+#include "AccessibleFilterMenu.hxx"
+#include "AccessibleFilterTopWindow.hxx"
+
+#include <com/sun/star/accessibility/XAccessible.hpp>
+#include <com/sun/star/accessibility/XAccessibleContext.hpp>
+
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::accessibility::XAccessible;
+using ::com::sun::star::accessibility::XAccessibleContext;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::std::vector;
+using ::std::hash_map;
+using ::std::auto_ptr;
+
+ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY) :
+ mpOutDev(pOutDev),
+ mpStyle(pStyle),
+ mbBaseButton(true),
+ mbPopupButton(false),
+ mbHasHiddenMember(false),
+ mbPopupPressed(false)
+{
+ if (pZoomX)
+ maZoomX = *pZoomX;
+ else
+ maZoomX = Fraction(1, 1);
+
+ if (pZoomY)
+ maZoomY = *pZoomY;
+ else
+ maZoomY = Fraction(1, 1);
+}
+
+ScDPFieldButton::~ScDPFieldButton()
+{
+}
+
+void ScDPFieldButton::setText(const OUString& rText)
+{
+ maText = rText;
+}
+
+void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize)
+{
+ maPos = rPos;
+ maSize = rSize;
+}
+
+void ScDPFieldButton::setDrawBaseButton(bool b)
+{
+ mbBaseButton = b;
+}
+
+void ScDPFieldButton::setDrawPopupButton(bool b)
+{
+ mbPopupButton = b;
+}
+
+void ScDPFieldButton::setHasHiddenMember(bool b)
+{
+ mbHasHiddenMember = b;
+}
+
+void ScDPFieldButton::setPopupPressed(bool b)
+{
+ mbPopupPressed = b;
+}
+
+void ScDPFieldButton::draw()
+{
+ const long nMargin = 2;
+ bool bOldMapEnablaed = mpOutDev->IsMapModeEnabled();
+ mpOutDev->EnableMapMode(false);
+
+ if (mbBaseButton)
+ {
+ // Background
+ Rectangle aRect(maPos, maSize);
+ mpOutDev->SetLineColor(mpStyle->GetFaceColor());
+ mpOutDev->SetFillColor(mpStyle->GetFaceColor());
+ mpOutDev->DrawRect(aRect);
+
+ // Border lines
+ mpOutDev->SetLineColor(mpStyle->GetLightColor());
+ mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1));
+ mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y()));
+
+ mpOutDev->SetLineColor(mpStyle->GetShadowColor());
+ mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1),
+ Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
+ mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()),
+ Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
+
+ // Field name.
+ Font aTextFont( mpStyle->GetLabelFont() );
+ double fFontHeight = 12.0;
+ fFontHeight *= static_cast<double>(maZoomY.GetNumerator()) / static_cast<double>(maZoomY.GetDenominator());
+ aTextFont.SetHeight(static_cast<long>(fFontHeight));
+ mpOutDev->SetFont(aTextFont);
+
+ Point aTextPos = maPos;
+ long nTHeight = static_cast<long>(fFontHeight);
+ aTextPos.setX(maPos.getX() + nMargin);
+ aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2);
+ mpOutDev->DrawText(aTextPos, maText);
+ }
+
+ if (mbPopupButton)
+ drawPopupButton();
+
+ mpOutDev->EnableMapMode(bOldMapEnablaed);
+}
+
+void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const
+{
+ long nW = maSize.getWidth() / 2;
+ long nH = maSize.getHeight();
+ if (nW > 18)
+ nW = 18;
+ if (nH > 18)
+ nH = 18;
+
+ rPos.setX(maPos.getX() + maSize.getWidth() - nW);
+ rPos.setY(maPos.getY() + maSize.getHeight() - nH);
+ rSize.setWidth(nW);
+ rSize.setHeight(nH);
+}
+
+bool ScDPFieldButton::isPopupButton() const
+{
+ return mbPopupButton;
+}
+
+void ScDPFieldButton::drawPopupButton()
+{
+ Point aPos;
+ Size aSize;
+ getPopupBoundingBox(aPos, aSize);
+
+ // Background & outer black border
+ mpOutDev->SetLineColor(COL_BLACK);
+ mpOutDev->SetFillColor(mpStyle->GetFaceColor());
+ mpOutDev->DrawRect(Rectangle(aPos, aSize));
+
+ if (!mbPopupPressed)
+ {
+ // border lines
+ mpOutDev->SetLineColor(mpStyle->GetLightColor());
+ mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2));
+ mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1));
+
+ mpOutDev->SetLineColor(mpStyle->GetShadowColor());
+ mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2),
+ Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
+ mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1),
+ Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
+ }
+
+ // the arrowhead
+ Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor();
+ mpOutDev->SetLineColor(aArrowColor);
+ mpOutDev->SetFillColor(aArrowColor);
+ Point aCenter(aPos.X() + (aSize.Width() >> 1), aPos.Y() + (aSize.Height() >> 1));
+ Point aPos1, aPos2;
+ aPos1.X() = aCenter.X() - 4;
+ aPos2.X() = aCenter.X() + 4;
+ aPos1.Y() = aCenter.Y() - 3;
+ aPos2.Y() = aCenter.Y() - 3;
+
+ if (mbPopupPressed)
+ {
+ aPos1.X() += 1;
+ aPos2.X() += 1;
+ aPos1.Y() += 1;
+ aPos2.Y() += 1;
+ }
+
+ do
+ {
+ ++aPos1.X();
+ --aPos2.X();
+ ++aPos1.Y();
+ ++aPos2.Y();
+ mpOutDev->DrawLine(aPos1, aPos2);
+ }
+ while (aPos1 != aPos2);
+
+ if (mbHasHiddenMember)
+ {
+ // tiny little box to display in presence of hidden member(s).
+ Point aBoxPos(aPos.X() + aSize.Width() - 5, aPos.Y() + aSize.Height() - 5);
+ if (mbPopupPressed)
+ {
+ aBoxPos.X() += 1;
+ aBoxPos.Y() += 1;
+ }
+ Size aBoxSize(3, 3);
+ mpOutDev->DrawRect(Rectangle(aBoxPos, aBoxSize));
+ }
+}
+
+// ============================================================================
+
+ScMenuFloatingWindow::MenuItemData::MenuItemData() :
+ mbEnabled(true),
+ mpAction(static_cast<ScDPFieldPopupWindow::Action*>(NULL)),
+ mpSubMenuWin(static_cast<ScMenuFloatingWindow*>(NULL))
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScMenuFloatingWindow::SubMenuItemData::SubMenuItemData(ScMenuFloatingWindow* pParent) :
+ mpSubMenu(NULL),
+ mnMenuPos(MENU_NOT_SELECTED),
+ mpParent(pParent)
+{
+ maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl) );
+ maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay());
+}
+
+void ScMenuFloatingWindow::SubMenuItemData::reset()
+{
+ mpSubMenu = NULL;
+ mnMenuPos = MENU_NOT_SELECTED;
+ maTimer.Stop();
+}
+
+IMPL_LINK( ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, void*, EMPTYARG )
+{
+ mpParent->handleMenuTimeout(this);
+ return 0;
+}
+
+// ----------------------------------------------------------------------------
+
+size_t ScMenuFloatingWindow::MENU_NOT_SELECTED = 999;
+
+ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel) :
+ PopupMenuFloatingWindow(pParent),
+ maOpenTimer(this),
+ maCloseTimer(this),
+ maName(OUString::createFromAscii("ScMenuFloatingWindow")),
+ mnSelectedMenu(MENU_NOT_SELECTED),
+ mnClickedMenu(MENU_NOT_SELECTED),
+ mpDoc(pDoc),
+ mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent)),
+ mpActiveSubMenu(NULL)
+{
+ SetMenuStackLevel(nMenuStackLevel);
+
+ // TODO: How do we get the right font to use here ?
+ const sal_uInt16 nPopupFontHeight = 12;
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+ maLabelFont = rStyle.GetLabelFont();
+ maLabelFont.SetHeight(nPopupFontHeight);
+ SetFont(maLabelFont);
+
+ SetText(OUString::createFromAscii("ScMenuFloatingWindow"));
+ SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, PopupEndHdl) );
+}
+
+ScMenuFloatingWindow::~ScMenuFloatingWindow()
+{
+ EndPopupMode();
+}
+
+void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt)
+{
+ const Point& rPos = rMEvt.GetPosPixel();
+ size_t nSelectedMenu = getEnclosingMenuItem(rPos);
+ setSelectedMenuItem(nSelectedMenu, true, false);
+
+ Window::MouseMove(rMEvt);
+}
+
+void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ const Point& rPos = rMEvt.GetPosPixel();
+ mnClickedMenu = getEnclosingMenuItem(rPos);
+ Window::MouseButtonDown(rMEvt);
+}
+
+void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt)
+{
+ executeMenuItem(mnClickedMenu);
+ mnClickedMenu = MENU_NOT_SELECTED;
+ Window::MouseButtonUp(rMEvt);
+}
+
+void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt)
+{
+ const KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ bool bHandled = true;
+ size_t nSelectedMenu = mnSelectedMenu;
+ size_t nLastMenuPos = maMenuItems.size() - 1;
+ switch (rKeyCode.GetCode())
+ {
+ case KEY_UP:
+ if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0)
+ nSelectedMenu = nLastMenuPos;
+ else
+ --nSelectedMenu;
+ setSelectedMenuItem(nSelectedMenu, false, false);
+ break;
+ case KEY_DOWN:
+ if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos)
+ nSelectedMenu = 0;
+ else
+ ++nSelectedMenu;
+ setSelectedMenuItem(nSelectedMenu, false, false);
+ break;
+ case KEY_LEFT:
+ if (mpParentMenu)
+ mpParentMenu->endSubMenu(this);
+ break;
+ case KEY_RIGHT:
+ {
+ if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
+ break;
+
+ const MenuItemData& rMenu = maMenuItems[mnSelectedMenu];
+ if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin)
+ break;
+
+ maOpenTimer.mnMenuPos = mnSelectedMenu;
+ maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get();
+ launchSubMenu(true);
+ }
+ break;
+ case KEY_RETURN:
+ if (nSelectedMenu != MENU_NOT_SELECTED)
+ executeMenuItem(nSelectedMenu);
+ break;
+ default:
+ bHandled = false;
+ }
+
+ if (!bHandled)
+ Window::KeyInput(rKEvt);
+}
+
+void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/)
+{
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+ Color aBackColor = rStyle.GetMenuColor();
+ Color aBorderColor = rStyle.GetShadowColor();
+
+ Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel());
+
+ // Window background
+ bool bNativeDrawn = true;
+ if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
+ {
+ SetClipRegion();
+ bNativeDrawn = DrawNativeControl(
+ CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED,
+ ImplControlValue(), OUString());
+ }
+ else
+ bNativeDrawn = false;
+
+ if (!bNativeDrawn)
+ {
+ SetFillColor(aBackColor);
+ SetLineColor(aBorderColor);
+ DrawRect(aCtrlRect);
+ }
+
+ // Menu items
+ SetTextColor(rStyle.GetMenuTextColor());
+ drawAllMenuItems();
+}
+
+Reference<XAccessible> ScMenuFloatingWindow::CreateAccessible()
+{
+ if (!mxAccessible.is())
+ {
+ Reference<XAccessible> xAccParent = mpParentMenu ?
+ mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible();
+
+ mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, 999, getDoc()));
+ ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(
+ mxAccessible.get());
+
+ vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
+ for (itr = itrBeg; itr != itrEnd; ++itr)
+ {
+ size_t nPos = ::std::distance(itrBeg, itr);
+ p->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
+ }
+ }
+
+ return mxAccessible;
+}
+
+void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction)
+{
+ MenuItemData aItem;
+ aItem.maText = rText;
+ aItem.mbEnabled = bEnabled;
+ aItem.mpAction.reset(pAction);
+ maMenuItems.push_back(aItem);
+}
+
+ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled)
+{
+ MenuItemData aItem;
+ aItem.maText = rText;
+ aItem.mbEnabled = bEnabled;
+ aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc, GetMenuStackLevel()+1));
+ aItem.mpSubMenuWin->setName(rText);
+ maMenuItems.push_back(aItem);
+ return aItem.mpSubMenuWin.get();
+}
+
+void ScMenuFloatingWindow::drawMenuItem(size_t nPos)
+{
+ if (nPos >= maMenuItems.size())
+ return;
+
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(nPos, aPos, aSize);
+
+ DecorationView aDecoView(this);
+ long nXOffset = 5;
+ long nYOffset = (aSize.Height() - maLabelFont.GetHeight())/2;
+ DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0, STRING_LEN,
+ maMenuItems[nPos].mbEnabled ? TEXT_DRAW_MNEMONIC : TEXT_DRAW_DISABLE);
+
+ if (maMenuItems[nPos].mpSubMenuWin)
+ {
+ long nFontHeight = maLabelFont.GetHeight();
+ Point aMarkerPos = aPos;
+ aMarkerPos.Y() += aSize.Height()/2 - nFontHeight/4 + 1;
+ aMarkerPos.X() += aSize.Width() - nFontHeight + nFontHeight/4;
+ Size aMarkerSize(nFontHeight/2, nFontHeight/2);
+ aDecoView.DrawSymbol(Rectangle(aMarkerPos, aMarkerSize),
+ SYMBOL_SPIN_RIGHT, GetTextColor(), 0);
+ }
+}
+
+void ScMenuFloatingWindow::drawAllMenuItems()
+{
+ size_t n = maMenuItems.size();
+ for (size_t i = 0; i < n; ++i)
+ highlightMenuItem(i, i == mnSelectedMenu);
+}
+
+const Font& ScMenuFloatingWindow::getLabelFont() const
+{
+ return maLabelFont;
+}
+
+void ScMenuFloatingWindow::executeMenuItem(size_t nPos)
+{
+ if (nPos >= maMenuItems.size())
+ return;
+
+ if (!maMenuItems[nPos].mpAction)
+ // no action is defined.
+ return;
+
+ maMenuItems[nPos].mpAction->execute();
+ terminateAllPopupMenus();
+}
+
+void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu)
+{
+ if (mnSelectedMenu == nPos)
+ // nothing to do.
+ return;
+
+ if (bEnsureSubMenu)
+ {
+ // Dismiss any child popup menu windows.
+ if (mnSelectedMenu < maMenuItems.size() &&
+ maMenuItems[mnSelectedMenu].mpSubMenuWin &&
+ maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
+ {
+ maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
+ }
+
+ // The popup is not visible, yet a menu item is selected. The request
+ // most likely comes from the accessible object. Make sure this
+ // window, as well as all its parent windows are visible.
+ if (!IsVisible() && mpParentMenu)
+ mpParentMenu->ensureSubMenuVisible(this);
+ }
+
+ selectMenuItem(mnSelectedMenu, false, bSubMenuTimer);
+ selectMenuItem(nPos, true, bSubMenuTimer);
+ mnSelectedMenu = nPos;
+
+ fireMenuHighlightedEvent();
+}
+
+size_t ScMenuFloatingWindow::getSelectedMenuItem() const
+{
+ return mnSelectedMenu;
+}
+
+void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItemData* pTimer)
+{
+ if (pTimer == &maOpenTimer)
+ {
+ // Close any open submenu immediately.
+ if (maCloseTimer.mpSubMenu)
+ {
+ maCloseTimer.mpSubMenu->EndPopupMode();
+ maCloseTimer.mpSubMenu = NULL;
+ maCloseTimer.maTimer.Stop();
+ }
+
+ launchSubMenu(false);
+ }
+ else if (pTimer == &maCloseTimer)
+ {
+ // end submenu.
+ if (maCloseTimer.mpSubMenu)
+ {
+ maOpenTimer.mpSubMenu = NULL;
+
+ maCloseTimer.mpSubMenu->EndPopupMode();
+ maCloseTimer.mpSubMenu = NULL;
+
+ highlightMenuItem(maOpenTimer.mnMenuPos, false);
+ maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
+ }
+ }
+}
+
+void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu)
+{
+ if (!pMenu)
+ return;
+
+ // Set the submenu on launch queue.
+ if (maOpenTimer.mpSubMenu)
+ {
+ if (maOpenTimer.mpSubMenu == pMenu)
+ {
+ if (pMenu == maCloseTimer.mpSubMenu)
+ maCloseTimer.reset();
+ return;
+ }
+
+ // new submenu is being requested.
+ queueCloseSubMenu();
+ }
+
+ maOpenTimer.mpSubMenu = pMenu;
+ maOpenTimer.mnMenuPos = nPos;
+ maOpenTimer.maTimer.Start();
+}
+
+void ScMenuFloatingWindow::queueCloseSubMenu()
+{
+ if (!maOpenTimer.mpSubMenu)
+ // There is no submenu to close.
+ return;
+
+ // Stop any submenu on queue for opening.
+ maOpenTimer.maTimer.Stop();
+
+ maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu;
+ maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos;
+ maCloseTimer.maTimer.Start();
+}
+
+void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos)
+{
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize);
+ ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu;
+
+ if (!pSubMenu)
+ return;
+
+ sal_uInt32 nOldFlags = GetPopupModeFlags();
+ SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
+ pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
+ pSubMenu->StartPopupMode(
+ Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
+ pSubMenu->AddPopupModeWindow(this);
+ if (bSetMenuPos)
+ pSubMenu->setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible.
+ SetPopupModeFlags(nOldFlags);
+}
+
+void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu)
+{
+ if (!pSubMenu)
+ return;
+
+ pSubMenu->EndPopupMode();
+ maOpenTimer.reset();
+
+ size_t nMenuPos = getSubMenuPos(pSubMenu);
+ if (nMenuPos != MENU_NOT_SELECTED)
+ {
+ highlightMenuItem(nMenuPos, true);
+ mnSelectedMenu = nMenuPos;
+ fireMenuHighlightedEvent();
+ }
+}
+
+void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const
+{
+ vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
+ for (itr = itrBeg; itr != itrEnd; ++itr)
+ {
+ size_t nPos = ::std::distance(itrBeg, itr);
+ pAccMenu->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
+ }
+}
+
+ScDocument* ScMenuFloatingWindow::getDoc()
+{
+ return mpDoc;
+}
+
+void ScMenuFloatingWindow::resizeToFitMenuItems()
+{
+ if (maMenuItems.empty())
+ return;
+
+ vector<MenuItemData>::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end();
+ long nTextWidth = 0;
+ for (; itr != itrEnd; ++itr)
+ nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth);
+
+ size_t nLastPos = maMenuItems.size()-1;
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(nLastPos, aPos, aSize);
+ aPos.X() += nTextWidth + 15;
+ aPos.Y() += aSize.Height() + 5;
+ SetOutputSizePixel(Size(aPos.X(), aPos.Y()));
+}
+
+void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer)
+{
+ if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED)
+ {
+ queueCloseSubMenu();
+ return;
+ }
+
+ if (!maMenuItems[nPos].mbEnabled)
+ {
+ queueCloseSubMenu();
+ return;
+ }
+
+ highlightMenuItem(nPos, bSelected);
+
+ if (bSelected)
+ {
+ if (mpParentMenu)
+ mpParentMenu->setSubMenuFocused(this);
+
+ if (bSubMenuTimer)
+ {
+ if (maMenuItems[nPos].mpSubMenuWin)
+ {
+ ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get();
+ queueLaunchSubMenu(nPos, pSubMenu);
+ }
+ else
+ queueCloseSubMenu();
+ }
+ }
+}
+
+void ScMenuFloatingWindow::clearSelectedMenuItem()
+{
+ selectMenuItem(mnSelectedMenu, false, false);
+ mnSelectedMenu = MENU_NOT_SELECTED;
+}
+
+ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const
+{
+ if (maMenuItems.size() <= nPos)
+ return NULL;
+
+ return maMenuItems[nPos].mpSubMenuWin.get();
+}
+
+size_t ScMenuFloatingWindow::getMenuItemCount() const
+{
+ return maMenuItems.size();
+}
+
+OUString ScMenuFloatingWindow::getMenuItemName(size_t nPos) const
+{
+ if (maMenuItems.size() <= nPos)
+ return ScGlobal::GetEmptyString();
+
+ return maMenuItems[nPos].maText;
+}
+
+bool ScMenuFloatingWindow::isMenuItemEnabled(size_t nPos) const
+{
+ if (maMenuItems.size() <= nPos)
+ return false;
+
+ return maMenuItems[nPos].mbEnabled;
+}
+
+bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const
+{
+ return nPos == mnSelectedMenu;
+}
+
+void ScMenuFloatingWindow::setName(const OUString& rName)
+{
+ maName = rName;
+}
+
+const OUString& ScMenuFloatingWindow::getName() const
+{
+ return maName;
+}
+
+void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected)
+{
+ if (nPos == MENU_NOT_SELECTED)
+ return;
+
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+ Color aBackColor = rStyle.GetMenuColor();
+ SetFillColor(aBackColor);
+ SetLineColor(aBackColor);
+
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(nPos, aPos, aSize);
+ Region aRegion(Rectangle(aPos,aSize));
+
+ if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
+ {
+ Push(PUSH_CLIPREGION);
+ IntersectClipRegion(Rectangle(aPos, aSize));
+ Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
+ DrawNativeControl(
+ CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED,
+ ImplControlValue(), OUString());
+
+ Pop();
+ }
+
+ bool bNativeDrawn = true;
+ if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM))
+ {
+ ControlState nState = bSelected ? CTRL_STATE_SELECTED : 0;
+ if (maMenuItems[nPos].mbEnabled)
+ nState |= CTRL_STATE_ENABLED;
+ bNativeDrawn = DrawNativeControl(
+ CTRL_MENU_POPUP, PART_MENU_ITEM, aRegion, nState, ImplControlValue(), OUString());
+ }
+ else
+ bNativeDrawn = false;
+
+ if (!bNativeDrawn)
+ {
+ if (bSelected)
+ {
+ aBackColor = rStyle.GetMenuHighlightColor();
+ SetFillColor(aBackColor);
+ SetLineColor(aBackColor);
+ }
+ DrawRect(Rectangle(aPos,aSize));
+ }
+
+ Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor();
+ SetTextColor(aTextColor);
+ drawMenuItem(nPos);
+}
+
+void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const
+{
+ const sal_uInt16 nLeftMargin = 5;
+ const sal_uInt16 nTopMargin = 5;
+ const sal_uInt16 nMenuItemHeight = static_cast< sal_uInt16 >( maLabelFont.GetHeight()*1.8 );
+
+ Size aWndSize = GetSizePixel();
+
+ Point aPos1(nLeftMargin, nTopMargin);
+ Size aSize1(aWndSize.Width() - nLeftMargin*2, nMenuItemHeight);
+
+ rPos = aPos1;
+ rPos.Y() += aSize1.Height()*nPos;
+ rSize = aSize1;
+}
+
+ScMenuFloatingWindow* ScMenuFloatingWindow::getParentMenuWindow() const
+{
+ return mpParentMenu;
+}
+
+size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const
+{
+ size_t n = maMenuItems.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(i, aPos, aSize);
+ Rectangle aRect(aPos, aSize);
+ if (aRect.IsInside(rPos))
+ return i;
+ }
+ return MENU_NOT_SELECTED;
+}
+
+size_t ScMenuFloatingWindow::getSubMenuPos(ScMenuFloatingWindow* pSubMenu)
+{
+ size_t n = maMenuItems.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ if (maMenuItems[i].mpSubMenuWin.get() == pSubMenu)
+ return i;
+ }
+ return MENU_NOT_SELECTED;
+}
+
+void ScMenuFloatingWindow::fireMenuHighlightedEvent()
+{
+ if (mnSelectedMenu == MENU_NOT_SELECTED)
+ return;
+
+ if (!mxAccessible.is())
+ return;
+
+ Reference<XAccessibleContext> xAccCxt = mxAccessible->getAccessibleContext();
+ if (!xAccCxt.is())
+ return;
+
+ Reference<XAccessible> xAccMenu = xAccCxt->getAccessibleChild(mnSelectedMenu);
+ if (!xAccMenu.is())
+ return;
+
+ VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu);
+ FireVclEvent(&aEvent);
+}
+
+void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu)
+{
+ maCloseTimer.reset();
+ size_t nMenuPos = getSubMenuPos(pSubMenu);
+ if (mnSelectedMenu != nMenuPos)
+ {
+ highlightMenuItem(nMenuPos, true);
+ mnSelectedMenu = nMenuPos;
+ }
+}
+
+void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu)
+{
+ if (mpParentMenu)
+ mpParentMenu->ensureSubMenuVisible(this);
+
+ if (pSubMenu->IsVisible())
+ return;
+
+ // Find the menu position of the submenu.
+ size_t nMenuPos = getSubMenuPos(pSubMenu);
+ if (nMenuPos != MENU_NOT_SELECTED)
+ {
+ setSelectedMenuItem(nMenuPos, false, false);
+
+ Point aPos;
+ Size aSize;
+ getMenuItemPosSize(nMenuPos, aPos, aSize);
+
+ sal_uInt32 nOldFlags = GetPopupModeFlags();
+ SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
+ pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
+ pSubMenu->StartPopupMode(
+ Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
+ pSubMenu->AddPopupModeWindow(this);
+ SetPopupModeFlags(nOldFlags);
+ }
+}
+
+void ScMenuFloatingWindow::ensureSubMenuNotVisible()
+{
+ if (mnSelectedMenu <= maMenuItems.size() &&
+ maMenuItems[mnSelectedMenu].mpSubMenuWin &&
+ maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
+ {
+ maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
+ }
+
+ EndPopupMode();
+}
+
+void ScMenuFloatingWindow::terminateAllPopupMenus()
+{
+ EndPopupMode();
+ if (mpParentMenu)
+ mpParentMenu->terminateAllPopupMenus();
+}
+
+IMPL_LINK( ScMenuFloatingWindow, PopupEndHdl, void*, EMPTYARG )
+{
+ clearSelectedMenuItem();
+ return 0;
+}
+
+// ============================================================================
+
+ScDPFieldPopupWindow::Member::Member() :
+ mbVisible(true)
+{
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPFieldPopupWindow::CancelButton::CancelButton(ScDPFieldPopupWindow* pParent) :
+ ::CancelButton(pParent), mpParent(pParent) {}
+
+void ScDPFieldPopupWindow::CancelButton::Click()
+{
+ mpParent->EndPopupMode();
+ ::CancelButton::Click();
+}
+
+// ----------------------------------------------------------------------------
+
+ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc) :
+ ScMenuFloatingWindow(pParent, pDoc),
+ maChecks(this, 0),
+ maChkToggleAll(this, 0),
+ maBtnSelectSingle (this, 0),
+ maBtnUnselectSingle(this, 0),
+ maBtnOk(this),
+ maBtnCancel(this),
+ mnCurTabStop(0),
+ mpExtendedData(NULL),
+ mpOKAction(NULL),
+ maWndSize(160, 330),
+ mePrevToggleAllState(STATE_DONTKNOW)
+{
+ maTabStopCtrls.reserve(7);
+ maTabStopCtrls.push_back(this);
+ maTabStopCtrls.push_back(&maChecks);
+ maTabStopCtrls.push_back(&maChkToggleAll);
+ maTabStopCtrls.push_back(&maBtnSelectSingle);
+ maTabStopCtrls.push_back(&maBtnUnselectSingle);
+ maTabStopCtrls.push_back(&maBtnOk);
+ maTabStopCtrls.push_back(&maBtnCancel);
+
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+
+ Point aPos;
+ Size aSize;
+ getSectionPosSize(aPos, aSize, WHOLE);
+ SetOutputSizePixel(aSize);
+ Size aOutSize = GetOutputSizePixel();
+
+ getSectionPosSize(aPos, aSize, BTN_OK);
+ maBtnOk.SetPosSizePixel(aPos, aSize);
+ maBtnOk.SetFont(getLabelFont());
+ maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
+ maBtnOk.Show();
+
+ getSectionPosSize(aPos, aSize, BTN_CANCEL);
+ maBtnCancel.SetPosSizePixel(aPos, aSize);
+ maBtnCancel.SetFont(getLabelFont());
+ maBtnCancel.Show();
+
+ getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER);
+ maChecks.SetPosSizePixel(aPos, aSize);
+ maChecks.SetFont(getLabelFont());
+ maChecks.SetCheckButtonHdl( LINK(this, ScDPFieldPopupWindow, CheckHdl) );
+ maChecks.Show();
+
+ getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL);
+ maChkToggleAll.SetPosSizePixel(aPos, aSize);
+ maChkToggleAll.SetFont(getLabelFont());
+ maChkToggleAll.SetText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL).GetString());
+ maChkToggleAll.SetControlBackground(rStyle.GetMenuColor());
+ maChkToggleAll.SetClickHdl( LINK(this, ScDPFieldPopupWindow, TriStateHdl) );
+ maChkToggleAll.Show();
+
+ getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT);
+ maBtnSelectSingle.SetPosSizePixel(aPos, aSize);
+ maBtnSelectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT).GetString());
+ maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT)), BMP_COLOR_NORMAL);
+ maBtnSelectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
+ maBtnSelectSingle.Show();
+
+ getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT);
+ maBtnUnselectSingle.SetPosSizePixel(aPos, aSize);
+ maBtnUnselectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT).GetString());
+ maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT)), BMP_COLOR_NORMAL);
+ maBtnUnselectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
+ maBtnUnselectSingle.Show();
+}
+
+ScDPFieldPopupWindow::~ScDPFieldPopupWindow()
+{
+}
+
+void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const
+{
+ // constant parameters.
+ const sal_uInt16 nListBoxMargin = 5; // horizontal distance from the side of the dialog to the listbox border.
+ const sal_uInt16 nListBoxInnerPadding = 5;
+ const sal_uInt16 nTopMargin = 5;
+ const sal_uInt16 nMenuHeight = 60;
+ const sal_uInt16 nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are.
+ const sal_uInt16 nBottomBtnAreaHeight = 50; // height of the bottom area where the OK and Cancel buttons are.
+ const sal_uInt16 nBtnWidth = 60;
+ const sal_uInt16 nLabelHeight = static_cast< sal_uInt16 >( getLabelFont().GetHeight() );
+ const sal_uInt16 nBtnHeight = nLabelHeight*2;
+ const sal_uInt16 nBottomMargin = 10;
+ const sal_uInt16 nMenuListMargin = 20;
+
+ // parameters calculated from constants.
+ const sal_uInt16 nListBoxWidth = static_cast< sal_uInt16 >( maWndSize.Width() - nListBoxMargin*2 );
+ const sal_uInt16 nListBoxHeight = static_cast< sal_uInt16 >( maWndSize.Height() - nTopMargin - nMenuHeight -
+ nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight );
+
+ const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1;
+
+ switch (eType)
+ {
+ case WHOLE:
+ {
+ rPos = Point(0, 0);
+ rSize = maWndSize;
+ }
+ break;
+ case LISTBOX_AREA_OUTER:
+ {
+ rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
+ rSize = Size(nListBoxWidth, nListBoxHeight);
+ }
+ break;
+ case LISTBOX_AREA_INNER:
+ {
+ rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
+ rPos.X() += nListBoxInnerPadding;
+ rPos.Y() += nListBoxInnerPadding;
+
+ rSize = Size(nListBoxWidth, nListBoxHeight);
+ rSize.Width() -= nListBoxInnerPadding*2;
+ rSize.Height() -= nListBoxInnerPadding*2;
+ }
+ break;
+ case SINGLE_BTN_AREA:
+ {
+ rPos = Point(nListBoxMargin, nSingleBtnAreaY);
+ rSize = Size(nListBoxWidth, nSingleItemBtnAreaHeight);
+ }
+ break;
+ case CHECK_TOGGLE_ALL:
+ {
+ long h = nLabelHeight*3/2; // check box height is heuristically 150% of the text height.
+ rPos = Point(nListBoxMargin, nSingleBtnAreaY);
+ rPos.X() += 5;
+ rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
+ rSize = Size(70, h);
+ }
+ break;
+ case BTN_SINGLE_SELECT:
+ {
+ long h = 26;
+ rPos = Point(nListBoxMargin, nSingleBtnAreaY);
+ rPos.X() += 75;
+ rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
+ rSize = Size(h, h);
+ }
+ break;
+ case BTN_SINGLE_UNSELECT:
+ {
+ long h = 26;
+ rPos = Point(nListBoxMargin, nSingleBtnAreaY);
+ rPos.X() += 75 + h + 10;
+ rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
+ rSize = Size(h, h);
+ }
+ break;
+ case BTN_OK:
+ {
+ long x = (maWndSize.Width() - nBtnWidth*2)/3;
+ long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
+ rPos = Point(x, y);
+ rSize = Size(nBtnWidth, nBtnHeight);
+ }
+ break;
+ case BTN_CANCEL:
+ {
+ long x = (maWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
+ long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
+ rPos = Point(x, y);
+ rSize = Size(nBtnWidth, nBtnHeight);
+ }
+ break;
+ default:
+ ;
+ }
+}
+
+void ScDPFieldPopupWindow::setAllMemberState(bool bSet)
+{
+ size_t n = maMembers.size();
+ for (size_t i = 0; i < n; ++i)
+ maChecks.CheckEntryPos(static_cast< USHORT >( i ), bSet);
+}
+
+void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet)
+{
+ setAllMemberState(!bSet);
+ sal_uInt16 nSelected = maChecks.GetSelectEntryPos();
+ maChecks.CheckEntryPos(nSelected, bSet);
+}
+
+void ScDPFieldPopupWindow::cycleFocus(bool bReverse)
+{
+ maTabStopCtrls[mnCurTabStop]->SetFakeFocus(false);
+ maTabStopCtrls[mnCurTabStop]->LoseFocus();
+ if (mnCurTabStop == 0)
+ clearSelectedMenuItem();
+
+ if (bReverse)
+ {
+ if (mnCurTabStop > 0)
+ --mnCurTabStop;
+ else
+ mnCurTabStop = maTabStopCtrls.size() - 1;
+ }
+ else
+ {
+ ++mnCurTabStop;
+ if (mnCurTabStop >= maTabStopCtrls.size())
+ mnCurTabStop = 0;
+ }
+ maTabStopCtrls[mnCurTabStop]->SetFakeFocus(true);
+ maTabStopCtrls[mnCurTabStop]->GrabFocus();
+}
+
+IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn )
+{
+ if (pBtn == &maBtnOk)
+ close(true);
+ else if (pBtn == &maBtnSelectSingle)
+ {
+ selectCurrentMemberOnly(true);
+ CheckHdl(&maChecks);
+ }
+ else if (pBtn == &maBtnUnselectSingle)
+ {
+ selectCurrentMemberOnly(false);
+ CheckHdl(&maChecks);
+ }
+ return 0;
+}
+
+IMPL_LINK( ScDPFieldPopupWindow, TriStateHdl, TriStateBox*, EMPTYARG )
+{
+ switch (mePrevToggleAllState)
+ {
+ case STATE_NOCHECK:
+ maChkToggleAll.SetState(STATE_CHECK);
+ setAllMemberState(true);
+ break;
+ case STATE_CHECK:
+ maChkToggleAll.SetState(STATE_NOCHECK);
+ setAllMemberState(false);
+ break;
+ case STATE_DONTKNOW:
+ default:
+ maChkToggleAll.SetState(STATE_CHECK);
+ setAllMemberState(true);
+ break;
+ }
+
+ mePrevToggleAllState = maChkToggleAll.GetState();
+ return 0;
+}
+
+IMPL_LINK( ScDPFieldPopupWindow, CheckHdl, SvTreeListBox*, pChecks )
+{
+ if (pChecks != &maChecks)
+ return 0;
+
+ size_t nNumChecked = maChecks.GetCheckedEntryCount();
+ if (nNumChecked == maMembers.size())
+ // all members visible
+ maChkToggleAll.SetState(STATE_CHECK);
+ else if (nNumChecked == 0)
+ // no members visible
+ maChkToggleAll.SetState(STATE_NOCHECK);
+ else
+ maChkToggleAll.SetState(STATE_DONTKNOW);
+
+ mePrevToggleAllState = maChkToggleAll.GetState();
+ return 0;
+}
+
+void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt)
+{
+ ScMenuFloatingWindow::MouseMove(rMEvt);
+
+ size_t nSelectedMenu = getSelectedMenuItem();
+ if (nSelectedMenu == MENU_NOT_SELECTED)
+ queueCloseSubMenu();
+}
+
+long ScDPFieldPopupWindow::Notify(NotifyEvent& rNEvt)
+{
+ switch (rNEvt.GetType())
+ {
+ case EVENT_KEYUP:
+ {
+ const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
+ const KeyCode& rCode = pKeyEvent->GetKeyCode();
+ bool bShift = rCode.IsShift();
+ if (rCode.GetCode() == KEY_TAB)
+ {
+ cycleFocus(bShift);
+ return true;
+ }
+ }
+ break;
+ }
+ return ScMenuFloatingWindow::Notify(rNEvt);
+}
+
+void ScDPFieldPopupWindow::Paint(const Rectangle& rRect)
+{
+ ScMenuFloatingWindow::Paint(rRect);
+
+ const StyleSettings& rStyle = GetSettings().GetStyleSettings();
+ Color aMemberBackColor = rStyle.GetFieldColor();
+ Color aBorderColor = rStyle.GetShadowColor();
+
+ Point aPos;
+ Size aSize;
+ getSectionPosSize(aPos, aSize, LISTBOX_AREA_OUTER);
+
+ // Member list box background
+ SetFillColor(aMemberBackColor);
+ SetLineColor(aBorderColor);
+ DrawRect(Rectangle(aPos,aSize));
+
+ // Single-action button box
+ getSectionPosSize(aPos, aSize, SINGLE_BTN_AREA);
+ SetFillColor(rStyle.GetMenuColor());
+ DrawRect(Rectangle(aPos,aSize));
+}
+
+Window* ScDPFieldPopupWindow::GetPreferredKeyInputWindow()
+{
+ return maTabStopCtrls[mnCurTabStop];
+}
+
+Reference<XAccessible> ScDPFieldPopupWindow::CreateAccessible()
+{
+ if (!mxAccessible.is())
+ {
+ mxAccessible.set(new ScAccessibleFilterTopWindow(
+ GetAccessibleParentWindow()->GetAccessible(), this, getName(), getDoc()));
+ ScAccessibleFilterTopWindow* pAccTop = static_cast<ScAccessibleFilterTopWindow*>(mxAccessible.get());
+ fillMenuItemsToAccessible(pAccTop);
+
+ pAccTop->setAccessibleChild(
+ maChecks.CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX);
+ pAccTop->setAccessibleChild(
+ maChkToggleAll.CreateAccessible(), ScAccessibleFilterTopWindow::TOGGLE_ALL);
+ pAccTop->setAccessibleChild(
+ maBtnSelectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_ON_BTN);
+ pAccTop->setAccessibleChild(
+ maBtnUnselectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_OFF_BTN);
+ pAccTop->setAccessibleChild(
+ maBtnOk.CreateAccessible(), ScAccessibleFilterTopWindow::OK_BTN);
+ pAccTop->setAccessibleChild(
+ maBtnCancel.CreateAccessible(), ScAccessibleFilterTopWindow::CANCEL_BTN);
+ }
+
+ return mxAccessible;
+}
+
+void ScDPFieldPopupWindow::setMemberSize(size_t n)
+{
+ maMembers.reserve(n);
+}
+
+void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible)
+{
+ Member aMember;
+ aMember.maName = rName;
+ aMember.mbVisible = bVisible;
+ maMembers.push_back(aMember);
+}
+
+void ScDPFieldPopupWindow::initMembers()
+{
+ size_t n = maMembers.size();
+ size_t nVisMemCount = 0;
+ for (size_t i = 0; i < n; ++i)
+ {
+ maChecks.InsertEntry(maMembers[i].maName);
+ maChecks.CheckEntryPos(static_cast< USHORT >( i ), maMembers[i].mbVisible);
+ if (maMembers[i].mbVisible)
+ ++nVisMemCount;
+ }
+ if (nVisMemCount == n)
+ {
+ // all members visible
+ maChkToggleAll.SetState(STATE_CHECK);
+ mePrevToggleAllState = STATE_CHECK;
+ }
+ else if (nVisMemCount == 0)
+ {
+ // no members visible
+ maChkToggleAll.SetState(STATE_NOCHECK);
+ mePrevToggleAllState = STATE_NOCHECK;
+ }
+ else
+ {
+ maChkToggleAll.SetState(STATE_DONTKNOW);
+ mePrevToggleAllState = STATE_DONTKNOW;
+ }
+}
+
+const Size& ScDPFieldPopupWindow::getWindowSize() const
+{
+ return maWndSize;
+}
+
+void ScDPFieldPopupWindow::getResult(hash_map<OUString, bool, OUStringHash>& rResult)
+{
+ typedef hash_map<OUString, bool, OUStringHash> ResultMap;
+ ResultMap aResult;
+ size_t n = maMembers.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ bool bState = maChecks.IsChecked(static_cast< USHORT >( i ));
+ aResult.insert(ResultMap::value_type(maMembers[i].maName, bState));
+ }
+ rResult.swap(aResult);
+}
+
+void ScDPFieldPopupWindow::close(bool bOK)
+{
+ if (bOK && mpOKAction.get())
+ mpOKAction->execute();
+
+ EndPopupMode();
+}
+
+void ScDPFieldPopupWindow::setExtendedData(ExtendedData* p)
+{
+ mpExtendedData.reset(p);
+}
+
+ScDPFieldPopupWindow::ExtendedData* ScDPFieldPopupWindow::getExtendedData()
+{
+ return mpExtendedData.get();
+}
+
+void ScDPFieldPopupWindow::setOKAction(Action* p)
+{
+ mpOKAction.reset(p);
+}
+
diff --git a/sc/source/ui/cctrl/dpcontrol.src b/sc/source/ui/cctrl/dpcontrol.src
new file mode 100644
index 000000000000..31cbb62085e5
--- /dev/null
+++ b/sc/source/ui/cctrl/dpcontrol.src
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: globstr.src,v $
+ * $Revision: 1.74.96.1 $
+ *
+ * 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 "dpcontrol.hrc"
+
+Resource RID_POPUP_FILTER
+{
+ String STR_MENU_SORT_ASC
+ {
+ Text [ en-US ] = "Sort Ascending" ;
+ };
+
+ String STR_MENU_SORT_DESC
+ {
+ Text [ en-US ] = "Sort Descending" ;
+ };
+
+ String STR_MENU_SORT_CUSTOM
+ {
+ Text [ en-US ] = "Custom Sort" ;
+ };
+
+ String STR_BTN_TOGGLE_ALL
+ {
+ Text [ en-US ] = "All" ;
+ };
+
+ String STR_BTN_SELECT_CURRENT
+ {
+ Text [ en-US ] = "Show only the current item." ;
+ };
+
+ String STR_BTN_UNSELECT_CURRENT
+ {
+ Text [ en-US ] = "Hide only the current item." ;
+ };
+};
+
+Image RID_IMG_SELECT_CURRENT
+{
+ ImageBitmap = Bitmap
+ {
+ File = "popup_select_current.png";
+ };
+ MaskColor = STD_MASKCOLOR;
+};
+
+Image RID_IMG_UNSELECT_CURRENT
+{
+ ImageBitmap = Bitmap
+ {
+ File = "popup_unselect_current.png";
+ };
+ MaskColor = STD_MASKCOLOR;
+};
diff --git a/sc/source/ui/cctrl/makefile.mk b/sc/source/ui/cctrl/makefile.mk
index e7b96afd7b9a..541a90cc4347 100644
--- a/sc/source/ui/cctrl/makefile.mk
+++ b/sc/source/ui/cctrl/makefile.mk
@@ -45,22 +45,30 @@ LIBTARGET=NO
# --- Files --------------------------------------------------------
EXCEPTIONSFILES= \
- $(SLO)$/tbzoomsliderctrl.obj
+ $(SLO)$/tbzoomsliderctrl.obj \
+ $(SLO)$/dpcontrol.obj
SLOFILES = \
$(SLO)$/popmenu.obj \
$(SLO)$/tbinsert.obj \
$(SLO)$/cbuttonw.obj \
+ $(SLO)$/dpcontrol.obj \
$(SLO)$/editfield.obj \
$(EXCEPTIONSFILES)
+SRS1NAME=$(TARGET)
+SRC1FILES = \
+ dpcontrol.src
+
LIB1TARGET=$(SLB)$/$(TARGET).lib
LIB1OBJFILES= \
$(SLO)$/popmenu.obj \
$(SLO)$/tbinsert.obj \
$(SLO)$/cbuttonw.obj \
+ $(SLO)$/dpcontrol.obj \
$(SLO)$/tbzoomsliderctrl.obj
+
# --- Tagets -------------------------------------------------------
.INCLUDE : target.mk
diff --git a/sc/source/ui/dbgui/makefile.mk b/sc/source/ui/dbgui/makefile.mk
index b495b5eabcc9..9ff21b6c4d08 100644
--- a/sc/source/ui/dbgui/makefile.mk
+++ b/sc/source/ui/dbgui/makefile.mk
@@ -80,6 +80,7 @@ EXCEPTIONSFILES= \
$(SLO)$/csvsplits.obj \
$(SLO)$/csvtablebox.obj \
$(SLO)$/fieldwnd.obj \
+ $(SLO)$/pvfundlg.obj \
$(SLO)$/pvlaydlg.obj \
$(SLO)$/dapidata.obj \
$(SLO)$/validate.obj
diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx
index d44791ff6972..30ee1a44d384 100644
--- a/sc/source/ui/dbgui/pvfundlg.cxx
+++ b/sc/source/ui/dbgui/pvfundlg.cxx
@@ -48,12 +48,15 @@
#include "pvfundlg.hrc"
#include "globstr.hrc"
+#include <vector>
+
// ============================================================================
using namespace ::com::sun::star::sheet;
using ::rtl::OUString;
using ::com::sun::star::uno::Sequence;
+using ::std::vector;
// ============================================================================
@@ -86,6 +89,25 @@ bool lclFillListBox( ListBoxType& rLBox, const Sequence< OUString >& rStrings, U
return bEmpty;
}
+template< typename ListBoxType >
+bool lclFillListBox( ListBoxType& rLBox, const vector<ScDPLabelData::Member>& rMembers, USHORT nEmptyPos = LISTBOX_APPEND )
+{
+ bool bEmpty = false;
+ vector<ScDPLabelData::Member>::const_iterator itr = rMembers.begin(), itrEnd = rMembers.end();
+ for (; itr != itrEnd; ++itr)
+ {
+ OUString aName = itr->getDisplayName();
+ if (aName.getLength())
+ rLBox.InsertEntry(aName);
+ else
+ {
+ rLBox.InsertEntry(ScGlobal::GetRscString(STR_EMPTYDATA), nEmptyPos);
+ bEmpty = true;
+ }
+ }
+ return bEmpty;
+}
+
/** Searches for a listbox entry, starts search at specified position. */
USHORT lclFindListBoxEntry( const ListBox& rLBox, const String& rEntry, USHORT nStartPos )
{
@@ -253,7 +275,7 @@ void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData&
maLbFunc.SetSelection( nFuncMask );
// field name
- maFtName.SetText( rLabelData.maName );
+ maFtName.SetText(rLabelData.getDisplayName());
// "More button" controls
maBtnMore.AddWindow( &maFlDisplay );
@@ -271,7 +293,7 @@ void ScDPFunctionDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData&
// base field list box
for( ScDPLabelDataVec::const_iterator aIt = mrLabelVec.begin(), aEnd = mrLabelVec.end(); aIt != aEnd; ++aIt )
- maLbBaseField.InsertEntry( aIt->maName );
+ maLbBaseField.InsertEntry(aIt->getDisplayName());
// base item list box
maLbBaseItem.SetSeparatorPos( SC_BASEITEM_USER_POS - 1 );
@@ -414,8 +436,6 @@ void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const
rLabelData.mnUsedHier = maLabelData.mnUsedHier;
rLabelData.mbShowAll = maCbShowAll.IsChecked();
rLabelData.maMembers = maLabelData.maMembers;
- rLabelData.maVisible = maLabelData.maVisible;
- rLabelData.maShowDet = maLabelData.maShowDet;
rLabelData.maSortInfo = maLabelData.maSortInfo;
rLabelData.maLayoutInfo = maLabelData.maLayoutInfo;
rLabelData.maShowInfo = maLabelData.maShowInfo;
@@ -424,7 +444,7 @@ void ScDPSubtotalDlg::FillLabelData( ScDPLabelData& rLabelData ) const
void ScDPSubtotalDlg::Init( const ScDPLabelData& rLabelData, const ScDPFuncData& rFuncData )
{
// field name
- maFtName.SetText( rLabelData.maName );
+ maFtName.SetText(rLabelData.getDisplayName());
// radio buttons
maRbNone.SetClickHdl( LINK( this, ScDPSubtotalDlg, RadioClickHdl ) );
@@ -547,9 +567,8 @@ void ScDPSubtotalOptDlg::FillLabelData( ScDPLabelData& rLabelData ) const
rLabelData.maMembers = maLabelData.maMembers;
ULONG nVisCount = maLbHide.GetEntryCount();
- rLabelData.maVisible.realloc( nVisCount );
for( USHORT nPos = 0; nPos < nVisCount; ++nPos )
- rLabelData.maVisible[ nPos ] = !maLbHide.IsChecked( nPos );
+ rLabelData.maMembers[nPos].mbVisible = !maLbHide.IsChecked(nPos);
// *** HIERARCHY ***
@@ -563,7 +582,8 @@ void ScDPSubtotalOptDlg::Init( const ScDPNameVec& rDataFields, bool bEnableLayou
sal_Int32 nSortMode = maLabelData.maSortInfo.Mode;
// sort fields list box
- maLbSortBy.InsertEntry( maLabelData.maName );
+ maLbSortBy.InsertEntry(maLabelData.getDisplayName());
+
for( ScDPNameVec::const_iterator aIt = rDataFields.begin(), aEnd = rDataFields.end(); aIt != aEnd; ++aIt )
{
maLbSortBy.InsertEntry( *aIt );
@@ -656,8 +676,9 @@ void ScDPSubtotalOptDlg::InitHideListBox()
{
maLbHide.Clear();
lclFillListBox( maLbHide, maLabelData.maMembers );
- for( sal_Int32 nVisIdx = 0, nVisSize = maLabelData.maVisible.getLength(); nVisIdx < nVisSize; ++nVisIdx )
- maLbHide.CheckEntryPos( static_cast< USHORT >( nVisIdx ), !maLabelData.maVisible[ nVisIdx ] );
+ size_t n = maLabelData.maMembers.size();
+ for (size_t i = 0; i < n; ++i)
+ maLbHide.CheckEntryPos(static_cast<USHORT>(i), !maLabelData.maMembers[i].mbVisible);
bool bEnable = maLbHide.GetEntryCount() > 0;
maFlHide.Enable( bEnable );
maLbHide.Enable( bEnable );
@@ -690,8 +711,7 @@ IMPL_LINK( ScDPSubtotalOptDlg, SelectHdl, ListBox*, pLBox )
{
if( pLBox == &maLbHierarchy )
{
- mrDPObj.GetMembers( maLabelData.mnCol, maLbHierarchy.GetSelectEntryPos(),
- maLabelData.maMembers, &maLabelData.maVisible, &maLabelData.maShowDet );
+ mrDPObj.GetMembers(maLabelData.mnCol, maLbHierarchy.GetSelectEntryPos(), maLabelData.maMembers);
InitHideListBox();
}
return 0;
@@ -705,7 +725,9 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR
maLbDims ( this, ScResId( LB_DIMS ) ),
maBtnOk ( this, ScResId( BTN_OK ) ),
maBtnCancel ( this, ScResId( BTN_CANCEL ) ),
- maBtnHelp ( this, ScResId( BTN_HELP ) )
+ maBtnHelp ( this, ScResId( BTN_HELP ) ),
+
+ mrDPObj(rDPObj)
{
FreeResource();
@@ -719,7 +741,13 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR
{
const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : 0;
if ( !pDimension || (pDimension->GetOrientation() != nOrient) )
+ {
+ const OUString* pLayoutName = pDimension->GetLayoutName();
+ if (pLayoutName)
+ aName = *pLayoutName;
maLbDims.InsertEntry( aName );
+ maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim));
+ }
}
}
if( maLbDims.GetEntryCount() )
@@ -735,7 +763,17 @@ short ScDPShowDetailDlg::Execute()
String ScDPShowDetailDlg::GetDimensionName() const
{
- return maLbDims.GetSelectEntry();
+ // Look up the internal dimension name which may be different from the
+ // displayed field name.
+ String aSelectedName = maLbDims.GetSelectEntry();
+ DimNameIndexMap::const_iterator itr = maNameIndexMap.find(aSelectedName);
+ if (itr == maNameIndexMap.end())
+ // This should never happen!
+ return aSelectedName;
+
+ long nDim = itr->second;
+ BOOL bIsDataLayout = false;
+ return mrDPObj.GetDimName(nDim, bIsDataLayout);
}
IMPL_LINK( ScDPShowDetailDlg, DblClickHdl, ListBox*, pLBox )
diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx
index 7b03e067a865..6a9bb63e3ae3 100644
--- a/sc/source/ui/dbgui/pvlaydlg.cxx
+++ b/sc/source/ui/dbgui/pvlaydlg.cxx
@@ -63,6 +63,8 @@
#include "sc.hrc" //CHINA001
#include "scabstdlg.hxx" //CHINA001
using namespace com::sun::star;
+using ::rtl::OUString;
+using ::std::vector;
//----------------------------------------------------------------------------
@@ -378,24 +380,23 @@ void ScDPLayoutDlg::StateChanged( StateChangedType nStateChange )
//----------------------------------------------------------------------------
-void ScDPLayoutDlg::InitWndSelect( LabelData** ppLabelArr, long nLabels )
+void ScDPLayoutDlg::InitWndSelect( const vector<ScDPLabelDataRef>& rLabels )
{
- if ( ppLabelArr )
+ size_t nLabelCount = rLabels.size();
+ if (nLabelCount > MAX_LABELS)
+ nLabelCount = MAX_LABELS;
+ size_t nLast = (nLabelCount > PAGE_SIZE) ? (PAGE_SIZE - 1) : (nLabelCount - 1);
+
+ aLabelDataArr.clear();
+ aLabelDataArr.reserve( nLabelCount );
+ for ( size_t i=0; i < nLabelCount; i++ )
{
- size_t nLabelCount = static_cast< size_t >( (nLabels > MAX_LABELS) ? MAX_LABELS : nLabels );
- size_t nLast = (nLabelCount > PAGE_SIZE) ? (PAGE_SIZE - 1) : (nLabelCount - 1);
+ aLabelDataArr.push_back(*rLabels[i]);
- aLabelDataArr.clear();
- aLabelDataArr.reserve( nLabelCount );
- for ( size_t i=0; i < nLabelCount; i++ )
+ if ( i <= nLast )
{
- aLabelDataArr.push_back( *ppLabelArr[i] );
-
- if ( i <= nLast )
- {
- aWndSelect.AddField( aLabelDataArr[i].maName, i );
- aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) );
- }
+ aWndSelect.AddField(aLabelDataArr[i].getDisplayName(), i);
+ aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) );
}
}
}
@@ -493,18 +494,19 @@ void ScDPLayoutDlg::InitFocus()
void ScDPLayoutDlg::InitFields()
{
- InitWndSelect( thePivotData.ppLabelArr, static_cast<long>(thePivotData.nLabels) );
+ InitWndSelect(thePivotData.maLabelArray);
InitWnd( thePivotData.aPageArr, static_cast<long>(thePivotData.nPageCount), TYPE_PAGE );
InitWnd( thePivotData.aColArr, static_cast<long>(thePivotData.nColCount), TYPE_COL );
InitWnd( thePivotData.aRowArr, static_cast<long>(thePivotData.nRowCount), TYPE_ROW );
InitWnd( thePivotData.aDataArr, static_cast<long>(thePivotData.nDataCount), TYPE_DATA );
+ size_t nLabels = thePivotData.maLabelArray.size();
aSlider.SetPageSize( PAGE_SIZE );
aSlider.SetVisibleSize( PAGE_SIZE );
aSlider.SetLineSize( LINE_SIZE );
- aSlider.SetRange( Range( 0, static_cast<long>(((thePivotData.nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) );
+ aSlider.SetRange( Range( 0, static_cast<long>(((nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) );
- if ( thePivotData.nLabels > PAGE_SIZE )
+ if ( nLabels > PAGE_SIZE )
{
aSlider.SetEndScrollHdl( LINK( this, ScDPLayoutDlg, ScrollHdl ) );
aSlider.Show();
@@ -594,7 +596,7 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po
if ( !bDataArr )
{
- if ( toWnd->AddField( rData.maName,
+ if ( toWnd->AddField( rData.getDisplayName(),
DlgPos2WndPos( rAtPos, *toWnd ),
nAddedAt ) )
{
@@ -605,9 +607,9 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po
else
{
USHORT nMask = fData.mnFuncMask;
- String aStr( GetFuncString( nMask, rData.mbIsValue ) );
+ OUString aStr = GetFuncString( nMask, rData.mbIsValue );
- aStr += rData.maName;
+ aStr += rData.getDisplayName();
if ( toWnd->AddField( aStr,
DlgPos2WndPos( rAtPos, *toWnd ),
@@ -1215,7 +1217,7 @@ String ScDPLayoutDlg::GetLabelString( SCsCOL nCol )
ScDPLabelData* pData = GetLabelData( nCol );
DBG_ASSERT( pData, "LabelData not found" );
if (pData)
- return pData->maName;
+ return pData->getDisplayName();
return String();
}
@@ -1491,6 +1493,8 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG )
nPageCount, nColCount, nRowCount, nDataCount );
if ( bFit )
{
+ ScDPSaveData* pOldSaveData = xDlgDPObject->GetSaveData();
+
ScRange aOutRange( aAdrDest ); // bToNewTable is passed separately
ScDPSaveData aSaveData;
@@ -1522,31 +1526,63 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG )
pDim->SetSortInfo( &aIt->maSortInfo );
pDim->SetLayoutInfo( &aIt->maLayoutInfo );
pDim->SetAutoShowInfo( &aIt->maShowInfo );
+ ScDPSaveDimension* pOldDim = NULL;
+ if (pOldSaveData)
+ {
+ // Transfer the existing layout names to new dimension instance.
+ pOldDim = pOldSaveData->GetExistingDimensionByName(aIt->maName);
+ if (pOldDim)
+ {
+ const OUString* pLayoutName = pOldDim->GetLayoutName();
+ if (pLayoutName)
+ pDim->SetLayoutName(*pLayoutName);
+
+ const OUString* pSubtotalName = pOldDim->GetSubtotalName();
+ if (pSubtotalName)
+ pDim->SetSubtotalName(*pSubtotalName);
+ }
+ }
bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL );
// visibility of members
- if( const rtl::OUString* pItem = aIt->maMembers.getConstArray() )
+ for (vector<ScDPLabelData::Member>::const_iterator itr = aIt->maMembers.begin(), itrEnd = aIt->maMembers.end();
+ itr != itrEnd; ++itr)
{
- sal_Int32 nIdx = 0;
- sal_Int32 nVisSize = aIt->maVisible.getLength();
- sal_Int32 nShowSize = aIt->maShowDet.getLength();
- for( const rtl::OUString* pEnd = pItem + aIt->maMembers.getLength(); pItem != pEnd; ++pItem, ++nIdx )
+ ScDPSaveMember* pMember = pDim->GetMemberByName(itr->maName);
+
+ // #i40054# create/access members only if flags are not default
+ // (or in manual sorting mode - to keep the order)
+ if (bManualSort || !itr->mbVisible || !itr->mbShowDetails)
+ {
+ pMember->SetIsVisible(itr->mbVisible);
+ pMember->SetShowDetails(itr->mbShowDetails);
+ }
+ if (pOldDim)
{
- // #i40054# create/access members only if flags are not default
- // (or in manual sorting mode - to keep the order)
- bool bIsVisible = (nIdx >= nVisSize) || aIt->maVisible[ nIdx ];
- bool bShowDetails = (nIdx >= nShowSize) || aIt->maShowDet[ nIdx ];
- if( bManualSort || !bIsVisible || !bShowDetails )
+ // Transfer the existing layout name.
+ ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(itr->maName);
+ if (pOldMember)
{
- ScDPSaveMember* pMember = pDim->GetMemberByName( *pItem );
- pMember->SetIsVisible( bIsVisible );
- pMember->SetShowDetails( bShowDetails );
+ const OUString* pLayoutName = pOldMember->GetLayoutName();
+ if (pLayoutName)
+ pMember->SetLayoutName(*pLayoutName);
}
}
}
}
}
+ ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension();
+ if (pDim && pOldSaveData)
+ {
+ ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension();
+ if (pOldDim)
+ {
+ const OUString* pLayoutName = pOldDim->GetLayoutName();
+ if (pLayoutName)
+ pDim->SetLayoutName(*pLayoutName);
+ }
+ }
USHORT nWhichPivot = SC_MOD()->GetPool().GetWhich( SID_PIVOT_TABLE );
ScPivotItem aOutItem( nWhichPivot, &aSaveData, &aOutRange, bToNewTable );
@@ -1720,7 +1756,7 @@ IMPL_LINK( ScDPLayoutDlg, ScrollHdl, ScrollBar *, EMPTYARG )
for ( i=0; i<nFields; i++ )
{
const ScDPLabelData& rData = aLabelDataArr[nOffset+i];
- aWndSelect.AddField( rData.maName, i );
+ aWndSelect.AddField(rData.getDisplayName(), i);
aSelectArr[i].reset( new ScDPFuncData( rData.mnCol, rData.mnFuncMask ) );
}
for ( ; i<aSelectArr.size(); i++ )
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 33caccaed815..4042154b9a52 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -1234,7 +1234,7 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb
aRange.aEnd.Col(), aRange.aEnd.Row(),
nTab, SC_MF_AUTO );
- pDoc->GetDPCollection()->Free( pOldObj ); // object is deleted here
+ pDoc->GetDPCollection()->FreeTable( pOldObj ); // object is deleted here
rDocShell.PostPaintGridAll(); //! only necessary parts
rDocShell.PostPaint( aRange.aStart.Col(), aRange.aStart.Row(), nTab,
@@ -1278,7 +1278,7 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb
pDestObj = new ScDPObject( *pNewObj );
pDestObj->SetAlive(TRUE);
- if ( !pDoc->GetDPCollection()->Insert(pDestObj) )
+ if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) )
{
DBG_ERROR("cannot insert DPObject");
DELETEZ( pDestObj );
diff --git a/sc/source/ui/inc/AccessibleContextBase.hxx b/sc/source/ui/inc/AccessibleContextBase.hxx
index 98f2afc8e88d..4c79c4388e44 100644
--- a/sc/source/ui/inc/AccessibleContextBase.hxx
+++ b/sc/source/ui/inc/AccessibleContextBase.hxx
@@ -319,6 +319,8 @@ protected:
/// Use this method to set initial Description without notification
void SetDescription(const rtl::OUString& rDesc) { msDescription = rDesc; }
+ void SetRole(sal_Int16 nRole);
+
/// Reference to the parent object.
::com::sun::star::uno::Reference<
::com::sun::star::accessibility::XAccessible> mxParent;
diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx
index 82739bfdd274..875576a22889 100644
--- a/sc/source/ui/inc/dbfunc.hxx
+++ b/sc/source/ui/inc/dbfunc.hxx
@@ -80,7 +80,7 @@ public:
void GotoDBArea( const String& rDBName );
// DB-Bereich vom Cursor
- ScDBData* GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE );
+ ScDBData* GetDBData( BOOL bMarkArea = TRUE, ScGetDBMode eMode = SC_DB_MAKE, bool bShrinkToData = false );
void NotifyCloseDbNameDlg( const ScDBCollection& rNewColl, const List& rDelAreaList );
@@ -99,6 +99,7 @@ public:
void UngroupDataPilot();
void DataPilotInput( const ScAddress& rPos, const String& rString );
+ bool DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId = NULL );
BOOL DataPilotMove( const ScRange& rSource, const ScAddress& rDest );
BOOL HasSelectionForDrillDown( USHORT& rOrientation );
diff --git a/sc/source/ui/inc/dpcontrol.hrc b/sc/source/ui/inc/dpcontrol.hrc
new file mode 100644
index 000000000000..2275b601c17a
--- /dev/null
+++ b/sc/source/ui/inc/dpcontrol.hrc
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: protectiondlg.hrc,v $
+ * $Revision: 1.1.2.1 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef __DPCONTROL_HRC__
+#define __DPCONTROL_HRC__
+
+#include <sc.hrc>
+
+#define STR_MENU_SORT_ASC 1
+#define STR_MENU_SORT_DESC 2
+#define STR_MENU_SORT_CUSTOM 3
+#define STR_BTN_TOGGLE_ALL 4
+#define STR_BTN_SELECT_CURRENT 5
+#define STR_BTN_UNSELECT_CURRENT 6
+
+#endif
diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx
new file mode 100644
index 000000000000..1b99f6a38842
--- /dev/null
+++ b/sc/source/ui/inc/dpcontrol.hxx
@@ -0,0 +1,366 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: document.hxx,v $
+ * $Revision: 1.115.36.9 $
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+#ifndef SC_DPCONTROL_HXX
+#define SC_DPCONTROL_HXX
+
+#include "rtl/ustring.hxx"
+#include "tools/gen.hxx"
+#include "tools/fract.hxx"
+#include "vcl/popupmenuwindow.hxx"
+#include "vcl/button.hxx"
+#include "vcl/scrbar.hxx"
+#include "vcl/timer.hxx"
+#include "svx/checklbx.hxx"
+
+#include <boost/shared_ptr.hpp>
+#include <memory>
+#include <hash_map>
+
+namespace com { namespace sun { namespace star {
+
+ namespace accessibility {
+ class XAccessible;
+ }
+
+}}}
+
+class OutputDevice;
+class Point;
+class Size;
+class StyleSettings;
+class Window;
+class ScDocument;
+class ScAccessibleFilterMenu;
+
+/**
+ * This class takes care of physically drawing field button controls inside
+ * data pilot tables.
+ */
+class ScDPFieldButton
+{
+public:
+ ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX = NULL, const Fraction* pZoomY = NULL);
+ ~ScDPFieldButton();
+
+ void setText(const ::rtl::OUString& rText);
+ void setBoundingBox(const Point& rPos, const Size& rSize);
+ void setDrawBaseButton(bool b);
+ void setDrawPopupButton(bool b);
+ void setHasHiddenMember(bool b);
+ void setPopupPressed(bool b);
+ void draw();
+
+ void getPopupBoundingBox(Point& rPos, Size& rSize) const;
+ bool isPopupButton() const;
+
+private:
+ void drawPopupButton();
+
+private:
+ Point maPos;
+ Size maSize;
+ ::rtl::OUString maText;
+ Fraction maZoomX;
+ Fraction maZoomY;
+ OutputDevice* mpOutDev;
+ const StyleSettings* mpStyle;
+ bool mbBaseButton;
+ bool mbPopupButton;
+ bool mbHasHiddenMember;
+ bool mbPopupPressed;
+};
+
+// ============================================================================
+
+class ScMenuFloatingWindow : public PopupMenuFloatingWindow
+{
+public:
+ static size_t MENU_NOT_SELECTED;
+ /**
+ * Action to perform when an event takes place. Create a sub-class of
+ * this to implement the desired action.
+ */
+ class Action
+ {
+ public:
+ virtual void execute() = 0;
+ };
+
+ explicit ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel = 0);
+ virtual ~ScMenuFloatingWindow();
+
+ virtual void MouseMove(const MouseEvent& rMEvt);
+ virtual void MouseButtonDown(const MouseEvent& rMEvt);
+ virtual void MouseButtonUp(const MouseEvent& rMEvt);
+ virtual void KeyInput(const KeyEvent& rKEvt);
+ virtual void Paint(const Rectangle& rRect);
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+ void addMenuItem(const ::rtl::OUString& rText, bool bEnabled, Action* pAction);
+ ScMenuFloatingWindow* addSubMenuItem(const ::rtl::OUString& rText, bool bEnabled);
+ void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu);
+ void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer);
+ void clearSelectedMenuItem();
+ ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const;
+ size_t getMenuItemCount() const;
+ ::rtl::OUString getMenuItemName(size_t nPos) const;
+ bool isMenuItemEnabled(size_t nPos) const;
+ bool isMenuItemSelected(size_t nPos) const;
+ size_t getSelectedMenuItem() const;
+
+ void setName(const ::rtl::OUString& rName);
+ const ::rtl::OUString& getName() const;
+
+ void executeMenuItem(size_t nPos);
+ void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const;
+ ScMenuFloatingWindow* getParentMenuWindow() const;
+
+protected:
+
+ void drawMenuItem(size_t nPos);
+ void drawAllMenuItems();
+ const Font& getLabelFont() const;
+
+ void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu);
+ void queueCloseSubMenu();
+ void launchSubMenu(bool bSetMenuPos);
+ void endSubMenu(ScMenuFloatingWindow* pSubMenu);
+
+ void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const;
+
+ ScDocument* getDoc();
+
+protected:
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::accessibility::XAccessible > mxAccessible;
+
+private:
+ struct SubMenuItemData;
+ void handleMenuTimeout(SubMenuItemData* pTimer);
+
+ void resizeToFitMenuItems();
+ void highlightMenuItem(size_t nPos, bool bSelected);
+
+ size_t getEnclosingMenuItem(const Point& rPos) const;
+ size_t getSubMenuPos(ScMenuFloatingWindow* pSubMenu);
+
+ /**
+ * Fire a menu highlight event since the accessibility framework needs
+ * this to track focus on menu items.
+ */
+ void fireMenuHighlightedEvent();
+
+ /**
+ * Make sure that the specified submenu is permanently up, the submenu
+ * close timer is not active, and the correct menu item associated with
+ * the submenu is highlighted.
+ */
+ void setSubMenuFocused(ScMenuFloatingWindow* pSubMenu);
+
+ /**
+ * When a menu item of an invisible submenu is selected, we need to make
+ * sure that all its parent menu(s) are visible, with the right menu item
+ * highlighted in each of the parents. Calling this method ensures it.
+ */
+ void ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu);
+
+ /**
+ * Dismiss any visible child submenus when a menu item of a parent menu is
+ * selected.
+ */
+ void ensureSubMenuNotVisible();
+
+ /**
+ * Dismiss all visible popup menus and set focus back to the application
+ * window. This method is called e.g. when a menu action is fired.
+ */
+ void terminateAllPopupMenus();
+
+ DECL_LINK( PopupEndHdl, void* );
+
+private:
+
+ struct MenuItemData
+ {
+ ::rtl::OUString maText;
+ bool mbEnabled;
+
+ ::boost::shared_ptr<Action> mpAction;
+ ::boost::shared_ptr<ScMenuFloatingWindow> mpSubMenuWin;
+
+ MenuItemData();
+ };
+
+ ::std::vector<MenuItemData> maMenuItems;
+
+ struct SubMenuItemData
+ {
+ Timer maTimer;
+ ScMenuFloatingWindow* mpSubMenu;
+ size_t mnMenuPos;
+
+ DECL_LINK( TimeoutHdl, void* );
+
+ SubMenuItemData(ScMenuFloatingWindow* pParent);
+ void reset();
+
+ private:
+ ScMenuFloatingWindow* mpParent;
+ };
+ SubMenuItemData maOpenTimer;
+ SubMenuItemData maCloseTimer;
+
+ Font maLabelFont;
+
+ // Name of this menu window, taken from the menu item of the parent window
+ // that launches it (if this is a sub menu). If this is a top-level menu
+ // window, then this name can be anything.
+ ::rtl::OUString maName;
+
+ size_t mnSelectedMenu;
+ size_t mnClickedMenu;
+
+ ScDocument* mpDoc;
+
+ ScMenuFloatingWindow* mpParentMenu;
+ ScMenuFloatingWindow* mpActiveSubMenu;
+};
+
+// ============================================================================
+
+/**
+ * This class implements a popup window for field button, for quick access
+ * of hide-item list, and possibly more stuff related to field options.
+ */
+class ScDPFieldPopupWindow : public ScMenuFloatingWindow
+{
+public:
+ /**
+ * Extended data that the client code may need to store. Create a
+ * sub-class of this and store data there.
+ */
+ struct ExtendedData {};
+
+ explicit ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc);
+ virtual ~ScDPFieldPopupWindow();
+
+ virtual void MouseMove(const MouseEvent& rMEvt);
+ virtual long Notify(NotifyEvent& rNEvt);
+ virtual void Paint(const Rectangle& rRect);
+ virtual Window* GetPreferredKeyInputWindow();
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
+
+ void setMemberSize(size_t n);
+ void addMember(const ::rtl::OUString& rName, bool bVisible);
+ void initMembers();
+
+ const Size& getWindowSize() const;
+
+ void getResult(::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rResult);
+ void close(bool bOK);
+
+ /**
+ * Set auxiliary data that the client code might need. Note that this
+ * popup window class manages its life time; no explicit deletion of the
+ * instance is needed in the client code.
+ */
+ void setExtendedData(ExtendedData* p);
+
+ /**
+ * Get the store auxiliary data, or NULL if no such data is stored.
+ */
+ ExtendedData* getExtendedData();
+
+ void setOKAction(Action* p);
+
+private:
+ struct Member
+ {
+ ::rtl::OUString maName;
+ bool mbVisible;
+
+ Member();
+ };
+
+ class CancelButton : public ::CancelButton
+ {
+ public:
+ CancelButton(ScDPFieldPopupWindow* pParent);
+
+ virtual void Click();
+
+ private:
+ ScDPFieldPopupWindow* mpParent;
+ };
+
+ enum SectionType {
+ WHOLE, // entire window
+ LISTBOX_AREA_OUTER, // box enclosing the check box items.
+ LISTBOX_AREA_INNER, // box enclosing the check box items.
+ SINGLE_BTN_AREA, // box enclosing the single-action buttons.
+ CHECK_TOGGLE_ALL, // check box for toggling all items.
+ BTN_SINGLE_SELECT,
+ BTN_SINGLE_UNSELECT,
+ BTN_OK, // OK button
+ BTN_CANCEL, // Cancel button
+ };
+ void getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const;
+
+ void setAllMemberState(bool bSet);
+ void selectCurrentMemberOnly(bool bSet);
+ void cycleFocus(bool bReverse = false);
+
+ DECL_LINK( ButtonHdl, Button* );
+ DECL_LINK( TriStateHdl, TriStateBox* );
+ DECL_LINK( CheckHdl, SvTreeListBox* );
+
+private:
+ SvxCheckListBox maChecks;
+
+ TriStateBox maChkToggleAll;
+ ImageButton maBtnSelectSingle;
+ ImageButton maBtnUnselectSingle;
+
+ OKButton maBtnOk;
+ CancelButton maBtnCancel;
+
+ ::std::vector<Window*> maTabStopCtrls;
+ size_t mnCurTabStop;
+
+ ::std::vector<Member> maMembers;
+ ::std::auto_ptr<ExtendedData> mpExtendedData;
+ ::std::auto_ptr<Action> mpOKAction;
+
+ const Size maWndSize; /// hard-coded window size.
+ TriState mePrevToggleAllState;
+};
+
+#endif
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index 8b680daad6cb..68f7ece9a249 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -37,15 +37,19 @@
#include "viewdata.hxx"
#include "cbutton.hxx"
#include <svx/sdr/overlay/overlayobject.hxx>
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <vector>
+#include <memory>
// ---------------------------------------------------------------------------
struct ScTableInfo;
class ScViewSelectionEngine;
class ScDPObject;
+class ScDPFieldPopupWindow;
+class ScDPFieldButton;
class ScOutputData;
class ScFilterListBox;
class AutoFilterPopup;
@@ -121,6 +125,8 @@ private:
ScFilterListBox* pFilterBox;
FloatingWindow* pFilterFloat;
+ ::std::auto_ptr<ScDPFieldPopupWindow> mpDPFieldPopup;
+ ::std::auto_ptr<ScDPFieldButton> mpFilterButton;
USHORT nCursorHideCount;
@@ -187,12 +193,23 @@ private:
BOOL TestMouse( const MouseEvent& rMEvt, BOOL bAction );
BOOL DoPageFieldSelection( SCCOL nCol, SCROW nRow );
+ bool DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt );
void DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt );
void DPMouseMove( const MouseEvent& rMEvt );
void DPMouseButtonUp( const MouseEvent& rMEvt );
void DPTestMouse( const MouseEvent& rMEvt, BOOL bMove );
+ /**
+ * Check if the mouse click is on a field popup button.
+ *
+ * @return bool true if the field popup menu has been launched and no
+ * further mouse event handling is necessary, false otherwise.
+ */
+ bool DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj);
+ void DPLaunchFieldPopupMenu(
+ const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj);
+
void RFMouseMove( const MouseEvent& rMEvt, BOOL bUp );
void PagebreakMove( const MouseEvent& rMEvt, BOOL bUp );
@@ -315,9 +332,11 @@ public:
void DoAutoFilterMenue( SCCOL nCol, SCROW nRow, BOOL bDataSelect );
void DoScenarioMenue( const ScRange& rScenRange );
- void DoPageFieldMenue( SCCOL nCol, SCROW nRow );
- BOOL HasPageFieldData( SCCOL nCol, SCROW nRow ) const;
+ void LaunchPageFieldMenu( SCCOL nCol, SCROW nRow );
+ void LaunchDPFieldMenu( SCCOL nCol, SCROW nRow );
+
+ ::com::sun::star::sheet::DataPilotFieldOrientation GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const;
void DrawButtons( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
ScTableInfo& rTabInfo, OutputDevice* pContentDev );
@@ -357,6 +376,8 @@ public:
void CheckNeedsRepaint();
+ void UpdateDPFromFieldPopupMenu();
+
// #114409#
void CursorChanged();
void DrawLayerCreated();
diff --git a/sc/source/ui/inc/pvfundlg.hxx b/sc/source/ui/inc/pvfundlg.hxx
index eeeb9c4094c4..6b9aa62c37a3 100644
--- a/sc/source/ui/inc/pvfundlg.hxx
+++ b/sc/source/ui/inc/pvfundlg.hxx
@@ -55,6 +55,8 @@
#include <sfx2/itemconnect.hxx>
#include "pivot.hxx"
+#include <hash_map>
+
// ============================================================================
typedef sfx::ListBoxWrapper< sal_Int32 > ScDPListBoxWrapper;
@@ -217,6 +219,11 @@ public:
virtual short Execute();
+ /**
+ * @return String internal name of the selected field. Note that this may
+ * be different from the name displayed in the dialog if the field
+ * has a layout name.
+ */
String GetDimensionName() const;
private:
@@ -228,6 +235,10 @@ private:
OKButton maBtnOk;
CancelButton maBtnCancel;
HelpButton maBtnHelp;
+
+ typedef ::std::hash_map<String, long, ScStringHashCode> DimNameIndexMap;
+ DimNameIndexMap maNameIndexMap;
+ ScDPObject& mrDPObj;
};
// ============================================================================
diff --git a/sc/source/ui/inc/pvlaydlg.hxx b/sc/source/ui/inc/pvlaydlg.hxx
index b7a71aebc1fe..c77364d3761f 100644
--- a/sc/source/ui/inc/pvlaydlg.hxx
+++ b/sc/source/ui/inc/pvlaydlg.hxx
@@ -193,7 +193,7 @@ private:
private:
ScDPFieldWindow& GetFieldWindow ( ScDPFieldType eType );
void Init ();
- void InitWndSelect ( LabelData** ppLabelArr, long nLabels );
+ void InitWndSelect ( const ::std::vector<ScDPLabelDataRef>& rLabels );
void InitWnd ( PivotField* pArr, long nCount, ScDPFieldType eType );
void InitFocus ();
void InitFields ();
diff --git a/sc/source/ui/undo/undodat.cxx b/sc/source/ui/undo/undodat.cxx
index 7ab321ac0c1d..5c929ec7a11b 100644
--- a/sc/source/ui/undo/undodat.cxx
+++ b/sc/source/ui/undo/undodat.cxx
@@ -1876,7 +1876,7 @@ void __EXPORT ScUndoDataPilot::Undo()
else
{
// delete inserted object
- pDoc->GetDPCollection()->Free(pDocObj);
+ pDoc->GetDPCollection()->FreeTable(pDocObj);
}
}
}
@@ -1886,7 +1886,7 @@ void __EXPORT ScUndoDataPilot::Undo()
ScDPObject* pDestObj = new ScDPObject( *pOldDPObject );
pDestObj->SetAlive(TRUE);
- if ( !pDoc->GetDPCollection()->Insert(pDestObj) )
+ if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) )
{
DBG_ERROR("cannot insert DPObject");
DELETEZ( pDestObj );
diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx
index ed40d2f5c96a..a7836b43f740 100644
--- a/sc/source/ui/unoobj/dapiuno.cxx
+++ b/sc/source/ui/unoobj/dapiuno.cxx
@@ -1626,8 +1626,13 @@ OUString SAL_CALL ScDataPilotFieldObj::getName() throw(RuntimeException)
if( pDim->IsDataLayout() )
aName = OUString( RTL_CONSTASCII_USTRINGPARAM( SC_DATALAYOUT_NAME ) );
else
- aName = pDim->GetLayoutName();
- }
+ {
+ const rtl::OUString* pLayoutName = pDim->GetLayoutName();
+ if (pLayoutName)
+ aName = *pLayoutName;
+ else
+ aName = pDim->GetName();
+ } }
return aName;
}
@@ -1639,7 +1644,7 @@ void SAL_CALL ScDataPilotFieldObj::setName( const OUString& rName ) throw(Runtim
if( pDim && !pDim->IsDataLayout() )
{
String aName( rName );
- pDim->SetLayoutName( &aName );
+ pDim->SetLayoutName(aName);
SetDPObject( pDPObj );
}
}
@@ -3069,7 +3074,7 @@ Sequence<OUString> SAL_CALL ScDataPilotItemsObj::getElementNames()
ScUnoGuard aGuard;
Sequence< OUString > aSeq;
if( ScDPObject* pDPObj = GetDPObject() )
- pDPObj->GetMembers( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
+ pDPObj->GetMemberNames( lcl_GetObjectIndex( pDPObj, maFieldId ), aSeq );
return aSeq;
}
diff --git a/sc/source/ui/unoobj/miscuno.cxx b/sc/source/ui/unoobj/miscuno.cxx
index 3d41da907016..ee2a64bd8c78 100644
--- a/sc/source/ui/unoobj/miscuno.cxx
+++ b/sc/source/ui/unoobj/miscuno.cxx
@@ -39,6 +39,9 @@
#include "unoguard.hxx"
using namespace com::sun::star;
+using ::com::sun::star::uno::Reference;
+using ::com::sun::star::uno::Any;
+using ::rtl::OUString;
//------------------------------------------------------------------------
@@ -137,6 +140,26 @@ sal_Int32 ScUnoHelpFunctions::GetEnumProperty( const uno::Reference<beans::XProp
return nRet;
}
+// static
+OUString ScUnoHelpFunctions::GetStringProperty(
+ const Reference<beans::XPropertySet>& xProp, const OUString& rName, const OUString& rDefault )
+{
+ OUString aRet = rDefault;
+ if (!xProp.is())
+ return aRet;
+
+ try
+ {
+ Any any = xProp->getPropertyValue(rName);
+ any >>= aRet;
+ }
+ catch (const uno::Exception&)
+ {
+ }
+
+ return aRet;
+}
+
// static
sal_Bool ScUnoHelpFunctions::GetBoolFromAny( const uno::Any& aAny )
{
@@ -180,6 +203,20 @@ void ScUnoHelpFunctions::SetBoolInAny( uno::Any& rAny, sal_Bool bValue )
rAny.setValue( &bValue, getBooleanCppuType() );
}
+// static
+void ScUnoHelpFunctions::SetOptionalPropertyValue(
+ Reference<beans::XPropertySet>& rPropSet, const sal_Char* pPropName, const Any& rVal )
+{
+ try
+ {
+ rPropSet->setPropertyValue(OUString::createFromAscii(pPropName), rVal);
+ }
+ catch (const beans::UnknownPropertyException&)
+ {
+ // ignored - not supported.
+ }
+}
+
//------------------------------------------------------------------------
ScIndexEnumeration::ScIndexEnumeration(const uno::Reference<container::XIndexAccess>& rInd,
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index cf64a07a2d95..47c55350f278 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -762,7 +762,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
{
// select database range or data
pTabViewShell->GetDBData( TRUE, SC_DB_OLD );
- const ScMarkData& rMark = GetViewData()->GetMarkData();
+ ScMarkData& rMark = GetViewData()->GetMarkData();
if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
pTabViewShell->MarkDataArea( FALSE );
@@ -828,6 +828,19 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
ScMarkType eType = GetViewData()->GetSimpleArea(aRange);
if ( (eType & SC_MARK_SIMPLE) == SC_MARK_SIMPLE )
{
+ // Shrink the range to the data area.
+ SCCOL nStartCol = aRange.aStart.Col(), nEndCol = aRange.aEnd.Col();
+ SCROW nStartRow = aRange.aStart.Row(), nEndRow = aRange.aEnd.Row();
+ if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nStartCol, nStartRow, nEndCol, nEndRow))
+ {
+ aRange.aStart.SetCol(nStartCol);
+ aRange.aStart.SetRow(nStartRow);
+ aRange.aEnd.SetCol(nEndCol);
+ aRange.aEnd.SetRow(nEndRow);
+ rMark.SetMarkArea(aRange);
+ pTabViewShell->MarkRange(aRange);
+ }
+
BOOL bOK = TRUE;
if ( pDoc->HasSubTotalCells( aRange ) )
{
diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx
index 0d44603b64f8..48b6d3ba11f7 100644
--- a/sc/source/ui/view/dbfunc.cxx
+++ b/sc/source/ui/view/dbfunc.cxx
@@ -107,14 +107,30 @@ void ScDBFunc::GotoDBArea( const String& rDBName )
// aktuellen Datenbereich fuer Sortieren / Filtern suchen
-ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode )
+ScDBData* ScDBFunc::GetDBData( BOOL bMark, ScGetDBMode eMode, bool bShrinkToData )
{
ScDocShell* pDocSh = GetViewData()->GetDocShell();
ScDBData* pData = NULL;
ScRange aRange;
ScMarkType eMarkType = GetViewData()->GetSimpleArea(aRange);
if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED )
+ {
+ if (bShrinkToData)
+ {
+ // Shrink the range to only include data area.
+ ScDocument* pDoc = pDocSh->GetDocument();
+ SCCOL nCol1 = aRange.aStart.Col(), nCol2 = aRange.aEnd.Col();
+ SCROW nRow1 = aRange.aStart.Row(), nRow2 = aRange.aEnd.Row();
+ if (pDoc->ShrinkToDataArea(aRange.aStart.Tab(), nCol1, nRow1, nCol2, nRow2))
+ {
+ aRange.aStart.SetCol(nCol1);
+ aRange.aEnd.SetCol(nCol2);
+ aRange.aStart.SetRow(nRow1);
+ aRange.aEnd.SetRow(nRow2);
+ }
+ }
pData = pDocSh->GetDBData( aRange, eMode, FALSE );
+ }
else if ( eMode != SC_DB_OLD )
pData = pDocSh->GetDBData(
ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(),
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index 5fd4a5f470f5..41a959409727 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -44,19 +44,17 @@
#include <vcl/waitobj.hxx>
#include <svl/zforlist.hxx>
#include <sfx2/app.hxx>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
+#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
-#include <com/sun/star/sheet/MemberResultFlags.hpp>
-
-#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp>
+#include <com/sun/star/sheet/GeneralFunction.hpp>
#include <com/sun/star/sheet/MemberResultFlags.hpp>
-#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
-#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
-#include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
#include <com/sun/star/sheet/XDimensionsSupplier.hpp>
-#include <com/sun/star/beans/XPropertySet.hpp>
-#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/sheet/XDrillDownDataSupplier.hpp>
#include "global.hxx"
#include "globstr.hrc"
@@ -81,9 +79,13 @@
#include "patattr.hxx"
#include "unonames.hxx"
#include "cell.hxx"
+#include "userlist.hxx"
#include <hash_set>
+#include <hash_map>
#include <memory>
+#include <list>
+#include <vector>
using namespace com::sun::star;
using ::com::sun::star::uno::Any;
@@ -91,7 +93,16 @@ using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::beans::XPropertySet;
+using ::com::sun::star::container::XNameAccess;
+using ::com::sun::star::sheet::XDimensionsSupplier;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
+using ::rtl::OUStringBuffer;
using ::std::auto_ptr;
+using ::std::list;
+using ::std::vector;
+using ::std::hash_map;
+using ::std::hash_set;
// STATIC DATA -----------------------------------------------------------
@@ -1351,123 +1362,323 @@ void ScDBFunc::UngroupDataPilot()
}
}
+static OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName)
+{
+ sal_Int32 n = rSubtotal.getLength();
+ const sal_Unicode* p = rSubtotal.getStr();
+ OUStringBuffer aBuf, aWordBuf;
+ for (sal_Int32 i = 0; i < n; ++i)
+ {
+ sal_Unicode c = p[i];
+ if (c == sal_Unicode(' '))
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ aBuf.append(c);
+ }
+ else if (c == sal_Unicode('\\'))
+ {
+ // Escape a backslash character.
+ aWordBuf.append(c);
+ aWordBuf.append(c);
+ }
+ else if (c == sal_Unicode('?'))
+ {
+ // A literal '?' must be escaped with a backslash ('\');
+ aWordBuf.append(sal_Unicode('\\'));
+ aWordBuf.append(c);
+ }
+ else
+ aWordBuf.append(c);
+ }
+
+ if (aWordBuf.getLength() > 0)
+ {
+ OUString aWord = aWordBuf.makeStringAndClear();
+ if (aWord.equals(rMemberName))
+ aBuf.append(sal_Unicode('?'));
+ else
+ aBuf.append(aWord);
+ }
+
+ return aBuf.makeStringAndClear();
+}
+
void ScDBFunc::DataPilotInput( const ScAddress& rPos, const String& rString )
{
+ using namespace ::com::sun::star::sheet;
+
String aNewName( rString );
ScDocument* pDoc = GetViewData()->GetDocument();
ScDPObject* pDPObj = pDoc->GetDPAtCursor( rPos.Col(), rPos.Row(), rPos.Tab() );
- if ( pDPObj )
+ if (!pDPObj)
+ return;
+
+ String aOldText;
+ pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
+
+ if ( aOldText == rString )
{
- String aOldText;
- pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText );
+ // nothing to do: silently exit
+ return;
+ }
+
+ USHORT nErrorId = 0;
+
+ pDPObj->BuildAllDimensionMembers();
+ ScDPSaveData aData( *pDPObj->GetSaveData() );
+ BOOL bChange = FALSE;
- if ( aOldText == rString )
+ USHORT nOrient = DataPilotFieldOrientation_HIDDEN;
+ long nField = pDPObj->GetHeaderDim( rPos, nOrient );
+ if ( nField >= 0 )
+ {
+ // changing a field title
+ if ( aData.GetExistingDimensionData() )
{
- // nothing to do: silently exit
- return;
- }
+ // only group dimensions can be renamed
- USHORT nErrorId = 0;
+ ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
+ if ( pGroupDim )
+ {
+ // valid name: not empty, no existing dimension (group or other)
+ if ( rString.Len() && !pDPObj->IsDimNameInUse(rString) )
+ {
+ pGroupDim->Rename( aNewName );
- ScDPSaveData aData( *pDPObj->GetSaveData() );
- BOOL bChange = FALSE;
+ // also rename in SaveData to preserve the field settings
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
+ pSaveDim->SetName( aNewName );
- USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
- long nField = pDPObj->GetHeaderDim( rPos, nOrient );
- if ( nField >= 0 )
+ bChange = TRUE;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else if (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW)
+ {
+ BOOL bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(nField, bDataLayout);
+ ScDPSaveDimension* pDim = bDataLayout ? aData.GetDataLayoutDimension() : aData.GetDimensionByName(aDimName);
+ if (pDim)
+ {
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(aDimName))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ }
+ else if (pDPObj->IsDataDescriptionCell(rPos))
+ {
+ // There is only one data dimension.
+ ScDPSaveDimension* pDim = aData.GetFirstDimension(sheet::DataPilotFieldOrientation_DATA);
+ if (pDim)
{
- // changing a field title
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pDim->GetName()))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ }
+ else
+ {
+ // This is not a field header.
+ sheet::DataPilotTableHeaderData aPosData;
+ pDPObj->GetHeaderPositionData(rPos, aPosData);
- if ( aData.GetExistingDimensionData() )
+ if ( (aPosData.Flags & MemberResultFlags::HASMEMBER) && aOldText.Len() )
+ {
+ if ( aData.GetExistingDimensionData() && !(aPosData.Flags & MemberResultFlags::SUBTOTAL))
{
- // only group dimensions can be renamed
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
- ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText );
+ ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
if ( pGroupDim )
{
- // valid name: not empty, no existing dimension (group or other)
- if ( aNewName.Len() && !pDPObj->IsDimNameInUse( aNewName ) )
+ // valid name: not empty, no existing group in this dimension
+ //! ignore case?
+ if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
{
- pGroupDim->Rename( aNewName );
+ ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
+ if ( pGroup )
+ pGroup->Rename( aNewName ); // rename the existing group
+ else
+ {
+ // create a new group to replace the automatic group
+ ScDPSaveGroupItem aGroup( aNewName );
+ aGroup.AddElement( aOldText );
+ pGroupDim->AddGroupItem( aGroup );
+ }
- // also rename in SaveData to preserve the field settings
- ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText );
- pSaveDim->SetName( aNewName );
+ // in both cases also adjust savedata, to preserve member settings (show details)
+ ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
+ ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
+ if ( pSaveMember )
+ pSaveMember->SetName( aNewName );
bChange = TRUE;
}
else
nErrorId = STR_INVALIDNAME;
- }
+ }
}
- }
- else
- {
- // renaming a group (item)?
- // allow only on the item name itself - not on empty cells, not on subtotals
-
- sheet::DataPilotTableHeaderData aPosData;
- pDPObj->GetHeaderPositionData(rPos, aPosData);
- if ( ( aPosData.Flags & sheet::MemberResultFlags::HASMEMBER ) &&
- ! ( aPosData.Flags & sheet::MemberResultFlags::SUBTOTAL ) &&
- aOldText.Len() )
+ else if ((aPosData.Flags & MemberResultFlags::GRANDTOTAL))
{
- if ( aData.GetExistingDimensionData() )
+ aData.SetGrandTotalName(rString);
+ bChange = true;
+ }
+ else if (aPosData.Dimension >= 0 && aPosData.MemberName.getLength() > 0)
+ {
+ BOOL bDataLayout = false;
+ String aDimName = pDPObj->GetDimName(static_cast<long>(aPosData.Dimension), bDataLayout);
+ if (bDataLayout)
{
- BOOL bIsDataLayout;
- String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout );
+ // data dimension
+ do
+ {
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
+ break;
+
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aPosData.MemberName);
+ if (!pDim)
+ break;
+
+ if (!rString.Len())
+ {
+ nErrorId = STR_INVALIDNAME;
+ break;
+ }
- ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
- ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
- if ( pGroupDim )
+ if (aPosData.MemberName.equalsIgnoreAsciiCase(rString))
+ {
+ pDim->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDPObj->IsDimNameInUse(rString))
+ {
+ pDim->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ while (false);
+ }
+ else
+ {
+ // field member
+ do
{
- // valid name: not empty, no existing group in this dimension
- //! ignore case?
- if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) )
+ ScDPSaveDimension* pDim = aData.GetDimensionByName(aDimName);
+ if (!pDim)
+ break;
+
+ ScDPSaveMember* pMem = pDim->GetExistingMemberByName(aPosData.MemberName);
+ if (!pMem)
+ break;
+
+ if ((aPosData.Flags & MemberResultFlags::SUBTOTAL))
{
- ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText );
- if ( pGroup )
- pGroup->Rename( aNewName ); // rename the existing group
- else
- {
- // create a new group to replace the automatic group
- ScDPSaveGroupItem aGroup( aNewName );
- aGroup.AddElement( aOldText );
- pGroupDim->AddGroupItem( aGroup );
- }
+ // Change subtotal only when the table has one data dimension.
+ if (aData.GetDataDimensionCount() > 1)
+ break;
+
+ // display name for subtotal is allowed only if the subtotal type is 'Automatic'.
+ if (pDim->GetSubTotalsCount() != 1)
+ break;
- // in both cases also adjust savedata, to preserve member settings (show details)
- ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName );
- ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText );
- if ( pSaveMember )
- pSaveMember->SetName( aNewName );
+ if (pDim->GetSubTotalFunc(0) != sheet::GeneralFunction_AUTO)
+ break;
- bChange = TRUE;
+ const OUString* pLayoutName = pMem->GetLayoutName();
+ String aMemberName;
+ if (pLayoutName)
+ aMemberName = *pLayoutName;
+ else
+ aMemberName = aPosData.MemberName;
+
+ String aNew = lcl_replaceMemberNameInSubtotal(rString, aMemberName);
+ pDim->SetSubtotalName(aNew);
+ bChange = true;
}
else
- nErrorId = STR_INVALIDNAME;
+ {
+ // Check to make sure the member name isn't
+ // already used.
+ if (rString.Len())
+ {
+ if (rString.EqualsIgnoreCaseAscii(pMem->GetName()))
+ {
+ pMem->RemoveLayoutName();
+ bChange = true;
+ }
+ else if (!pDim->IsMemberNameInUse(rString))
+ {
+ pMem->SetLayoutName(rString);
+ bChange = true;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
+ else
+ nErrorId = STR_INVALIDNAME;
+ }
}
+ while (false);
}
}
}
+ }
- if ( bChange )
- {
- // apply changes
- ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
- ScDPObject* pNewObj = new ScDPObject( *pDPObj );
- pNewObj->SetSaveData( aData );
- aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
- delete pNewObj;
- }
- else
- {
- if ( !nErrorId )
- nErrorId = STR_ERR_DATAPILOT_INPUT;
- ErrorMessage( nErrorId );
- }
+ if ( bChange )
+ {
+ // apply changes
+ ScDBDocFunc aFunc( *GetViewData()->GetDocShell() );
+ ScDPObject* pNewObj = new ScDPObject( *pDPObj );
+ pNewObj->SetSaveData( aData );
+ aFunc.DataPilotUpdate( pDPObj, pNewObj, TRUE, FALSE );
+ delete pNewObj;
+ }
+ else
+ {
+ if ( !nErrorId )
+ nErrorId = STR_ERR_DATAPILOT_INPUT;
+ ErrorMessage( nErrorId );
}
}
@@ -1484,6 +1695,134 @@ void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName )
// puts it to the end of the list even if it was in the list before.
}
+bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId )
+{
+ ScDocument* pDoc = GetViewData()->GetDocument();
+ ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab());
+ if (!pDPObj)
+ return false;
+
+ // We need to run this to get all members later.
+ pDPObj->BuildAllDimensionMembers();
+
+ USHORT nOrientation;
+ long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation);
+ if (nDimIndex < 0)
+ // Invalid dimension index. Bail out.
+ return false;
+
+ BOOL bDataLayout;
+ ScDPSaveData* pSaveData = pDPObj->GetSaveData();
+ if (!pSaveData)
+ return false;
+
+ ScDPSaveData aNewSaveData(*pSaveData);
+ String aDimName = pDPObj->GetDimName(nDimIndex, bDataLayout);
+ ScDPSaveDimension* pSaveDim = aNewSaveData.GetDimensionByName(aDimName);
+ if (!pSaveDim)
+ return false;
+
+ typedef ScDPSaveDimension::MemberList MemList;
+ const MemList& rDimMembers = pSaveDim->GetMembers();
+ list<OUString> aMembers;
+ hash_set<OUString, ::rtl::OUStringHash> aMemberSet;
+ size_t nMemberCount = 0;
+ for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end();
+ itr != itrEnd; ++itr)
+ {
+ ScDPSaveMember* pMem = *itr;
+ aMembers.push_back(pMem->GetName());
+ aMemberSet.insert(pMem->GetName());
+ ++nMemberCount;
+ }
+
+ // Sort the member list in ascending order.
+ aMembers.sort();
+
+ // Collect and rank those custom sort strings that also exist in the member name list.
+
+ typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap;
+ UserSortMap aSubStrs;
+ sal_uInt16 nSubCount = 0;
+ if (pUserListId)
+ {
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ if (!pUserList)
+ return false;
+
+ {
+ sal_uInt16 n = pUserList->GetCount();
+ if (!n || *pUserListId >= n)
+ return false;
+ }
+
+ ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]);
+ if (pData)
+ {
+ sal_uInt16 n = pData->GetSubCount();
+ for (sal_uInt16 i = 0; i < n; ++i)
+ {
+ OUString aSub = pData->GetSubStr(i);
+ if (!aMemberSet.count(aSub))
+ // This string doesn't exist in the member name set. Don't add this.
+ continue;
+
+ aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++));
+ }
+ }
+ }
+
+ // Rank all members.
+
+ vector<OUString> aRankedNames(nMemberCount);
+ sal_uInt16 nCurStrId = 0;
+ for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end();
+ itr != itrEnd; ++itr)
+ {
+ OUString aName = *itr;
+ sal_uInt16 nRank = 0;
+ UserSortMap::const_iterator itrSub = aSubStrs.find(aName);
+ if (itrSub == aSubStrs.end())
+ nRank = nSubCount + nCurStrId++;
+ else
+ nRank = itrSub->second;
+
+ if (!bAscending)
+ nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 );
+
+ aRankedNames[nRank] = aName;
+ }
+
+ // Re-order ScDPSaveMember instances with the new ranks.
+
+ for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end();
+ itr != itrEnd; ++itr)
+ {
+ const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr);
+ if (!pOldMem)
+ // All members are supposed to be present.
+ continue;
+
+ ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem);
+ pSaveDim->AddMember(pNewMem);
+ }
+
+ // Set the sorting mode to manual for now. We may introduce a new sorting
+ // mode later on.
+
+ sheet::DataPilotFieldSortInfo aSortInfo;
+ aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL;
+ pSaveDim->SetSortInfo(&aSortInfo);
+
+ // Update the datapilot with the newly sorted field members.
+
+ auto_ptr<ScDPObject> pNewObj(new ScDPObject(*pDPObj));
+ pNewObj->SetSaveData(aNewSaveData);
+ ScDBDocFunc aFunc(*GetViewData()->GetDocShell());
+
+ return aFunc.DataPilotUpdate(pDPObj, pNewObj.get(), true, false);
+}
+
BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
{
BOOL bRet = FALSE;
@@ -1529,7 +1868,7 @@ BOOL ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest )
// get all member names in source order
uno::Sequence<rtl::OUString> aMemberNames;
- pDPObj->GetMembers( aDestData.Dimension, aMemberNames );
+ pDPObj->GetMemberNames( aDestData.Dimension, aMemberNames );
bool bInserted = false;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index aca88c554317..7f78461aedb0 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -121,6 +121,7 @@
#include "validat.hxx"
#include "tabprotection.hxx"
#include "postit.hxx"
+#include "dpcontrol.hxx"
#include "drawview.hxx"
#include <svx/sdrpagewindow.hxx>
@@ -369,6 +370,8 @@ ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhic
pNoteMarker( NULL ),
pFilterBox( NULL ),
pFilterFloat( NULL ),
+ mpDPFieldPopup(NULL),
+ mpFilterButton(NULL),
nCursorHideCount( 0 ),
bMarking( FALSE ),
nButtonDown( 0 ),
@@ -445,14 +448,26 @@ void __EXPORT ScGridWindow::Resize( const Size& )
void ScGridWindow::ClickExtern()
{
- // #i81298# don't delete the filter box when called from its select handler
- // (possible through row header size update)
- // #i84277# when initializing the filter box, a Basic error can deactivate the view
- if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
- return;
+ do
+ {
+ // #i81298# don't delete the filter box when called from its select handler
+ // (possible through row header size update)
+ // #i84277# when initializing the filter box, a Basic error can deactivate the view
+ if ( pFilterBox && ( pFilterBox->IsInSelect() || pFilterBox->IsInInit() ) )
+ {
+ break;
+ }
- DELETEZ(pFilterBox);
- DELETEZ(pFilterFloat);
+ DELETEZ(pFilterBox);
+ DELETEZ(pFilterFloat);
+ }
+ while (false);
+
+ if (mpDPFieldPopup.get())
+ {
+ mpDPFieldPopup->close(false);
+ mpDPFieldPopup.reset();
+ }
}
IMPL_LINK( ScGridWindow, PopupModeEndHdl, FloatingWindow*, EMPTYARG )
@@ -507,7 +522,7 @@ void ScGridWindow::ExecPageFieldSelect( SCCOL nCol, SCROW nRow, BOOL bHasSelecti
}
}
-void ScGridWindow::DoPageFieldMenue( SCCOL nCol, SCROW nRow )
+void ScGridWindow::LaunchPageFieldMenu( SCCOL nCol, SCROW nRow )
{
//! merge position/size handling with DoAutoFilterMenue
@@ -658,6 +673,22 @@ void ScGridWindow::DoPageFieldMenue( SCCOL nCol, SCROW nRow )
CaptureMouse();
}
+void ScGridWindow::LaunchDPFieldMenu( SCCOL nCol, SCROW nRow )
+{
+ SCTAB nTab = pViewData->GetTabNo();
+ ScDPObject* pDPObj = pViewData->GetDocument()->GetDPAtCursor(nCol, nRow, nTab);
+ if (!pDPObj)
+ return;
+
+ // Get the geometry of the cell.
+ Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel(nCol, nRow, nSizeX, nSizeY);
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, ScAddress(nCol, nRow, nTab), pDPObj);
+}
+
void ScGridWindow::DoScenarioMenue( const ScRange& rScenRange )
{
delete pFilterBox;
@@ -1619,52 +1650,8 @@ void ScGridWindow::HandleMouseButtonDown( const MouseEvent& rMEvt )
pDoc->GetAttr( nPosX, nPosY, nTab, ATTR_MERGE_FLAG );
if (pAttr->HasAutoFilter())
{
- Point aScrPos = pViewData->GetScrPos(nPosX,nPosY,eWhich);
- long nSizeX;
- long nSizeY;
- Point aDiffPix = aPos;
-
- aDiffPix -= aScrPos;
- BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
- if ( bLayoutRTL )
- aDiffPix.X() = -aDiffPix.X();
-
- pViewData->GetMergeSizePixel( nPosX, nPosY, nSizeX, nSizeY );
-
- // Breite des Buttons ist nicht von der Zellhoehe abhaengig
- Size aButSize = aComboButton.GetSizePixel();
- long nButWidth = Min( aButSize.Width(), nSizeX );
- long nButHeight = Min( aButSize.Height(), nSizeY );
-
- if ( aDiffPix.X() >= nSizeX - nButWidth &&
- aDiffPix.Y() >= nSizeY - nButHeight )
- {
- if ( DoPageFieldSelection( nPosX, nPosY ) )
- return;
-
- BOOL bFilterActive = IsAutoFilterActive( nPosX, nPosY,
- pViewData->GetTabNo() );
-
- aComboButton.SetOptSizePixel();
- DrawComboButton( aScrPos, nSizeX, nSizeY, bFilterActive, TRUE );
-
-#if 0
- if ( bWasFilterBox
- && (SCsCOL)nOldColFBox == nPosX
- && (SCsROW)nOldRowFBox == nPosY )
- {
- // Verhindern, dass an gleicher Stelle eine
- // FilterBox geoeffnet wird, wenn diese gerade
- // geloescht wurde
-
- nMouseStatus = SC_GM_FILTER; // fuer ButtonDraw im MouseButtonUp();
- return;
- }
-#endif
- DoAutoFilterMenue( nPosX, nPosY, FALSE );
-
+ if (DoAutoFilterButton(nPosX, nPosY, rMEvt))
return;
- }
}
if (pAttr->HasButton())
{
@@ -1794,11 +1781,17 @@ void __EXPORT ScGridWindow::MouseButtonUp( const MouseEvent& rMEvt )
{
if ( pFilterBox && pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
{
- BOOL bFilterActive = IsAutoFilterActive( pFilterBox->GetCol(), pFilterBox->GetRow(),
- pViewData->GetTabNo() );
- HideCursor();
- aComboButton.Draw( bFilterActive );
- ShowCursor();
+ if (mpFilterButton.get())
+ {
+ bool bFilterActive = IsAutoFilterActive(
+ pFilterBox->GetCol(), pFilterBox->GetRow(), pViewData->GetTabNo() );
+
+ mpFilterButton->setHasHiddenMember(bFilterActive);
+ mpFilterButton->setPopupPressed(false);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ }
}
nMouseStatus = SC_GM_NONE;
ReleaseMouse();
@@ -2218,9 +2211,14 @@ void __EXPORT ScGridWindow::MouseMove( const MouseEvent& rMEvt )
nMouseStatus = SC_GM_NONE;
if ( pFilterBox->GetMode() == SC_FILTERBOX_FILTER )
{
- HideCursor();
- aComboButton.Draw( FALSE );
- ShowCursor();
+ if (mpFilterButton.get())
+ {
+ mpFilterButton->setHasHiddenMember(false);
+ mpFilterButton->setPopupPressed(false);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ }
}
ReleaseMouse();
pFilterBox->MouseButtonDown( MouseEvent( aRelPos, 1, MOUSE_SIMPLECLICK, MOUSE_LEFT ) );
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
index 643928a7c8aa..e0dd63ff090e 100644
--- a/sc/source/ui/view/gridwin2.cxx
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -55,48 +55,124 @@
#include "dpoutput.hxx" // ScDPPositionData
#include "dpshttab.hxx"
#include "dbdocfun.hxx"
+#include "dpcontrol.hxx"
+#include "dpcontrol.hrc"
+#include "strload.hxx"
+#include "userlist.hxx"
#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
#include "scabstdlg.hxx" //CHINA001
-using namespace com::sun::star;
+#include <vector>
+#include <hash_map>
+
+using namespace com::sun::star;
+using ::com::sun::star::sheet::DataPilotFieldOrientation;
+using ::std::vector;
+using ::std::auto_ptr;
+using ::std::hash_map;
+using ::rtl::OUString;
+using ::rtl::OUStringHash;
// STATIC DATA -----------------------------------------------------------
// -----------------------------------------------------------------------
-BOOL ScGridWindow::HasPageFieldData( SCCOL nCol, SCROW nRow ) const
+DataPilotFieldOrientation ScGridWindow::GetDPFieldOrientation( SCCOL nCol, SCROW nRow ) const
{
+ using namespace ::com::sun::star::sheet;
+
ScDocument* pDoc = pViewData->GetDocument();
SCTAB nTab = pViewData->GetTabNo();
ScDPObject* pDPObj = pDoc->GetDPAtCursor(nCol, nRow, nTab);
- if ( pDPObj && nCol > 0 )
+ if (!pDPObj)
+ return DataPilotFieldOrientation_HIDDEN;
+
+ USHORT nOrient = DataPilotFieldOrientation_HIDDEN;
+
+ // Check for page field first.
+ if (nCol > 0)
{
// look for the dimension header left of the drop-down arrow
- USHORT nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
long nField = pDPObj->GetHeaderDim( ScAddress( nCol-1, nRow, nTab ), nOrient );
- if ( nField >= 0 && nOrient == sheet::DataPilotFieldOrientation_PAGE )
+ if ( nField >= 0 && nOrient == DataPilotFieldOrientation_PAGE )
{
BOOL bIsDataLayout = FALSE;
String aFieldName = pDPObj->GetDimName( nField, bIsDataLayout );
if ( aFieldName.Len() && !bIsDataLayout )
- return TRUE;
+ return DataPilotFieldOrientation_PAGE;
}
}
- return FALSE;
+
+ nOrient = sheet::DataPilotFieldOrientation_HIDDEN;
+
+ // Now, check for row/column field.
+ long nField = pDPObj->GetHeaderDim(ScAddress(nCol, nRow, nTab), nOrient);
+ if (nField >= 0 && (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) )
+ {
+ BOOL bIsDataLayout = FALSE;
+ String aFieldName = pDPObj->GetDimName(nField, bIsDataLayout);
+ if (aFieldName.Len() && !bIsDataLayout)
+ return static_cast<DataPilotFieldOrientation>(nOrient);
+ }
+
+ return DataPilotFieldOrientation_HIDDEN;
}
// private method for mouse button handling
BOOL ScGridWindow::DoPageFieldSelection( SCCOL nCol, SCROW nRow )
{
- if ( HasPageFieldData( nCol, nRow ) )
+ if (GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE)
{
- DoPageFieldMenue( nCol, nRow );
+ LaunchPageFieldMenu( nCol, nRow );
return TRUE;
}
return FALSE;
}
+bool ScGridWindow::DoAutoFilterButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
+{
+ ScDocument* pDoc = pViewData->GetDocument();
+ SCTAB nTab = pViewData->GetTabNo();
+ Point aScrPos = pViewData->GetScrPos(nCol, nRow, eWhich);
+ Point aDiffPix = rMEvt.GetPosPixel();
+
+ aDiffPix -= aScrPos;
+ BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab );
+ if ( bLayoutRTL )
+ aDiffPix.X() = -aDiffPix.X();
+
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ // Check if the mouse cursor is clicking on the popup arrow box.
+ mpFilterButton.reset(new ScDPFieldButton(this, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY()));
+ mpFilterButton->setBoundingBox(aScrPos, aScrSize);
+ Point aPopupPos;
+ Size aPopupSize;
+ mpFilterButton->getPopupBoundingBox(aPopupPos, aPopupSize);
+ Rectangle aRec(aPopupPos, aPopupSize);
+ if (aRec.IsInside(rMEvt.GetPosPixel()))
+ {
+ if ( DoPageFieldSelection( nCol, nRow ) )
+ return true;
+
+ bool bFilterActive = IsAutoFilterActive(nCol, nRow, nTab);
+ mpFilterButton->setHasHiddenMember(bFilterActive);
+ mpFilterButton->setDrawBaseButton(false);
+ mpFilterButton->setDrawPopupButton(true);
+ mpFilterButton->setPopupPressed(true);
+ HideCursor();
+ mpFilterButton->draw();
+ ShowCursor();
+ DoAutoFilterMenue(nCol, nRow, false);
+ return true;
+ }
+
+ return false;
+}
+
void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt )
{
ScDocument* pDoc = pViewData->GetDocument();
@@ -114,6 +190,15 @@ void ScGridWindow::DoPushButton( SCCOL nCol, SCROW nRow, const MouseEvent& rMEvt
bDPMouse = TRUE;
nDPField = nField;
pDragDPObj = pDPObj;
+
+ if (DPTestFieldPopupArrow(rMEvt, aPos, pDPObj))
+ {
+ // field name pop up menu has been launched. Don't activate
+ // field move.
+ bDPMouse = false;
+ return;
+ }
+
DPTestMouse( rMEvt, TRUE );
StartTracking();
}
@@ -282,6 +367,223 @@ void ScGridWindow::DPTestMouse( const MouseEvent& rMEvt, BOOL bMove )
pViewData->GetView()->ResetTimer();
}
+bool ScGridWindow::DPTestFieldPopupArrow(const MouseEvent& rMEvt, const ScAddress& rPos, ScDPObject* pDPObj)
+{
+ // Get the geometry of the cell.
+ Point aScrPos = pViewData->GetScrPos(rPos.Col(), rPos.Row(), eWhich);
+ long nSizeX, nSizeY;
+ pViewData->GetMergeSizePixel(rPos.Col(), rPos.Row(), nSizeX, nSizeY);
+ Size aScrSize(nSizeX-1, nSizeY-1);
+
+ // Check if the mouse cursor is clicking on the popup arrow box.
+ ScDPFieldButton aBtn(this, &GetSettings().GetStyleSettings());
+ aBtn.setBoundingBox(aScrPos, aScrSize);
+ Point aPopupPos;
+ Size aPopupSize;
+ aBtn.getPopupBoundingBox(aPopupPos, aPopupSize);
+ Rectangle aRec(aPopupPos, aPopupSize);
+ if (aRec.IsInside(rMEvt.GetPosPixel()))
+ {
+ // Mouse cursor inside the popup arrow box. Launch the field menu.
+ DPLaunchFieldPopupMenu(OutputToScreenPixel(aScrPos), aScrSize, rPos, pDPObj);
+ return true;
+ }
+
+ return false;
+}
+
+namespace {
+
+struct DPFieldPopupData : public ScDPFieldPopupWindow::ExtendedData
+{
+ ScPivotParam maDPParam;
+ ScDPObject* mpDPObj;
+ long mnDim;
+};
+
+class DPFieldPopupOKAction : public ScMenuFloatingWindow::Action
+{
+public:
+ explicit DPFieldPopupOKAction(ScGridWindow* p) :
+ mpGridWindow(p) {}
+
+ virtual void execute()
+ {
+ mpGridWindow->UpdateDPFromFieldPopupMenu();
+ }
+private:
+ ScGridWindow* mpGridWindow;
+};
+
+class PopupSortAction : public ScMenuFloatingWindow::Action
+{
+public:
+ enum SortType { ASCENDING, DESCENDING, CUSTOM };
+
+ explicit PopupSortAction(const ScAddress& rPos, SortType eType, sal_uInt16 nUserListIndex, ScTabViewShell* pViewShell) :
+ maPos(rPos), meType(eType), mnUserListIndex(nUserListIndex), mpViewShell(pViewShell) {}
+
+ virtual void execute()
+ {
+ switch (meType)
+ {
+ case ASCENDING:
+ mpViewShell->DataPilotSort(maPos, true);
+ break;
+ case DESCENDING:
+ mpViewShell->DataPilotSort(maPos, false);
+ break;
+ case CUSTOM:
+ mpViewShell->DataPilotSort(maPos, true, &mnUserListIndex);
+ break;
+ default:
+ ;
+ }
+ }
+
+private:
+ ScAddress maPos;
+ SortType meType;
+ sal_uInt16 mnUserListIndex;
+ ScTabViewShell* mpViewShell;
+};
+
+}
+
+void ScGridWindow::DPLaunchFieldPopupMenu(
+ const Point& rScrPos, const Size& rScrSize, const ScAddress& rPos, ScDPObject* pDPObj)
+{
+ // We need to get the list of field members.
+ auto_ptr<DPFieldPopupData> pDPData(new DPFieldPopupData);
+ pDPObj->FillLabelData(pDPData->maDPParam);
+ pDPData->mpDPObj = pDPObj;
+
+ USHORT nOrient;
+ pDPData->mnDim = pDPObj->GetHeaderDim(rPos, nOrient);
+
+ if (pDPData->maDPParam.maLabelArray.size() <= static_cast<size_t>(pDPData->mnDim))
+ // out-of-bound dimension ID. This should never happen!
+ return;
+
+ const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+
+ mpDPFieldPopup.reset(new ScDPFieldPopupWindow(this, pViewData->GetDocument()));
+ mpDPFieldPopup->setName(OUString::createFromAscii("DataPilot field member popup"));
+ mpDPFieldPopup->setExtendedData(pDPData.release());
+ mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
+ {
+ // Populate field members.
+ size_t n = rLabelData.maMembers.size();
+ mpDPFieldPopup->setMemberSize(n);
+ for (size_t i = 0; i < n; ++i)
+ {
+ const ScDPLabelData::Member& rMem = rLabelData.maMembers[i];
+ mpDPFieldPopup->addMember(rMem.getDisplayName(), rMem.mbVisible);
+ }
+ mpDPFieldPopup->initMembers();
+ }
+
+ vector<OUString> aUserSortNames;
+ ScUserList* pUserList = ScGlobal::GetUserList();
+ if (pUserList)
+ {
+ sal_uInt16 n = pUserList->GetCount();
+ aUserSortNames.reserve(n);
+ for (sal_uInt16 i = 0; i < n; ++i)
+ {
+ ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[i]);
+ aUserSortNames.push_back(pData->GetString());
+ }
+ }
+
+ // Populate the menus.
+ ScTabViewShell* pViewShell = pViewData->GetViewShell();
+ mpDPFieldPopup->addMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_ASC).GetString(), true,
+ new PopupSortAction(rPos, PopupSortAction::ASCENDING, 0, pViewShell));
+ mpDPFieldPopup->addMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_DESC).GetString(), true,
+ new PopupSortAction(rPos, PopupSortAction::DESCENDING, 0, pViewShell));
+ ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem(
+ ScRscStrLoader(RID_POPUP_FILTER, STR_MENU_SORT_CUSTOM).GetString(), !aUserSortNames.empty());
+
+ if (pSubMenu && !aUserSortNames.empty())
+ {
+ size_t n = aUserSortNames.size();
+ for (size_t i = 0; i < n; ++i)
+ {
+ pSubMenu->addMenuItem(
+ aUserSortNames[i], true,
+ new PopupSortAction(rPos, PopupSortAction::CUSTOM, static_cast<sal_uInt16>(i), pViewShell));
+ }
+ }
+
+ Rectangle aCellRect(rScrPos, rScrSize);
+ const Size& rPopupSize = mpDPFieldPopup->getWindowSize();
+ if (rScrSize.getWidth() > rPopupSize.getWidth())
+ {
+ // If the cell width is larger than the popup window width, launch it
+ // right-aligned with the cell.
+ long nXOffset = rScrSize.getWidth() - rPopupSize.getWidth();
+ aCellRect.SetPos(Point(rScrPos.X() + nXOffset, rScrPos.Y()));
+ }
+ mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) );
+ mpDPFieldPopup->StartPopupMode(aCellRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS));
+}
+
+void ScGridWindow::UpdateDPFromFieldPopupMenu()
+{
+ typedef hash_map<OUString, OUString, OUStringHash> MemNameMapType;
+ typedef hash_map<OUString, bool, OUStringHash> MemVisibilityType;
+
+ if (!mpDPFieldPopup.get())
+ return;
+
+ DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(mpDPFieldPopup->getExtendedData());
+ if (!pDPData)
+ return;
+
+ ScDPObject* pDPObj = pDPData->mpDPObj;
+ ScDPObject aNewDPObj(*pDPObj);
+ aNewDPObj.BuildAllDimensionMembers();
+ ScDPSaveData* pSaveData = aNewDPObj.GetSaveData();
+
+ BOOL bIsDataLayout;
+ String aDimName = pDPObj->GetDimName(pDPData->mnDim, bIsDataLayout);
+ ScDPSaveDimension* pDim = pSaveData->GetDimensionByName(aDimName);
+ if (!pDim)
+ return;
+
+ // Build a map of layout names to original names.
+ const ScDPLabelData& rLabelData = *pDPData->maDPParam.maLabelArray[pDPData->mnDim];
+ MemNameMapType aMemNameMap;
+ for (vector<ScDPLabelData::Member>::const_iterator itr = rLabelData.maMembers.begin(), itrEnd = rLabelData.maMembers.end();
+ itr != itrEnd; ++itr)
+ aMemNameMap.insert(MemNameMapType::value_type(itr->maLayoutName, itr->maName));
+
+ // The raw result may contain a mixture of layout names and original names.
+ MemVisibilityType aRawResult;
+ mpDPFieldPopup->getResult(aRawResult);
+
+ MemVisibilityType aResult;
+ for (MemVisibilityType::const_iterator itr = aRawResult.begin(), itrEnd = aRawResult.end(); itr != itrEnd; ++itr)
+ {
+ MemNameMapType::const_iterator itrNameMap = aMemNameMap.find(itr->first);
+ if (itrNameMap == aMemNameMap.end())
+ // This is an original member name. Use it as-is.
+ aResult.insert(MemVisibilityType::value_type(itr->first, itr->second));
+ else
+ {
+ // This is a layout name. Get the original member name and use it.
+ aResult.insert(MemVisibilityType::value_type(itrNameMap->second, itr->second));
+ }
+ }
+ pDim->UpdateMemberVisibility(aResult);
+
+ ScDBDocFunc aFunc(*pViewData->GetDocShell());
+ aFunc.DataPilotUpdate(pDPObj, &aNewDPObj, true, false);
+}
+
void ScGridWindow::DPMouseMove( const MouseEvent& rMEvt )
{
DPTestMouse( rMEvt, TRUE );
diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx
index d700ee606731..7719dfcc5474 100644
--- a/sc/source/ui/view/gridwin4.cxx
+++ b/sc/source/ui/view/gridwin4.cxx
@@ -73,6 +73,7 @@
#include "editutil.hxx"
#include "inputopt.hxx"
#include "fillinfo.hxx"
+#include "dpcontrol.hxx"
#include "sc.hrc"
#include <vcl/virdev.hxx>
@@ -1203,6 +1204,8 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2
{
aComboButton.SetOutputDevice( pContentDev );
+ ScDPFieldButton aCellBtn(pContentDev, &GetSettings().GetStyleSettings(), &pViewData->GetZoomX(), &pViewData->GetZoomY());
+
SCCOL nCol;
SCROW nRow;
SCSIZE nArrY;
@@ -1284,14 +1287,14 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2
bool bArrowState = bSimpleQuery && bColumnFound;
long nSizeX;
long nSizeY;
-
pViewData->GetMergeSizePixel( nCol, nRow, nSizeX, nSizeY );
- aComboButton.SetOptSizePixel();
- DrawComboButton( pViewData->GetScrPos( nCol, nRow, eWhich ),
- nSizeX, nSizeY, bArrowState );
+ Point aScrPos = pViewData->GetScrPos( nCol, nRow, eWhich );
- aComboButton.SetPosPixel( aOldPos ); // alten Zustand
- aComboButton.SetSizePixel( aOldSize ); // fuer MouseUp/Down
+ aCellBtn.setBoundingBox(aScrPos, Size(nSizeX-1, nSizeY-1));
+ aCellBtn.setDrawBaseButton(false);
+ aCellBtn.setDrawPopupButton(true);
+ aCellBtn.setHasHiddenMember(bArrowState);
+ aCellBtn.draw();
}
}
}
@@ -1318,13 +1321,14 @@ void ScGridWindow::DrawButtons( SCCOL nX1, SCROW /*nY1*/, SCCOL nX2, SCROW /*nY2
nPosX -= nSizeX - 2;
}
- pContentDev->SetLineColor( GetSettings().GetStyleSettings().GetLightColor() );
- pContentDev->DrawLine( Point(nPosX,nPosY), Point(nPosX,nPosY+nSizeY-1) );
- pContentDev->DrawLine( Point(nPosX,nPosY), Point(nPosX+nSizeX-1,nPosY) );
- pContentDev->SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() );
- pContentDev->DrawLine( Point(nPosX,nPosY+nSizeY-1), Point(nPosX+nSizeX-1,nPosY+nSizeY-1) );
- pContentDev->DrawLine( Point(nPosX+nSizeX-1,nPosY), Point(nPosX+nSizeX-1,nPosY+nSizeY-1) );
- pContentDev->SetLineColor( COL_BLACK );
+ String aStr;
+ pDoc->GetString(nCol, nRow, nTab, aStr);
+ aCellBtn.setText(aStr);
+ aCellBtn.setBoundingBox(Point(nPosX, nPosY), Size(nSizeX-1, nSizeY-1));
+ aCellBtn.setDrawBaseButton(true);
+ aCellBtn.setDrawPopupButton(pInfo->bPopupButton);
+ aCellBtn.setHasHiddenMember(pInfo->bFilterActive);
+ aCellBtn.draw();
}
}
}
diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk
index d8f45c8a754f..ed50324f68be 100644
--- a/sc/source/ui/view/makefile.mk
+++ b/sc/source/ui/view/makefile.mk
@@ -140,7 +140,6 @@ SLOFILES = \
$(SLO)$/dbfunc2.obj \
$(SLO)$/tabvwsh2.obj
.ELSE
-
NOOPTFILES=\
$(SLO)$/drawview.obj \
$(SLO)$/dbfunc2.obj \
@@ -157,7 +156,8 @@ EXCEPTIONSFILES= \
$(SLO)$/cellsh1.obj \
$(SLO)$/drawvie4.obj \
$(SLO)$/formatsh.obj \
- $(SLO)$/scextopt.obj \
+ $(SLO)$/gridwin2.obj \
+ $(SLO)$/scextopt.obj \
$(SLO)$/tabvwshb.obj \
$(SLO)$/viewdata.obj \
$(SLO)$/viewfun5.obj \
diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx
index 3077e852dbaf..c076575d4e6d 100644
--- a/sc/source/ui/view/tabview.cxx
+++ b/sc/source/ui/view/tabview.cxx
@@ -200,6 +200,8 @@
#include "AccessibilityHints.hxx"
#include "appoptio.hxx"
+#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
+
#include <string>
#include <algorithm>
@@ -212,6 +214,8 @@
// fuer Rad-Maus
#define SC_DELTA_ZOOM 10
+using namespace ::com::sun::star;
+
// STATIC DATA -----------------------------------------------------------
@@ -2476,7 +2480,7 @@ sal_Bool ScTabView::HasPageFieldDataAtCursor() const
SCCOL nCol = aViewData.GetCurX();
SCROW nRow = aViewData.GetCurY();
if (pWin)
- return pWin->HasPageFieldData( nCol, nRow );
+ return pWin->GetDPFieldOrientation( nCol, nRow ) == sheet::DataPilotFieldOrientation_PAGE;
return sal_False;
}
@@ -2486,15 +2490,23 @@ void ScTabView::StartDataSelect()
ScGridWindow* pWin = pGridWin[aViewData.GetActivePart()];
SCCOL nCol = aViewData.GetCurX();
SCROW nRow = aViewData.GetCurY();
- if (pWin)
- {
- // #i36598# If the cursor is on a page field's data cell,
- // no meaningful input is possible anyway, so this function
- // can be used to select a page field entry.
- if ( pWin->HasPageFieldData( nCol, nRow ) )
- pWin->DoPageFieldMenue( nCol, nRow );
- else
+ if (!pWin)
+ return;
+
+ switch (pWin->GetDPFieldOrientation(nCol, nRow))
+ {
+ case sheet::DataPilotFieldOrientation_PAGE:
+ // #i36598# If the cursor is on a page field's data cell,
+ // no meaningful input is possible anyway, so this function
+ // can be used to select a page field entry.
+ pWin->LaunchPageFieldMenu( nCol, nRow );
+ break;
+ case sheet::DataPilotFieldOrientation_COLUMN:
+ case sheet::DataPilotFieldOrientation_ROW:
+ pWin->LaunchDPFieldMenu( nCol, nRow );
+ break;
+ default:
pWin->DoAutoFilterMenue( nCol, nRow, TRUE );
}
}
diff --git a/sc/util/makefile.mk b/sc/util/makefile.mk
index 3c51d15634de..44d2ad9b490d 100644
--- a/sc/util/makefile.mk
+++ b/sc/util/makefile.mk
@@ -54,6 +54,7 @@ RESLIB1LIST=\
$(SRS)$/formdlgs.srs \
$(SRS)$/pagedlg.srs \
$(SRS)$/navipi.srs \
+ $(SRS)$/cctrl.srs \
$(SOLARCOMMONRESDIR)$/sfx.srs
RESLIB1NAME=sc